TkN 2.1
Toolkit for Nuclei
tknucleus.cpp
1/********************************************************************************
2 * Copyright (c) : Université de Lyon 1, CNRS/IN2P3, UMR5822, *
3 * IP2I, F-69622 Villeurbanne Cedex, France *
4 * Normandie Université, ENSICAEN, UNICAEN, CNRS/IN2P3, *
5 * LPC Caen, F-14000 Caen, France *
6 * Contibutor(s) : *
7 * Jérémie Dudouet jeremie.dudouet@cnrs.fr [2020] *
8 * Diego Gruyer diego.gruyer@cnrs.fr [2020] *
9 * *
10 * This software is governed by the CeCILL-B license under French law and *
11 * abiding by the rules of distribution of free software. You can use, *
12 * modify and/ or redistribute the software under the terms of the *
13 * CeCILL-B license as circulated by CEA, CNRS and INRIA at the following *
14 * URL \"http://www.cecill.info\". *
15 * *
16 * As a counterpart to the access to the source code and rights to copy, *
17 * modify and redistribute granted by the license, users are provided *
18 * only with a limited warranty and the software's author, the holder of *
19 * the economic rights, and the successive licensors have only limited *
20 * liability. *
21 * *
22 * In this respect, the user's attention is drawn to the risks associated *
23 * with loading, using, modifying and/or developing or reproducing the *
24 * software by the user in light of its specific status of free software, *
25 * that may mean that it is complicated to manipulate, and that also *
26 * therefore means that it is reserved for developers and experienced *
27 * professionals having in-depth computer knowledge. Users are therefore *
28 * encouraged to load and test the software's suitability as regards *
29 * their requirements in conditions enabling the security of their *
30 * systems and/or data to be ensured and, more generally, to use and *
31 * operate it in the same conditions as regards security. *
32 * *
33 * The fact that you are presently reading this means that you have had *
34 * knowledge of the CeCILL-B license and that you accept its terms. *
35 ********************************************************************************/
36
37#include "tknucleus.h"
38#include "sqlite3.h"
39#include "tklog.h"
40#include "tkstring.h"
41#include "tkmanager.h"
42
43namespace tkn {
52}
53
54using namespace tkn;
55
56vector<int> tknucleus::fmagic_number_list{2,8,20,28,50,82,126};
57
63tknucleus::tknucleus(int _Z, int _A) : tkproperty_list("nucleus")
64{
65 tkstring symbol = gmanager->get_element_symbol(_Z);
66 if(symbol.empty()) {
67 glog << warning << "Unknown nucleus. No properties loaded " << tkstring::form("(%d,%d)",_Z,_A) << do_endl;
68 fZ = _Z;
69 fN = _A-_Z;
70 fA = _A;
71 return;
72 }
73 symbol.prepend(tkstring::form("%d",_A));
74 if(!gmanager->known_nucleus(symbol)){
75 glog << warning << "Unknown nucleus. No properties loaded (" << symbol << ")" << do_endl;
76 return;
77 }
78 const tknucleus & nuc = *gmanager->get_nucleus(symbol).get(); // vérifier que ca fasse une copie et pas une reference
79 (*this) = nuc;
80}
81
88{
89 if(!gmanager->known_element(_Z)) glog << warning << "Unknown element. No properties loaded" << do_endl;
90 else {
91 shared_ptr<tknucleus> bestnuc;
92 for(const auto &nuc: gmanager->get_nuclei_for_z(_Z)) {
93 if(bestnuc==nullptr) bestnuc = nuc;
94 else if(isnan(bestnuc->get_lifetime()) || (nuc->get_lifetime()>bestnuc->get_lifetime())) bestnuc = nuc;
95 else if(nuc->get_lifetime() == bestnuc->get_lifetime() && nuc->get_abundance()>bestnuc->get_abundance()) bestnuc = nuc;
96 }
97 const tknucleus & nuc = *bestnuc.get();
98 (*this) = nuc;
99 }
100}
101
107tknucleus::tknucleus(const char *_symbol) : tkproperty_list("nucleus")
108{
109 if(!gmanager->known_nucleus(tkstring(_symbol))) {
110 int z;
111 if(gmanager->known_element(tkstring(_symbol),z)) {
112 if(!tkstring(_symbol).is_alpha()) {
113 glog << warning << "Unknown nucleus. TkN will choose one for you ;)" << do_endl;
114 }
115 const tknucleus nuc(z);
116 (*this) = nuc;
117 return;
118 }
119 }
120 const tknucleus & nuc = *gmanager->get_nucleus(_symbol).get();
121 (*this) = nuc;
122}
123
124void tknucleus::set_name(const char *_name)
125{
126 fSymbol = _name;
127 felement_symbol = fSymbol.extract_alpha();
128 fA = fSymbol.atoi();
129}
130
132 if(std::find(fmagic_number_list.begin(), fmagic_number_list.end(), fZ) != fmagic_number_list.end()) return true;
133 return false;
134}
135
137 if(std::find(fmagic_number_list.begin(), fmagic_number_list.end(), fN) != fmagic_number_list.end()) return true;
138 return false;
139}
140
141shared_ptr<tklevel_scheme> tknucleus::get_level_scheme()
142{
143 return gmanager->get_level_scheme(get_symbol(), get_z(), get_a());
144}
145
154{
155 if(!has_property("radius")) return -1.;
156 return get("radius")->get_value();
157}
158
167{
168 if(!has_property("magnetic_dipole")) return -1.;
169 return get("magnetic_dipole")->get_value();
170}
171
180{
181 if(!has_property("electric_quadrupole")) return -1.;
182 return get("electric_quadrupole")->get_value();
183}
184
193{
194 if(!has_property("abundance")) return -1.;
195 return get("abundance")->get_value();
196}
197
206{
207 if(!has_property("mass_excess")) return std::nan("1");
208 if(gunits->get_type(_unit)!=tkunit_manager::units_type::kEnergy){
209 glog << error << gunits->get_name(_unit) << " is not of 'energy' type (returns nan(1))" << do_endl;
210 return std::nan("1");
211 }
212 return get("mass_excess")->get_value(_unit);
213}
214
223{
224 if(!has_property("binding_energy_overA")) return std::nan("1");
225 if(gunits->get_type(_unit)!=tkunit_manager::units_type::kEnergy){
226 glog << error << gunits->get_name(_unit) << " is not of 'energy' type (returns nan(1))" << do_endl;
227 return std::nan("1");
228 }
229 return get("binding_energy_overA")->get_value(_unit);
230}
231
240{
241 if(!has_property("lifetime")) return std::nan("1");
242 if(gunits->get_type(_unit)!=tkunit_manager::units_type::kTime&&gunits->get_type(_unit)!=tkunit_manager::units_type::kEnergy){
243 glog << error << gunits->get_name(_unit) << " is not of 'time' or 'energy' type (returns nan(1))" << do_endl;
244 return std::nan("1");
245 }
246 return get("lifetime")->get_value(_unit);
247}
248
249
250
264double tknucleus::get_fission_yield(tkstring _parent, bool _cumulative) {
265 if(!_parent.begins_with("FY")) _parent.prepend("FY");
266 if(_cumulative) _parent.prepend("c");
267 if(!has_property(_parent)) return 0.;
268 return get(_parent)->get_value();
269}
270
276{
277 if(!has_property("lifetime")) return "";
278 tkstring lifetime_str;
279
280 if(is_stable())
281 lifetime_str = "STABLE";
282 else {
283 vector<tkunit_manager::units_keys> units{tkunit_manager::y, tkunit_manager::d, tkunit_manager::h, tkunit_manager::min,
287
288 for(auto &unit: units) {
289 double lifetime = get_lifetime(unit);
290 if(lifetime>1.) {
291 lifetime_str = tkstring::Form("%.3g %s",lifetime,std::get<0>(tkunit_manager::funits_properties.at(unit)).data());
292 break;
293 }
294 }
295 }
296
297 return lifetime_str;
298}
299
300shared_ptr<tklevel> tknucleus::get_ground_state()
301{
302 if(!get_level_scheme()->get_levels().empty())
303 return get_level_scheme()->get_levels().front();
304 return nullptr;
305}
306
308{
309 if(!has_property("binding_energy_overA")) return false;
310 return get("binding_energy_overA")->get_value()>0;
311}
312
318vector<pair<tkstring, double>> tknucleus::get_decay_modes()
319{
320 vector<pair<tkstring, double>> decay_list;
321 auto decays = get_decay_mode_str();
322 auto tokkens = decays.replace_all("[","]").tokenize("]");
323 for(auto &dec: tokkens) {
324 auto tokk = dec.tokenize(";");
325 decay_list.push_back({tokk.front(),tokk.back().atof()});
326 }
327 return decay_list;
328}
329
331{
332 glog << info << fSymbol << " (Z=" << fZ <<", N=" << fN << ") properties:" << do_endl;
333 glog << info << "Ground state configuration: ";
334 if(get_jpi().is_empty()) glog << "Unkown" << do_endl;
335 else glog << get_jpi() << do_endl;
336 if(is_stable()) glog << info << "Stable nucleus, abundance: " << tkstring::form("%3.2f",get_abundance()) << " %" << do_endl;
337 else {
338 glog << info << "Radioactive nucleus:"<<do_endl;
340 glog << info << "Decay: " << get_property("decay_modes") << do_endl;
341 }
342}
343
344
345#ifdef HAS_ROOT
347ClassImp(tknucleus);
348#endif
A nucleus made of Z protons and N neutrons.
Definition: tknucleus.h:54
double get_mass_excess(const tkunit_manager::units_keys _unit=tkunit_manager::units_keys::keV)
return the mass excess in keV by default
Definition: tknucleus.cpp:205
const tkstring & get_jpi() const
return the ground state spin and parity as a string
Definition: tknucleus.h:169
int get_a()
return the mass number
Definition: tknucleus.h:92
vector< pair< tkstring, double > > get_decay_modes()
return the decay modes as a vector of decay
Definition: tknucleus.cpp:318
double get_radius() const
returns the radius in fm
Definition: tknucleus.cpp:153
bool is_n_magic()
return true in case of n is a magic number
Definition: tknucleus.cpp:136
double get_lifetime(const tkunit_manager::units_keys _unit=tkunit_manager::units_keys::s)
returns the lifetime in second
Definition: tknucleus.cpp:239
bool is_stable() const
test if the nucleus is stable
Definition: tknucleus.h:162
double get_abundance() const
returns the natural abundance in percent
Definition: tknucleus.cpp:192
tknucleus()
default constructor
Definition: tknucleus.h:76
double get_fission_yield(tkstring _parent, bool _cumulative=false)
returns the fission yield of the current nucleus
Definition: tknucleus.cpp:264
tkstring get_lifetime_str()
returns the lifetime in string (using the best adapted unit)
Definition: tknucleus.cpp:275
shared_ptr< tklevel > get_ground_state()
return the ground state level (nullptr if no GS known)
Definition: tknucleus.cpp:300
bool is_z_magic()
return true in case of z is a magic number
Definition: tknucleus.cpp:131
int get_z()
return the proton number
Definition: tknucleus.h:88
shared_ptr< tklevel_scheme > get_level_scheme()
return a tklevel_scheme shared pointer to the nucleus level scheme
Definition: tknucleus.cpp:141
double get_electric_quadrupole()
return the electric quadrupole moment in barn by default
Definition: tknucleus.cpp:179
shared_ptr< tkmeasure > get_lifetime_measure() const
returns the lifetime tkmeasure object
Definition: tknucleus.h:138
void print() const
print the main nucleus properties
Definition: tknucleus.cpp:330
const tkstring & get_symbol()
return the nucleus symbol
Definition: tknucleus.h:95
double get_magnetic_dipole()
return the magnetic dipole moment in mun by default
Definition: tknucleus.cpp:166
tkstring get_decay_mode_str()
return the decay modes as a string
Definition: tknucleus.h:151
double get_binding_energy_over_a(const tkunit_manager::units_keys _unit=tkunit_manager::units_keys::MeV)
returns the binding energy per mass unit in MeV
Definition: tknucleus.cpp:222
bool is_bound() const
test if the nucleus is bound (positive binding energy)
Definition: tknucleus.cpp:307
Contains list of properties.
bool has_property(const tkstring &_property) const
to check if the property is available
shared_ptr< tkmeasure > get(const tkstring &_property) const
get the property as tkmeasure
tkstring get_property(const tkstring &_property) const
get the property value as a string
std::string with usefull tricks from TString (ROOT) and KVString (KaliVeda) and more....
Definition: tkstring.h:54
tkstring extract_alpha()
Returns a tkstring composed only of the alphabetic letters of the original tkstring.
Definition: tkstring.cpp:387
static const char * form(const char *_format,...)
Definition: tkstring.cpp:431
static tkstring Form(const char *_format,...)
Definition: tkstring.cpp:345
int atoi() const
Converts a string to integer value.
Definition: tkstring.cpp:175
tkstring & prepend(const tkstring &_st)
Definition: tkstring.h:224
bool begins_with(const char *_s, ECaseCompare _cmp=kExact) const
Definition: tkstring.h:185
units_keys
units identifiers
Definition: tkunit.h:69
static std::vector< std::tuple< tkstring, units_type, double > > funits_properties
Definition: tkunit.h:75
Definition: tklog.cpp:39
tklog & info(tklog &log)
Definition: tklog.h:336
tklog & error(tklog &log)
Definition: tklog.h:367
tklog & do_endl(tklog &log)
Definition: tklog.h:235
tklog & warning(tklog &log)
Definition: tklog.h:354