Flow123d  release_3.0.0-902-gf72c4b4
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  .close();
76 }
77 
79  Input::register_class< FirstOrderReaction, Mesh &, Input::Record >("FirstOrderReaction") +
81 
82 
84  : FirstOrderReactionBase(init_mesh, in_rec)
85 {
86 }
87 
89 {
90 }
91 
93 {
94  // create decay matrix
96  unsigned int reactant_index, product_index; //global indices of the substances
97  double exponent; //temporary variable for k
98  for (unsigned int i_reaction = 0; i_reaction < reaction_rates_.size(); i_reaction++) {
99  reactant_index = substance_ids_[i_reaction][0];
100  exponent = reaction_rates_[i_reaction];
101  reaction_matrix_(reactant_index, reactant_index) = -exponent;
102 
103  for (unsigned int i_product = 1; i_product < substance_ids_[i_reaction].size(); ++i_product){
104  product_index = substance_ids_[i_reaction][i_product];
105  reaction_matrix_(product_index, reactant_index) = exponent * bifurcation_[i_reaction][i_product-1];
106  }
107  }
108 }
109 
110 
112 {
113  unsigned int idx; //temporary variable, indexing substances
114 
115  Input::Array reactions_array = input_record_.val<Input::Array>("reactions");
116 
117  substance_ids_.resize( reactions_array.size() );
118  reaction_rates_.resize( reactions_array.size() );
119  bifurcation_.resize( reactions_array.size() );
120 
121  int i_reaction=0;
122  for (Input::Iterator<Input::Record> react_it = reactions_array.begin<Input::Record>();
123  react_it != reactions_array.end(); ++react_it, ++i_reaction)
124  {
125  //read reaction rate
126  reaction_rates_[i_reaction] = react_it->val<double>("reaction_rate");
127 
128  //read reactant name, product names and branching ratios
129  Input::Array reactant_array = react_it->val<Input::Array>("reactants");
130  Input::Array product_array = react_it->val<Input::Array>("products");
131 
132  //resize substance_ids array
133  substance_ids_[i_reaction].resize( product_array.size()+1 );
134  bifurcation_[i_reaction].resize(product_array.size());
135 
136  if(reactant_array.size() != 1)
137  xprintf(UsrErr, "More than one reactant is not available at the moment.");
138 
139  //take only one reactant
140  Input::Iterator<Input::Record> reactant_it = reactant_array.begin<Input::Record>();
141  {
142  string reactant_name = reactant_it->val<string>("name");
143  idx = find_subst_name(reactant_name);
144  if (idx < substances_.size())
145  substance_ids_[i_reaction][0] = idx;
146  else THROW(ReactionTerm::ExcUnknownSubstance()
147  << ReactionTerm::EI_Substance(reactant_name)
148  << (*reactant_it).ei_address());
149  }
150 
151  // set products
152  unsigned int i_product = 0;
153  for(Input::Iterator<Input::Record> product_it = product_array.begin<Input::Record>();
154  product_it != product_array.end(); ++product_it, i_product++)
155  {
156  string product_name = product_it->val<string>("name");
157  idx = find_subst_name(product_name);
158  if (idx < substances_.size())
159  substance_ids_[i_reaction][i_product+1] = idx;
160  else THROW(ReactionTerm::ExcUnknownSubstance()
161  << ReactionTerm::EI_Substance(product_name)
162  << product_array.ei_address());
163 
164  bifurcation_[i_reaction][i_product] = product_it->val<double>("branching_ratio");
165  }
166 
167 
168  //Normalization of branching ratios in bifurcation vector by its norm.
169  //sum:
170  double sum=0;
171  for(auto &b : bifurcation_[i_reaction])
172  sum += b;
173  //Normalization:
174  for(auto &b : bifurcation_[i_reaction])
175  b = b / sum;
176  }
177 }
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: balance.hh:37
SubstanceList substances_
Names belonging to substances.
Definition: mesh.h:80
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:346
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:541
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
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:501
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:589
#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_