Flow123d  release_2.2.0-914-gf1a3a4f
first_order_reaction.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 first_order_reaction.cc
15  * @brief
16  */
17 
21 
22 #include "system/global_defs.h"
23 #include "mesh/mesh.h"
24 #include "input/factory.hh"
25 #include "input/accessors.hh"
26 
27 FLOW123D_FORCE_LINK_IN_CHILD(firstOrderReaction)
28 
29 
30 using namespace Input::Type;
31 
32 const Record & FirstOrderReaction::get_input_type_reactant() {
33  return Record("FirstOrderReactionReactant", "A record describing a reactant of a reaction.")
34  .allow_auto_conversion("name")
35  .declare_key("name", String(), Default::obligatory(),
36  "The name of the reactant.")
37  //.declare_key("stoichiometric_coefficient", Integer(0.0), Default::optional(1.0)) //in future
38  .close();
39 }
40 
42  return Record("FirstOrderReactionProduct", "A record describing a product of a reaction.")
43  .allow_auto_conversion("name")
44  .declare_key("name", String(), Default::obligatory(),
45  "The name of the product.")
46  //.declare_key("stoichiometric_coefficient", Integer(0.0), Default::optional(1.0)) //in future
47  .declare_key("branching_ratio", Double(0.0), Default("1.0"),
48  "The branching ratio of the product when there are more products.\n"
49  "The value must be positive. Further, the branching ratios of all products are normalized "
50  "in order to sum to one.\n"
51  "The default value 1.0, should only be used in the case of single product.")
52  .close();
53 }
54 
56  return Record("Reaction", "Describes a single first order chemical reaction.")
57  .declare_key("reactants", Array(FirstOrderReaction::get_input_type_reactant(), 1), Default::obligatory(),
58  "An array of reactants. Do not use array, reactions with only one reactant (decays) are implemented at the moment!")
59  .declare_key("reaction_rate", Double(0.0), Default::obligatory(),
60  "The reaction rate coefficient of the first order reaction.")
61  .declare_key("products", Array(FirstOrderReaction::get_input_type_product(), 1), Default::obligatory(),
62  "An array of products.")
63  .close();
64 }
65 
66 
68  return Record("FirstOrderReaction", "A model of first order chemical reactions (decompositions of a reactant into products).")
73  .declare_key("reactions", Array( FirstOrderReaction::get_input_type_single_reaction()), Default::obligatory(),
74  "An array of first order chemical reactions.")
75  .declare_key("ode_solver", PadeApproximant::get_input_type(), Default("{}"),
76  "Numerical solver for the system of first order ordinary differential equations coming from the model.")
77  .close();
78 }
79 
81  Input::register_class< FirstOrderReaction, Mesh &, Input::Record >("FirstOrderReaction") +
83 
84 
86  : FirstOrderReactionBase(init_mesh, in_rec)
87 {
88 }
89 
91 {
92 }
93 
95 {
96  // create decay matrix
98  unsigned int reactant_index, product_index; //global indices of the substances
99  double exponent; //temporary variable for k
100  for (unsigned int i_reaction = 0; i_reaction < reaction_rates_.size(); i_reaction++) {
101  reactant_index = substance_ids_[i_reaction][0];
102  exponent = reaction_rates_[i_reaction];
103  reaction_matrix_(reactant_index, reactant_index) = -exponent;
104 
105  for (unsigned int i_product = 1; i_product < substance_ids_[i_reaction].size(); ++i_product){
106  product_index = substance_ids_[i_reaction][i_product];
107  reaction_matrix_(product_index, reactant_index) = exponent * bifurcation_[i_reaction][i_product-1];
108  }
109  }
110 }
111 
112 
114 {
115  unsigned int idx; //temporary variable, indexing substances
116 
117  Input::Array reactions_array = input_record_.val<Input::Array>("reactions");
118 
119  substance_ids_.resize( reactions_array.size() );
120  reaction_rates_.resize( reactions_array.size() );
121  bifurcation_.resize( reactions_array.size() );
122 
123  int i_reaction=0;
124  for (Input::Iterator<Input::Record> react_it = reactions_array.begin<Input::Record>();
125  react_it != reactions_array.end(); ++react_it, ++i_reaction)
126  {
127  //read reaction rate
128  reaction_rates_[i_reaction] = react_it->val<double>("reaction_rate");
129 
130  //read reactant name, product names and branching ratios
131  Input::Array reactant_array = react_it->val<Input::Array>("reactants");
132  Input::Array product_array = react_it->val<Input::Array>("products");
133 
134  //resize substance_ids array
135  substance_ids_[i_reaction].resize( product_array.size()+1 );
136  bifurcation_[i_reaction].resize(product_array.size());
137 
138  if(reactant_array.size() != 1)
139  xprintf(UsrErr, "More than one reactant is not available at the moment.");
140 
141  //take only one reactant
142  Input::Iterator<Input::Record> reactant_it = reactant_array.begin<Input::Record>();
143  {
144  string reactant_name = reactant_it->val<string>("name");
145  idx = find_subst_name(reactant_name);
146  if (idx < substances_.size())
147  substance_ids_[i_reaction][0] = idx;
148  else THROW(ReactionTerm::ExcUnknownSubstance()
149  << ReactionTerm::EI_Substance(reactant_name)
150  << (*reactant_it).ei_address());
151  }
152 
153  // set products
154  unsigned int i_product = 0;
155  for(Input::Iterator<Input::Record> product_it = product_array.begin<Input::Record>();
156  product_it != product_array.end(); ++product_it, i_product++)
157  {
158  string product_name = product_it->val<string>("name");
159  idx = find_subst_name(product_name);
160  if (idx < substances_.size())
161  substance_ids_[i_reaction][i_product+1] = idx;
162  else THROW(ReactionTerm::ExcUnknownSubstance()
163  << ReactionTerm::EI_Substance(product_name)
164  << product_array.ei_address());
165 
166  bifurcation_[i_reaction][i_product] = product_it->val<double>("branching_ratio");
167  }
168 
169 
170  //Normalization of branching ratios in bifurcation vector by its norm.
171  //sum:
172  double sum=0;
173  for(auto &b : bifurcation_[i_reaction])
174  sum += b;
175  //Normalization:
176  for(auto &b : bifurcation_[i_reaction])
177  b = b / sum;
178  }
179 }
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
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
SubstanceList substances_
Names belonging to substances.
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
Class ReactionTerm is an abstract class representing reaction term in transport.
~FirstOrderReaction(void)
Destructor.
IteratorBase end() const
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
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
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
#define xprintf(...)
Definition: system.hh:92
static const Input::Type::Record & get_input_type_reactant()
Input record for a reactant of a reaction.
static Input::Type::Abstract & it_abstract_immobile_term()
static const Input::Type::Record & get_input_type_product()
Input record for a product of a reaction.
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
void initialize_from_input() override
Initializes private members of sorption from the input record.
static Input::Type::Abstract & it_abstract_term()
Definition: system.hh:64
Input::Record input_record_
Definition: equation.hh:225
static const Input::Type::Record & get_input_type()
Input record for class FirstOrderReaction.
static const Input::Type::Record & get_input_type_single_reaction()
Input record which defines particular reaction.
FirstOrderReaction(Mesh &init_mesh, Input::Record in_rec)
Constructor.
static const int registrar
Registrar of class to factory.
std::vector< std::vector< unsigned int > > substance_ids_
unsigned int size() const
Record type proxy class.
Definition: type_record.hh:182
Class implements the linear reactions.
unsigned int n_substances_
Number of all transported substances. It is the dimension of the reaction matrix. ...
std::vector< double > reaction_rates_
Vector of reaction rates of the transported substances.
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
void assemble_ode_matrix(void) override
Implements the assembly of the system matrix of the ODEs.
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
std::vector< std::vector< double > > bifurcation_