Flow123d  last_with_con_2.0.0-4-g42e6930
sorption_base.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 sorption_base.cc
15  * @brief
16  */
17 
18 #include <boost/foreach.hpp>
19 
26 #include "reaction/isotherm.hh"
27 
28 #include "system/system.hh"
29 #include "system/sys_profiler.hh"
30 
31 #include "la/distribution.hh"
32 #include "mesh/mesh.h"
33 #include "mesh/elements.h"
34 #include "input/type_selection.hh"
35 
36 #include "fields/field_set.hh"
38 
39 using namespace Input::Type;
40 
42  return Selection("SorptionType")
43  .add_value(Isotherm::none,"none", "No sorption considered.")
44  .add_value(Isotherm::linear, "linear",
45  "Linear isotherm runs the concentration exchange between liquid and solid.")
46  .add_value(Isotherm::langmuir, "langmuir",
47  "Langmuir isotherm runs the concentration exchange between liquid and solid.")
48  .add_value(Isotherm::freundlich, "freundlich",
49  "Freundlich isotherm runs the concentration exchange between liquid and solid.")
50  .close();
51 }
52 
53 
54 
56  return Record("Sorption", "AUXILIARY RECORD. Should not be directly part of the input tree.")
57  .declare_key("substances", Array(String(),1), Default::obligatory(),
58  "Names of the substances that take part in the sorption model.")
59  .declare_key("solvent_density", Double(0.0), Default("1.0"),
60  "Density of the solvent.")
61  .declare_key("substeps", Integer(1), Default("1000"),
62  "Number of equidistant substeps, molar mass and isotherm intersections")
63  .declare_key("solubility", Array(Double(0.0)), Default::optional(), //("-1.0"), //
64  "Specifies solubility limits of all the sorbing species.")
65  .declare_key("table_limits", Array(Double(0.0)), Default::optional(), //("-1.0"), //
66  "Specifies highest aqueous concentration in interpolation table.")
67  .declare_key("input_fields", Array(EqData("").input_data_set_.make_field_descriptor_type("Sorption")), Default::obligatory(), //
68  "Containes region specific data necessary to construct isotherms.")//;
69  .declare_key("reaction_liquid", ReactionTerm::get_input_type(), Default::optional(), "Reaction model following the sorption in the liquid.")
70  .declare_key("reaction_solid", ReactionTerm::get_input_type(), Default::optional(), "Reaction model following the sorption in the solid.")
71  .close();
72 }
73 
74 
75 SorptionBase::EqData::EqData(const string &output_field_name)
76 {
77  ADD_FIELD(rock_density, "Rock matrix density.", "0.0");
78  rock_density.units( UnitSI().kg().m(-3) );
79 
80  ADD_FIELD(sorption_type,"Considered sorption is described by selected isotherm. If porosity on an element is equal or even higher than 1.0 (meaning no sorbing surface), then type 'none' will be selected automatically."); //
81  sorption_type.input_selection(get_sorption_type_selection());
82  sorption_type.units( UnitSI::dimensionless() );
83 
84  ADD_FIELD(isotherm_mult,"Multiplication parameters (k, omega) in either Langmuir c_s = omega * (alpha*c_a)/(1- alpha*c_a) or in linear c_s = k * c_a isothermal description.","1.0");
85  isotherm_mult.units( UnitSI().mol().kg(-1) );
86 
87  ADD_FIELD(isotherm_other,"Second parameters (alpha, ...) defining isotherm c_s = omega * (alpha*c_a)/(1- alpha*c_a).","1.0");
88  isotherm_other.units( UnitSI::dimensionless() );
89 
90  ADD_FIELD(init_conc_solid, "Initial solid concentration of substances."
91  " Vector, one value for every substance.", "0");
92  init_conc_solid.units( UnitSI().mol().kg(-1) );
93 
94  input_data_set_ += *this;
95 
96  // porosity field is set from governing equation (transport) later
97  // hence we do not add it to the input_data_set_
98  *this += porosity
99  .name("porosity")
100  .units( UnitSI::dimensionless() )
101  .flags(FieldFlag::input_copy);
102 
103  output_fields += *this;
104  output_fields += conc_solid.name(output_field_name).units( UnitSI().kg().m(-3) ).flags(FieldFlag::equation_result);
105 }
106 
107 
109  : ReactionTerm(init_mesh, in_rec),
110  data_(nullptr)
111 {
112  // creating reaction from input and setting their parameters
113  make_reactions();
114 }
115 
116 
118 {
119  if (data_ != nullptr) delete data_;
120 
121  VecScatterDestroy(&(vconc_out_scatter));
122  if (vconc_solid != NULL) {
123 
124 
125  for (unsigned int sbi = 0; sbi < substances_.size(); sbi++)
126  {
127  //no mpi vectors
128  VecDestroy( &(vconc_solid[sbi]) );
129  delete [] conc_solid[sbi];
130  }
131  delete [] vconc_solid;
132  delete [] conc_solid;
133  }
134 }
135 
137 {
139 
140  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_liquid");
141  if ( reactions_it )
142  {
143  // TODO: allowed instances in this case are only
144  // FirstOrderReaction, RadioactiveDecay
145  reaction_liquid = (*reactions_it).factory< ReactionTerm, Mesh &, Input::Record >(*mesh_, *reactions_it);
146  } else
147  {
148  reaction_liquid = nullptr;
149  }
150 
151  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_solid");
152  if ( reactions_it )
153  {
154  // TODO: allowed instances in this case are only
155  // FirstOrderReaction, RadioactiveDecay
156  reaction_solid = (*reactions_it).factory< ReactionTerm, Mesh &, Input::Record >(*mesh_, *reactions_it);
157  } else
158  {
159  reaction_solid = nullptr;
160  }
161 }
162 
164 {
165  OLD_ASSERT(distribution_ != nullptr, "Distribution has not been set yet.\n");
166  OLD_ASSERT(time_ != nullptr, "Time governor has not been set yet.\n");
167  OLD_ASSERT(output_stream_,"Null output stream.");
169 
170  initialize_substance_ids(); //computes present substances and sets indices
171  initialize_from_input(); //reads non-field data from input
172 
173  //isotherms array resized bellow
174  unsigned int nr_of_regions = mesh_->region_db().bulk_size();
175  isotherms.resize(nr_of_regions);
176  for(unsigned int i_reg = 0; i_reg < nr_of_regions; i_reg++)
177  {
178  isotherms[i_reg].resize(n_substances_);
179  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
180  {
181  isotherms[i_reg][i_subst] = Isotherm();
182  }
183  }
184 
185  //allocating new array for sorbed concentrations
186  conc_solid = new double* [substances_.size()];
187  conc_solid_out.clear();
188  conc_solid_out.resize( substances_.size() );
189  for (unsigned int sbi = 0; sbi < substances_.size(); sbi++)
190  {
191  conc_solid[sbi] = new double [distribution_->lsize()];
192  conc_solid_out[sbi].resize( distribution_->size() );
193  //zero initialization of solid concentration for all substances
194  for(unsigned int i=0; i < distribution_->lsize(); i++)
195  conc_solid[sbi][i] = 0;
196  }
197 
199 
201 
202  if(reaction_liquid)
203  {
204  reaction_liquid->substances(substances_)
205  .concentration_matrix(concentration_matrix_, distribution_, el_4_loc_, row_4_el_)
206  .set_time_governor(*time_);
207  reaction_liquid->initialize();
208  }
209  if(reaction_solid)
210  {
211  reaction_solid->substances(substances_)
212  .concentration_matrix(conc_solid, distribution_, el_4_loc_, row_4_el_)
213  .set_time_governor(*time_);
214  reaction_solid->initialize();
215  }
216 }
217 
218 
220 {
221  Input::Array substances_array = input_record_.val<Input::Array>("substances");
222  unsigned int k, global_idx, i_subst = 0;
223  bool found;
224  Input::Iterator<string> spec_iter = substances_array.begin<string>();
225 
226  for(; spec_iter != substances_array.end(); ++spec_iter, i_subst++)
227  {
228  //finding the name of a substance in the global array of names
229  found = false;
230  for(k = 0; k < substances_.size(); k++)
231  {
232  if (*spec_iter == substances_[k].name())
233  {
234  global_idx = k;
235  found = true;
236  break;
237  }
238  }
239 
240  if(!found)
241  THROW(ReactionTerm::ExcUnknownSubstance()
242  << ReactionTerm::EI_Substance(*spec_iter)
243  << substances_array.ei_address());
244 
245  //finding the global index of substance in the local array
246  found = false;
247  for(k = 0; k < substance_global_idx_.size(); k++)
248  {
249  if(substance_global_idx_[k] == global_idx)
250  {
251  found = true;
252  break;
253  }
254  }
255 
256  if(!found)
257  {
258  substance_global_idx_.push_back(global_idx);
259  }
260 
261  }
263 }
264 
266 {
267  // read number of interpolation steps - value checked by the record definition
268  n_interpolation_steps_ = input_record_.val<int>("substeps");
269 
270  // read the density of solvent - value checked by the record definition
271  solvent_density_ = input_record_.val<double>("solvent_density");
272 
273  // read the solubility vector
274  Input::Iterator<Input::Array> solub_iter = input_record_.find<Input::Array>("solubility");
275  if( solub_iter )
276  {
277  if (solub_iter->Array::size() != n_substances_)
278  {
279  THROW(SorptionBase::ExcSubstanceCountMatch()
280  << SorptionBase::EI_ArrayName("solubility")
282  // there is no way to get ei_address from 'solub_iter', only as a string
283  }
284 
285  else solub_iter->copy_to(solubility_vec_);
286  }
287  else{
288  // fill solubility_vec_ with zeros
289  solubility_vec_.clear();
290  solubility_vec_.resize(n_substances_,0.0);
291  }
292 
293  // read the interpolation table limits
294  Input::Iterator<Input::Array> interp_table_limits = input_record_.find<Input::Array>("table_limits");
295  if( interp_table_limits )
296  {
297  if (interp_table_limits->Array::size() != n_substances_)
298  {
299  THROW(SorptionBase::ExcSubstanceCountMatch()
300  << SorptionBase::EI_ArrayName("table_limits")
302  // there is no way to get ei_address from 'interp_table_limits', only as a string
303  }
304 
305  else interp_table_limits->copy_to(table_limit_);
306  }
307  else{
308  // fill table_limit_ with zeros
309  table_limit_.clear();
310  table_limit_.resize(n_substances_,0.0);
311  }
312 }
313 
315 {
316  OLD_ASSERT(n_substances_ > 0, "Number of substances is wrong, they might have not been set yet.\n");
317 
318  // create vector of substances that are involved in sorption
319  // and initialize data_ with their names
320  std::vector<std::string> substances_sorption;
321  for (unsigned int i : substance_global_idx_)
322  substances_sorption.push_back(substances_[i].name());
323  data_->set_components(substances_sorption);
324 
325  // read fields from input file
327 
328  data_->set_mesh(*mesh_);
329 
330  //initialization of output
331  //output_array = input_record_.val<Input::Array>("output_fields");
336  for (unsigned int sbi=0; sbi<substances_.size(); sbi++)
337  {
338  // create shared pointer to a FieldElementwise and push this Field to output_field on all regions
339  auto output_field_ptr = conc_solid_out[sbi].create_field<3, FieldValue<3>::Scalar>(substances_.size());
340  data_->conc_solid[sbi].set_field(mesh_->region_db().get_region_set("ALL"), output_field_ptr, 0);
341  }
342  //output_stream_->add_admissible_field_names(output_array);
344 }
345 
346 
348 {
349  OLD_ASSERT(distribution_ != nullptr, "Distribution has not been set yet.\n");
350  OLD_ASSERT(time_ != nullptr, "Time governor has not been set yet.\n");
351  OLD_ASSERT(output_stream_,"Null output stream.");
353 
356  make_tables();
357 
358  // write initial condition
359  //output_vector_gather();
360  //data_->output_fields.set_time(time_->step(), LimitSide::right);
361  //data_->output_fields.output(output_stream_);
362 
363  if(reaction_liquid) reaction_liquid->zero_time_step();
364  if(reaction_solid) reaction_solid->zero_time_step();
365 
366  output_data();
367 }
368 
370 {
371  for (unsigned int loc_el = 0; loc_el < distribution_->lsize(); loc_el++)
372  {
373  unsigned int index = el_4_loc_[loc_el];
374  ElementAccessor<3> ele_acc = mesh_->element_accessor(index);
375  arma::vec value = data_->init_conc_solid.value(ele_acc.centre(),
376  ele_acc);
377 
378  //setting initial solid concentration for substances involved in adsorption
379  for (unsigned int sbi = 0; sbi < n_substances_; sbi++)
380  {
381  int subst_id = substance_global_idx_[sbi];
382  conc_solid[subst_id][loc_el] = value(sbi);
383  }
384  }
385 }
386 
387 
389 {
390  data_->set_time(time_->step(), LimitSide::right); // set to the last computed time
391 
392  // if parameters changed during last time step, reinit isotherms and eventualy
393  // update interpolation tables in the case of constant rock matrix parameters
394  if(data_->changed())
395  make_tables();
396 
397 
398  START_TIMER("Sorption");
399  for (unsigned int loc_el = 0; loc_el < distribution_->lsize(); loc_el++)
400  {
402  }
403  END_TIMER("Sorption");
404 
405  if(reaction_liquid) reaction_liquid->update_solution();
406  if(reaction_solid) reaction_solid->update_solution();
407 }
408 
410 {
411  try
412  {
413  ElementAccessor<3> elm;
414  BOOST_FOREACH(const Region &reg_iter, this->mesh_->region_db().get_region_set("BULK") )
415  {
416  int reg_idx = reg_iter.bulk_idx();
417 
418  if(data_->is_constant(reg_iter))
419  {
420  ElementAccessor<3> elm(this->mesh_, reg_iter); // constant element accessor
421  isotherm_reinit(isotherms[reg_idx],elm);
422  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
423  {
424  isotherms[reg_idx][i_subst].make_table(n_interpolation_steps_);
425  }
426  }
427  }
428  }
429  catch(ExceptionBase const &e)
430  {
431  e << input_record_.ei_address();
432  throw;
433  }
434 }
435 
436 double **SorptionBase::compute_reaction(double **concentrations, int loc_el)
437 {
438  ElementFullIter elem = mesh_->element(el_4_loc_[loc_el]);
439  int reg_idx = elem->region().bulk_idx();
440  unsigned int i_subst, subst_id;
441 
442  std::vector<Isotherm> & isotherms_vec = isotherms[reg_idx];
443 
444  try{
445  // Constant value of rock density and mobile porosity over the whole region
446  // => interpolation_table is precomputed
447  if (isotherms_vec[0].is_precomputed())
448  {
449  for(i_subst = 0; i_subst < n_substances_; i_subst++)
450  {
451  subst_id = substance_global_idx_[i_subst];
452 
453  isotherms_vec[i_subst].interpolate(concentration_matrix_[subst_id][loc_el],
454  conc_solid[subst_id][loc_el]);
455  }
456  }
457  else
458  {
459  isotherm_reinit(isotherms_vec, elem->element_accessor());
460 
461  for(i_subst = 0; i_subst < n_substances_; i_subst++)
462  {
463  subst_id = substance_global_idx_[i_subst];
464  isotherms_vec[i_subst].compute(concentration_matrix_[subst_id][loc_el],
465  conc_solid[subst_id][loc_el]);
466  }
467  }
468  }
469  catch(ExceptionBase const &e)
470  {
471  e << input_record_.ei_address();
472  throw;
473  }
474 
475  return concentrations;
476 }
477 
478 
479 /**************************************** OUTPUT ***************************************************/
480 
482 {
483  int sbi, n_subst;
484  n_subst = substances_.size();
485 
486  vconc_solid = new Vec [n_subst];
487 
488  for (sbi = 0; sbi < n_subst; sbi++) {
489  VecCreateMPIWithArray(PETSC_COMM_WORLD,1, distribution_->lsize(), mesh_->n_elements(), conc_solid[sbi],
490  &vconc_solid[sbi]);
491  VecZeroEntries(vconc_solid[sbi]);
492 
493  VecZeroEntries(conc_solid_out[sbi].get_data_petsc());
494  }
495 
496  // creating output vector scatter
497  IS is;
498  ISCreateGeneral(PETSC_COMM_SELF, mesh_->n_elements(), row_4_el_, PETSC_COPY_VALUES, &is); //WithArray
499  VecScatterCreate(vconc_solid[0], is, conc_solid_out[0].get_data_petsc(), PETSC_NULL, &vconc_out_scatter);
500  ISDestroy(&(is));
501 }
502 
503 
505 {
506  unsigned int sbi;
507 
508  for (sbi = 0; sbi < substances_.size(); sbi++) {
509  VecScatterBegin(vconc_out_scatter, vconc_solid[sbi], conc_solid_out[sbi].get_data_petsc(), INSERT_VALUES, SCATTER_FORWARD);
510  VecScatterEnd(vconc_out_scatter, vconc_solid[sbi], conc_solid_out[sbi].get_data_petsc(), INSERT_VALUES, SCATTER_FORWARD);
511  }
512 }
513 
514 
516 {
520  }
521 
522  // Register fresh output data
523  data_->output_fields.output(time().step());
524 }
TimeGovernor & time()
Definition: equation.hh:146
void output_type(OutputTime::DiscreteSpace rt)
Definition: field_set.hh:203
unsigned int size() const
get global size
void set_input_list(Input::Array input_list)
Definition: field_set.hh:180
std::shared_ptr< ReactionTerm > reaction_solid
Iterator< ValueType > begin() const
void allocate_output_mpi(void)
Allocates petsc vectors, prepares them for output and creates vector scatter.
#define ADD_FIELD(name,...)
Definition: field_set.hh:271
MultiField< 3, FieldValue< 3 >::Scalar > conc_solid
Calculated sorbed concentrations, for output only.
void make_reactions()
std::vector< VectorSeqDouble > conc_solid_out
sorbed concentration array output (gathered - sequential)
Accessor to input data conforming to declared Array.
Definition: accessors.hh:552
double solvent_density_
EI_Address ei_address() const
Definition: accessors.cc:306
std::vector< std::vector< Isotherm > > isotherms
virtual ~SorptionBase(void)
void initialize_substance_ids()
Reads names of substances from input and creates indexing to global vector of substance.
double ** concentration_matrix_
unsigned int bulk_size() const
Definition: region.cc:268
const std::vector< std::string > & names()
Definition: substance.hh:85
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:50
EqData(const string &output_field_name)
Collect all fields.
static Input::Type::Abstract & get_input_type()
void set_time(const TimeStep &time, LimitSide limit_side)
Definition: field_set.hh:195
void output(TimeStep step)
double ** compute_reaction(double **concentrations, int loc_el)
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:99
SubstanceList substances_
Names belonging to substances.
void zero_time_step() override
RegionSet get_region_set(const string &set_name) const
Definition: region.cc:328
Definition: mesh.h:95
Iterator< Ret > find(const string &key) const
int * row_4_el_
Indices of rows belonging to elements.
void initialize(std::shared_ptr< OutputTime > stream, Input::Record in_rec, const TimeGovernor &tg)
EquationOutput output_fields
Fields indended for output, i.e. all input fields plus those representing solution.
static const Input::Type::Selection & get_sorption_type_selection()
const RegionDB & region_db() const
Definition: mesh.h:152
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:700
const TimeStep & step(int index=-1) const
std::vector< double > table_limit_
Class for declaration of the integral input data.
Definition: type_base.hh:465
unsigned int size() const
Definition: substance.hh:87
Class for declaration of inputs sequences.
Definition: type_base.hh:321
std::shared_ptr< OutputTime > output_stream_
Pointer to a transport output stream.
ReactionTerm(Mesh &init_mesh, Input::Record in_rec)
Constructor.
Class ReactionTerm is an abstract class representing reaction term in transport.
std::vector< unsigned int > substance_global_idx_
Mapping from local indexing of substances to global.
void initialize_fields()
Initializes field sets.
Class Dual_por_exchange implements the model of dual porosity.
IteratorBase end() const
EI_Address ei_address() const
Definition: accessors.cc:170
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:113
#define OLD_ASSERT(...)
Definition: global_defs.h:131
void setup_components()
unsigned int n_elements() const
Definition: mesh.h:138
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:518
Distribution * distribution_
Pointer to reference to distribution of elements between processors.
static constexpr Mask equation_result
Match result fields. These are never given by input or copy of input.
Definition: field_flag.hh:55
void output_data(void) override
Output method.
static constexpr Mask input_copy
Definition: field_flag.hh:44
Vec * vconc_solid
PETSC sorbed concentration vector (parallel).
MultiField< 3, FieldValue< 3 >::Scalar > init_conc_solid
Initial sorbed concentrations.
void initialize_from_input()
Initializes private members of sorption from the input record.
std::vector< double > solubility_vec_
Selection & add_value(const int value, const std::string &key, const std::string &description="")
Adds one new value with name given by key to the Selection.
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
unsigned int n_interpolation_steps_
const Ret val(const string &key) const
void make_tables(void)
#define START_TIMER(tag)
Starts a timer with specified tag.
#define OLD_ASSERT_LESS(a, b)
Definition: global_defs.h:134
Mesh * mesh_
Definition: equation.hh:221
virtual void isotherm_reinit(std::vector< Isotherm > &isotherms, const ElementAccessor< 3 > &elm)=0
Reinitializes the isotherm.
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
void output_vector_gather(void) override
Gathers all the parallel vectors to enable them to be output.
void update_solution(void) override
Updates the solution.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:444
Support classes for parallel programing.
Class SorptionBase is abstract class representing model of sorption in transport. ...
virtual MultiFieldValue::return_type value(const Point &p, const ElementAccessor< spacedim > &elm) const
const Selection & close() const
Close the Selection, no more values can be added.
Input::Record input_record_
Definition: equation.hh:223
void set_components(const std::vector< string > &names)
Definition: field_set.hh:167
int * el_4_loc_
Indices of elements belonging to local dofs.
void set_initial_condition()
Reads and sets initial condition for concentration in solid.
bool is_constant(Region reg) const
Definition: field_set.cc:154
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Definition: region.hh:90
#define END_TIMER(tag)
Ends a timer with specified tag.
arma::vec::fixed< spacedim > centre() const
Definition: accessors.hh:91
double ** conc_solid
void set_mesh(const Mesh &mesh)
Definition: field_set.hh:173
void set_components(const std::vector< string > &names)
Record type proxy class.
Definition: type_record.hh:171
static const Input::Type::Record & get_input_type()
VecScatter vconc_out_scatter
Output vector scatter.
bool is_field_output_time(const FieldCommon &field, TimeStep step) const
Base of exceptions used in Flow123d.
Definition: exceptions.hh:67
unsigned int n_substances_
Class for representation SI units of Fields.
Definition: unit_si.hh:40
EqData * data_
Pointer to equation data. The object is constructed in descendants.
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:53
Other possible transformation of coordinates:
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
bool changed() const
Definition: field_set.cc:146
Template for classes storing finite set of named values.
Input::Type::Record make_field_descriptor_type(const std::string &equation_name) const
Definition: field_set.cc:61
TimeGovernor * time_
Definition: equation.hh:222
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:221
FieldSet input_data_set_
Input data set - fields in this set are read from the input file.
std::shared_ptr< ReactionTerm > reaction_liquid
unsigned int lsize(int proc) const
get local size
void initialize() override
Prepares the object to usage.