Flow123d  last_with_con_2.0.0-4-g42e6930
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.")
64  .declare_key("decays", Array( RadioactiveDecay::get_input_type_single_decay(), 1), Default::obligatory(),
65  "An array of radioactive decays.")
66  .declare_key("ode_solver", PadeApproximant::get_input_type(), Default("{}"),
67  "Numerical solver for the system of first order ordinary differential equations coming from the model.")
68  .close();
69 }
70 
72  Input::register_class< RadioactiveDecay, Mesh &, Input::Record >("RadioactiveDecay") +
74 
75 
76 
78  : FirstOrderReactionBase(init_mesh, in_rec)
79 {
80 }
81 
83 {
84 }
85 
86 
88 {
89  Input::Array decay_array = input_record_.val<Input::Array>("decays");
90 
91  substance_ids_.resize( decay_array.size() );
92  half_lives_.resize( decay_array.size() );
93  bifurcation_.resize( decay_array.size() );
94 
95  unsigned int idx;
96  int i_decay = 0;
97  for (Input::Iterator<Input::Record> dec_it = decay_array.begin<Input::Record>();
98  dec_it != decay_array.end(); ++dec_it, ++i_decay)
99  {
100  //read half-life
101  half_lives_[i_decay] = dec_it->val<double>("half_life");
102 
103  //read radionuclide name and products array
104  string radionuclide = dec_it->val<string>("radionuclide");
105  Input::Array product_array = dec_it->val<Input::Array>("products");
106 
107  //resizing according to product count
108  substance_ids_[i_decay].resize(product_array.size()+1);
109  bifurcation_[i_decay].resize(product_array.size());
110 
111  //Reading products - setting substance ids, branching ratios.
112  //iterating over products
113  unsigned int i_product = 0;
114  for (Input::Iterator<Input::Record> prod_it = product_array.begin<Input::Record>();
115  prod_it != product_array.end(); ++prod_it, ++i_product)
116  {
117  string product_name = prod_it->val<string>("name");
118  idx = find_subst_name(product_name);
119  if (idx < substances_.size())
120  substance_ids_[i_decay][i_product+1] = idx;
121  else THROW(ReactionTerm::ExcUnknownSubstance()
122  << ReactionTerm::EI_Substance(product_name)
123  << (*prod_it).ei_address());
124 
125  bifurcation_[i_decay][i_product] = prod_it->val<double>("branching_ratio");
126  }
127 
128  // set radionuclide substance index
129  idx = find_subst_name(radionuclide);
130  if (idx < substances_.size())
131  substance_ids_[i_decay][0] = idx;
132  else THROW(ReactionTerm::ExcUnknownSubstance()
133  << ReactionTerm::EI_Substance(radionuclide)
134  << (*dec_it).ei_address());
135 
136  //Normalization of branching ratios in bifurcation vector by its norm.
137  //sum:
138  double sum=0;
139  for(auto &b : bifurcation_[i_decay])
140  sum += b;
141  //Normalization:
142  for(auto &b : bifurcation_[i_decay])
143  b = b / sum;
144  }
145 }
146 
147 
149 {
150  // create decay matrix
152  unsigned int reactant_index, product_index; //global indices of the substances
153  double exponent; //temporary variable k = ln(2)/t_half
154  for (unsigned int i_decay = 0; i_decay < half_lives_.size(); i_decay++) {
155  reactant_index = substance_ids_[i_decay][0];
156  exponent = log(2) / half_lives_[i_decay];
157  reaction_matrix_(reactant_index, reactant_index) = -exponent;
158 
159  for (unsigned int i_product = 1; i_product < substance_ids_[i_decay].size(); ++i_product){
160  product_index = substance_ids_[i_decay][i_product];
161  reaction_matrix_(product_index, reactant_index) = exponent * bifurcation_[i_decay][i_product-1];
162  }
163  }
164 }
Iterator< ValueType > begin() const
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:582
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:50
static Input::Type::Abstract & get_input_type()
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:95
unsigned int find_subst_name(const std::string &name)
Base class for linear reactions and decay chain.
unsigned int size() const
Definition: substance.hh:87
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:286
Class for declaration of inputs sequences.
Definition: type_base.hh:321
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:518
Class implements the radioactive decay chain.
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
static const Input::Type::Record & get_input_type()
const Ret val(const string &key) const
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:468
static const Input::Type::Record & get_input_type()
Input record for class RadioactiveDecay.
Input::Record input_record_
Definition: equation.hh:223
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:171
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:568
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
std::vector< std::vector< double > > bifurcation_