Flow123d  release_1.8.2-1603-g0109a2b
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  VecDestroy(vconc_solid);
124 
125  for (unsigned int sbi = 0; sbi < substances_.size(); sbi++)
126  {
127  //no mpi vectors
128  xfree(conc_solid[sbi]);
129  }
130  xfree(conc_solid);
131  }
132 }
133 
135 {
137 
138  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_liquid");
139  if ( reactions_it )
140  {
141  // TODO: allowed instances in this case are only
142  // FirstOrderReaction, RadioactiveDecay
143  reaction_liquid = (*reactions_it).factory< ReactionTerm, Mesh &, Input::Record >(*mesh_, *reactions_it);
144  } else
145  {
146  reaction_liquid = nullptr;
147  }
148 
149  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_solid");
150  if ( reactions_it )
151  {
152  // TODO: allowed instances in this case are only
153  // FirstOrderReaction, RadioactiveDecay
154  reaction_solid = (*reactions_it).factory< ReactionTerm, Mesh &, Input::Record >(*mesh_, *reactions_it);
155  } else
156  {
157  reaction_solid = nullptr;
158  }
159 }
160 
162 {
163  OLD_ASSERT(distribution_ != nullptr, "Distribution has not been set yet.\n");
164  OLD_ASSERT(time_ != nullptr, "Time governor has not been set yet.\n");
165  OLD_ASSERT(output_stream_,"Null output stream.");
167 
168  initialize_substance_ids(); //computes present substances and sets indices
169  initialize_from_input(); //reads non-field data from input
170 
171  //isotherms array resized bellow
172  unsigned int nr_of_regions = mesh_->region_db().bulk_size();
173  isotherms.resize(nr_of_regions);
174  for(unsigned int i_reg = 0; i_reg < nr_of_regions; i_reg++)
175  {
176  isotherms[i_reg].resize(n_substances_);
177  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
178  {
179  isotherms[i_reg][i_subst] = Isotherm();
180  }
181  }
182 
183  //allocating new array for sorbed concentrations
184  conc_solid = (double**) xmalloc(substances_.size() * sizeof(double*));//new double * [n_substances_];
185  conc_solid_out.clear();
186  conc_solid_out.resize( substances_.size() );
187  for (unsigned int sbi = 0; sbi < substances_.size(); sbi++)
188  {
189  conc_solid[sbi] = (double*) xmalloc(distribution_->lsize() * sizeof(double));//new double[ nr_of_local_elm ];
190  conc_solid_out[sbi].resize( distribution_->size() );
191  //zero initialization of solid concentration for all substances
192  for(unsigned int i=0; i < distribution_->lsize(); i++)
193  conc_solid[sbi][i] = 0;
194  }
195 
197 
199 
200  if(reaction_liquid)
201  {
202  reaction_liquid->substances(substances_)
203  .concentration_matrix(concentration_matrix_, distribution_, el_4_loc_, row_4_el_)
204  .set_time_governor(*time_);
205  reaction_liquid->initialize();
206  }
207  if(reaction_solid)
208  {
209  reaction_solid->substances(substances_)
210  .concentration_matrix(conc_solid, distribution_, el_4_loc_, row_4_el_)
211  .set_time_governor(*time_);
212  reaction_solid->initialize();
213  }
214 }
215 
216 
218 {
219  Input::Array substances_array = input_record_.val<Input::Array>("substances");
220  unsigned int k, global_idx, i_subst = 0;
221  bool found;
222  Input::Iterator<string> spec_iter = substances_array.begin<string>();
223 
224  for(; spec_iter != substances_array.end(); ++spec_iter, i_subst++)
225  {
226  //finding the name of a substance in the global array of names
227  found = false;
228  for(k = 0; k < substances_.size(); k++)
229  {
230  if (*spec_iter == substances_[k].name())
231  {
232  global_idx = k;
233  found = true;
234  break;
235  }
236  }
237 
238  if(!found)
239  THROW(ReactionTerm::ExcUnknownSubstance()
240  << ReactionTerm::EI_Substance(*spec_iter)
241  << substances_array.ei_address());
242 
243  //finding the global index of substance in the local array
244  found = false;
245  for(k = 0; k < substance_global_idx_.size(); k++)
246  {
247  if(substance_global_idx_[k] == global_idx)
248  {
249  found = true;
250  break;
251  }
252  }
253 
254  if(!found)
255  {
256  substance_global_idx_.push_back(global_idx);
257  }
258 
259  }
261 }
262 
264 {
265  // read number of interpolation steps - value checked by the record definition
266  n_interpolation_steps_ = input_record_.val<int>("substeps");
267 
268  // read the density of solvent - value checked by the record definition
269  solvent_density_ = input_record_.val<double>("solvent_density");
270 
271  // read the solubility vector
272  Input::Iterator<Input::Array> solub_iter = input_record_.find<Input::Array>("solubility");
273  if( solub_iter )
274  {
275  if (solub_iter->Array::size() != n_substances_)
276  {
277  THROW(SorptionBase::ExcSubstanceCountMatch()
278  << SorptionBase::EI_ArrayName("solubility")
280  // there is no way to get ei_address from 'solub_iter', only as a string
281  }
282 
283  else solub_iter->copy_to(solubility_vec_);
284  }
285  else{
286  // fill solubility_vec_ with zeros
287  solubility_vec_.clear();
288  solubility_vec_.resize(n_substances_,0.0);
289  }
290 
291  // read the interpolation table limits
292  Input::Iterator<Input::Array> interp_table_limits = input_record_.find<Input::Array>("table_limits");
293  if( interp_table_limits )
294  {
295  if (interp_table_limits->Array::size() != n_substances_)
296  {
297  THROW(SorptionBase::ExcSubstanceCountMatch()
298  << SorptionBase::EI_ArrayName("table_limits")
300  // there is no way to get ei_address from 'interp_table_limits', only as a string
301  }
302 
303  else interp_table_limits->copy_to(table_limit_);
304  }
305  else{
306  // fill table_limit_ with zeros
307  table_limit_.clear();
308  table_limit_.resize(n_substances_,0.0);
309  }
310 }
311 
313 {
314  OLD_ASSERT(n_substances_ > 0, "Number of substances is wrong, they might have not been set yet.\n");
315 
316  // create vector of substances that are involved in sorption
317  // and initialize data_ with their names
318  std::vector<std::string> substances_sorption;
319  for (unsigned int i : substance_global_idx_)
320  substances_sorption.push_back(substances_[i].name());
321  data_->set_components(substances_sorption);
322 
323  // read fields from input file
325 
326  data_->set_mesh(*mesh_);
327 
328  //initialization of output
329  output_array = input_record_.val<Input::Array>("output_fields");
334  for (unsigned int sbi=0; sbi<substances_.size(); sbi++)
335  {
336  // create shared pointer to a FieldElementwise and push this Field to output_field on all regions
337  auto output_field_ptr = conc_solid_out[sbi].create_field<3, FieldValue<3>::Scalar>(substances_.size());
338  data_->conc_solid[sbi].set_field(mesh_->region_db().get_region_set("ALL"), output_field_ptr, 0);
339  }
340  output_stream_->add_admissible_field_names(output_array);
341 }
342 
343 
345 {
346  OLD_ASSERT(distribution_ != nullptr, "Distribution has not been set yet.\n");
347  OLD_ASSERT(time_ != nullptr, "Time governor has not been set yet.\n");
348  OLD_ASSERT(output_stream_,"Null output stream.");
350 
353  make_tables();
354 
355  // write initial condition
359 
360  if(reaction_liquid) reaction_liquid->zero_time_step();
361  if(reaction_solid) reaction_solid->zero_time_step();
362 }
363 
365 {
366  for (unsigned int loc_el = 0; loc_el < distribution_->lsize(); loc_el++)
367  {
368  unsigned int index = el_4_loc_[loc_el];
369  ElementAccessor<3> ele_acc = mesh_->element_accessor(index);
370  arma::vec value = data_->init_conc_solid.value(ele_acc.centre(),
371  ele_acc);
372 
373  //setting initial solid concentration for substances involved in adsorption
374  for (unsigned int sbi = 0; sbi < n_substances_; sbi++)
375  {
376  int subst_id = substance_global_idx_[sbi];
377  conc_solid[subst_id][loc_el] = value(sbi);
378  }
379  }
380 }
381 
382 
384 {
385  data_->set_time(time_->step(), LimitSide::right); // set to the last computed time
386 
387  // if parameters changed during last time step, reinit isotherms and eventualy
388  // update interpolation tables in the case of constant rock matrix parameters
389  if(data_->changed())
390  make_tables();
391 
392 
393  START_TIMER("Sorption");
394  for (unsigned int loc_el = 0; loc_el < distribution_->lsize(); loc_el++)
395  {
397  }
398  END_TIMER("Sorption");
399 
400  if(reaction_liquid) reaction_liquid->update_solution();
401  if(reaction_solid) reaction_solid->update_solution();
402 }
403 
405 {
406  try
407  {
408  ElementAccessor<3> elm;
409  BOOST_FOREACH(const Region &reg_iter, this->mesh_->region_db().get_region_set("BULK") )
410  {
411  int reg_idx = reg_iter.bulk_idx();
412 
413  if(data_->is_constant(reg_iter))
414  {
415  ElementAccessor<3> elm(this->mesh_, reg_iter); // constant element accessor
416  isotherm_reinit(isotherms[reg_idx],elm);
417  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
418  {
419  isotherms[reg_idx][i_subst].make_table(n_interpolation_steps_);
420  }
421  }
422  }
423  }
424  catch(ExceptionBase const &e)
425  {
426  e << input_record_.ei_address();
427  throw;
428  }
429 }
430 
431 double **SorptionBase::compute_reaction(double **concentrations, int loc_el)
432 {
433  ElementFullIter elem = mesh_->element(el_4_loc_[loc_el]);
434  int reg_idx = elem->region().bulk_idx();
435  unsigned int i_subst, subst_id;
436 
437  std::vector<Isotherm> & isotherms_vec = isotherms[reg_idx];
438 
439  try{
440  // Constant value of rock density and mobile porosity over the whole region
441  // => interpolation_table is precomputed
442  if (isotherms_vec[0].is_precomputed())
443  {
444  for(i_subst = 0; i_subst < n_substances_; i_subst++)
445  {
446  subst_id = substance_global_idx_[i_subst];
447 
448  isotherms_vec[i_subst].interpolate(concentration_matrix_[subst_id][loc_el],
449  conc_solid[subst_id][loc_el]);
450  }
451  }
452  else
453  {
454  isotherm_reinit(isotherms_vec, elem->element_accessor());
455 
456  for(i_subst = 0; i_subst < n_substances_; i_subst++)
457  {
458  subst_id = substance_global_idx_[i_subst];
459  isotherms_vec[i_subst].compute(concentration_matrix_[subst_id][loc_el],
460  conc_solid[subst_id][loc_el]);
461  }
462  }
463  }
464  catch(ExceptionBase const &e)
465  {
466  e << input_record_.ei_address();
467  throw;
468  }
469 
470  return concentrations;
471 }
472 
473 
474 /**************************************** OUTPUT ***************************************************/
475 
477 {
478  int sbi, n_subst;
479  n_subst = substances_.size();
480 
481  vconc_solid = (Vec*) xmalloc(n_subst * (sizeof(Vec)));
482 
483  for (sbi = 0; sbi < n_subst; sbi++) {
484  VecCreateMPIWithArray(PETSC_COMM_WORLD,1, distribution_->lsize(), mesh_->n_elements(), conc_solid[sbi],
485  &vconc_solid[sbi]);
486  VecZeroEntries(vconc_solid[sbi]);
487 
488  VecZeroEntries(conc_solid_out[sbi].get_data_petsc());
489  }
490 
491  // creating output vector scatter
492  IS is;
493  ISCreateGeneral(PETSC_COMM_SELF, mesh_->n_elements(), row_4_el_, PETSC_COPY_VALUES, &is); //WithArray
494  VecScatterCreate(vconc_solid[0], is, conc_solid_out[0].get_data_petsc(), PETSC_NULL, &vconc_out_scatter);
495  ISDestroy(&(is));
496 }
497 
498 
500 {
501  unsigned int sbi;
502 
503  for (sbi = 0; sbi < substances_.size(); sbi++) {
504  VecScatterBegin(vconc_out_scatter, vconc_solid[sbi], conc_solid_out[sbi].get_data_petsc(), INSERT_VALUES, SCATTER_FORWARD);
505  VecScatterEnd(vconc_out_scatter, vconc_solid[sbi], conc_solid_out[sbi].get_data_petsc(), INSERT_VALUES, SCATTER_FORWARD);
506  }
507 }
508 
509 
511 {
513 
514  // Register fresh output data
517 }
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:275
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:329
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:261
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
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:321
Definition: mesh.h:99
Iterator< Ret > find(const string &key) const
int * row_4_el_
Indices of rows belonging to elements.
static const Input::Type::Selection & get_sorption_type_selection()
const RegionDB & region_db() const
Definition: mesh.h:156
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:460
unsigned int size() const
Definition: substance.hh:87
Class for declaration of inputs sequences.
Definition: type_base.hh:316
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:193
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:128
void setup_components()
unsigned int n_elements() const
Definition: mesh.h:142
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:513
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:49
void output_data(void) override
Output method.
static constexpr Mask input_copy
A field that is input of its equation and can not read from input, thus must be set by copy...
Definition: field_flag.hh:39
Vec * vconc_solid
PETSC sorbed concentration vector (parallel).
MultiField< 3, FieldValue< 3 >::Scalar > init_conc_solid
Initial sorbed concentrations.
FieldSet output_fields
Fields indended for output, i.e. all input fields plus those representing solution.
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:131
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:459
void output_vector_gather(void) override
Gathers all the parallel vectors to enable them to be output.
Input::Array output_array
void update_solution(void) override
Updates the solution.
void * xmalloc(size_t size)
Memory allocation with checking.
Definition: system.cc:198
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 output(std::shared_ptr< OutputTime > stream)
Definition: field_set.cc:169
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.
Base of exceptions used in Flow123d.
Definition: exceptions.hh:66
unsigned int n_substances_
#define xfree(p)
Definition: system.hh:95
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:563
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:44
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:225
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.