Flow123d  release_2.2.0-914-gf1a3a4f
radioactive_decay.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file radioactive_decay.cc
15  * @brief
16  */
17 
22 
23 #include "system/global_defs.h"
24 #include "mesh/mesh.h"
25 #include "input/factory.hh"
26 #include "input/accessors.hh"
27 
28 #include "armadillo"
29 
30 FLOW123D_FORCE_LINK_IN_CHILD(radioactiveDecay)
31 
32 
33 using namespace Input::Type;
34 
35 const Record & RadioactiveDecay::get_input_type_product() {
36  return Record("RadioactiveDecayProduct", "A record describing a product of a radioactive decay.")
37  .allow_auto_conversion("name")
38  .declare_key("name", String(), Default::obligatory(),
39  "The name of the product.")
40  .declare_key("energy", Double(0.0), Default("0.0"),
41  "Not used at the moment! The released energy in MeV from the decay of the radionuclide into the product.")
42  .declare_key("branching_ratio", Double(0.0), Default("1.0"),
43  "The branching ratio of the product when there is more than one."
44  "Considering only one product, the default ratio 1.0 is used."
45  "Its value must be positive. Further, the branching ratios of all products are normalized"
46  "by their sum, so the sum then gives 1.0 (this also resolves possible rounding errors).")
47  .close();
48 }
49 
51  return Record("Decay", "A model of a radioactive decay.")
52  .declare_key("radionuclide", String(), Default::obligatory(),
53  "The name of the parent radionuclide.")
54  .declare_key("half_life", Double(0.0), Default::obligatory(),
55  "The half life of the parent radionuclide in seconds.")
56  .declare_key("products", Array(RadioactiveDecay::get_input_type_product(), 1), Default::obligatory(),
57  "An array of the decay products (daughters).")
58  .close();
59 }
60 
62  return Record("RadioactiveDecay", "A model of a radioactive decay and possibly of a decay chain.")
67  .declare_key("decays", Array( RadioactiveDecay::get_input_type_single_decay(), 1), Default::obligatory(),
68  "An array of radioactive decays.")
69  .declare_key("ode_solver", PadeApproximant::get_input_type(), Default("{}"),
70  "Numerical solver for the system of first order ordinary differential equations coming from the model.")
71  .close();
72 }
73 
75  Input::register_class< RadioactiveDecay, Mesh &, Input::Record >("RadioactiveDecay") +
77 
78 
79 
81  : FirstOrderReactionBase(init_mesh, in_rec)
82 {
83 }
84 
86 {
87 }
88 
89 
91 {
92  Input::Array decay_array = input_record_.val<Input::Array>("decays");
93 
94  substance_ids_.resize( decay_array.size() );
95  half_lives_.resize( decay_array.size() );
96  bifurcation_.resize( decay_array.size() );
97 
98  unsigned int idx;
99  int i_decay = 0;
100  for (Input::Iterator<Input::Record> dec_it = decay_array.begin<Input::Record>();
101  dec_it != decay_array.end(); ++dec_it, ++i_decay)
102  {
103  //read half-life
104  half_lives_[i_decay] = dec_it->val<double>("half_life");
105 
106  //read radionuclide name and products array
107  string radionuclide = dec_it->val<string>("radionuclide");
108  Input::Array product_array = dec_it->val<Input::Array>("products");
109 
110  //resizing according to product count
111  substance_ids_[i_decay].resize(product_array.size()+1);
112  bifurcation_[i_decay].resize(product_array.size());
113 
114  //Reading products - setting substance ids, branching ratios.
115  //iterating over products
116  unsigned int i_product = 0;
117  for (Input::Iterator<Input::Record> prod_it = product_array.begin<Input::Record>();
118  prod_it != product_array.end(); ++prod_it, ++i_product)
119  {
120  string product_name = prod_it->val<string>("name");
121  idx = find_subst_name(product_name);
122  if (idx < substances_.size())
123  substance_ids_[i_decay][i_product+1] = idx;
124  else THROW(ReactionTerm::ExcUnknownSubstance()
125  << ReactionTerm::EI_Substance(product_name)
126  << (*prod_it).ei_address());
127 
128  bifurcation_[i_decay][i_product] = prod_it->val<double>("branching_ratio");
129  }
130 
131  // set radionuclide substance index
132  idx = find_subst_name(radionuclide);
133  if (idx < substances_.size())
134  substance_ids_[i_decay][0] = idx;
135  else THROW(ReactionTerm::ExcUnknownSubstance()
136  << ReactionTerm::EI_Substance(radionuclide)
137  << (*dec_it).ei_address());
138 
139  //Normalization of branching ratios in bifurcation vector by its norm.
140  //sum:
141  double sum=0;
142  for(auto &b : bifurcation_[i_decay])
143  sum += b;
144  //Normalization:
145  for(auto &b : bifurcation_[i_decay])
146  b = b / sum;
147  }
148 }
149 
150 
152 {
153  // create decay matrix
155  unsigned int reactant_index, product_index; //global indices of the substances
156  double exponent; //temporary variable k = ln(2)/t_half
157  for (unsigned int i_decay = 0; i_decay < half_lives_.size(); i_decay++) {
158  reactant_index = substance_ids_[i_decay][0];
159  exponent = log(2) / half_lives_[i_decay];
160  reaction_matrix_(reactant_index, reactant_index) = -exponent;
161 
162  for (unsigned int i_product = 1; i_product < substance_ids_[i_decay].size(); ++i_product){
163  product_index = substance_ids_[i_decay][i_product];
164  reaction_matrix_(product_index, reactant_index) = exponent * bifurcation_[i_decay][i_product-1];
165  }
166  }
167 }
Iterator< ValueType > begin() const
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:598
void assemble_ode_matrix(void) override
Implements the assembly of the system matrix of the ODEs.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
Abstract linear system class.
Definition: equation.hh:37
static const Input::Type::Record & get_input_type_product()
Input record for a product of a radioactive decay.
SubstanceList substances_
Names belonging to substances.
~RadioactiveDecay(void)
Destructor.
Definition: mesh.h:99
unsigned int find_subst_name(const std::string &name)
Base class for linear reactions and decay chain.
static Input::Type::Abstract & it_abstract_mobile_term()
static Input::Type::Abstract & it_abstract_reaction()
unsigned int size() const
Definition: substance.hh:87
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
Class for declaration of inputs sequences.
Definition: type_base.hh:345
void initialize_from_input() override
Initializes private members of sorption from the input record.
Class ReactionTerm is an abstract class representing reaction term in transport.
IteratorBase end() const
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
static const Input::Type::Record & get_input_type_single_decay()
Input record which defines particular decay step.
Global macros to enhance readability and debugging, general constants.
virtual Record & allow_auto_conversion(const string &from_key)
Allows shorter input of the Record providing only value of the from_key given as the parameter...
Definition: type_record.cc:132
arma::mat reaction_matrix_
Reaction matrix.
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:540
Class implements the radioactive decay chain.
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
static const Input::Type::Record & get_input_type()
const Ret val(const string &key) const
static Input::Type::Abstract & it_abstract_immobile_term()
static const int registrar
Registrar of class to factory.
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:490
static const Input::Type::Record & get_input_type()
Input record for class RadioactiveDecay.
static Input::Type::Abstract & it_abstract_term()
Input::Record input_record_
Definition: equation.hh:225
std::vector< double > half_lives_
Half-lives of the substances.
std::vector< std::vector< unsigned int > > substance_ids_
unsigned int size() const
Record type proxy class.
Definition: type_record.hh:182
RadioactiveDecay(Mesh &mesh, Input::Record in_rec)
Constructor.
unsigned int n_substances_
Number of all transported substances. It is the dimension of the reaction matrix. ...
Class for declaration of the input data that are in string format.
Definition: type_base.hh:588
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
std::vector< std::vector< double > > bifurcation_