Flow123d  JS_before_hm-946-gd238683
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 
25 #include "reaction/isotherm.hh"
26 
27 #include "system/system.hh"
28 #include "system/sys_profiler.hh"
29 
30 #include "la/distribution.hh"
31 #include "mesh/mesh.h"
32 #include "mesh/elements.h"
33 #include "mesh/accessors.hh"
34 #include "input/type_selection.hh"
35 
36 #include "fields/field_set.hh"
37 #include "fields/field_fe.hh"
39 
40 using namespace Input::Type;
41 
43  return Selection("SorptionType")
44  .add_value(Isotherm::none,"none", "No sorption considered.")
45  .add_value(Isotherm::linear, "linear",
46  "Linear isotherm runs the concentration exchange between liquid and solid.")
47  .add_value(Isotherm::langmuir, "langmuir",
48  "Langmuir isotherm runs the concentration exchange between liquid and solid.")
49  .add_value(Isotherm::freundlich, "freundlich",
50  "Freundlich isotherm runs the concentration exchange between liquid and solid.")
51  .close();
52 }
53 
54 
55 
57  return Record("SorptionAux", "AUXILIARY RECORD. Should not be directly part of the input tree.")
58  .declare_key("substances", Array(String(),1), Default::obligatory(),
59  "Names of the substances that take part in the sorption model.")
60  .declare_key("solvent_density", Double(0.0), Default("1.0"),
61  "Density of the solvent.")
62  .declare_key("substeps", Integer(1), Default("1000"),
63  "Number of equidistant substeps, molar mass and isotherm intersections")
64  .declare_key("solubility", Array(Double(0.0)), Default::optional(), //("-1.0"), //
65  "Specifies solubility limits of all the sorbing species.")
66  .declare_key("table_limits", Array(Double(-1.0)), Default::optional(), //("-1.0"), //
67  "Specifies the highest aqueous concentration in the isotherm function interpolation table. "
68  "Use any negative value for an automatic choice according to current maximal concentration (default and recommended). "
69  "Use '0' to always evaluate isotherm function directly (can be very slow). "
70  "Use a positive value to set the interpolation table limit manually "
71  "(if aqueous concentration is higher, then the isotherm function is evaluated directly).")
72  .declare_key("input_fields", Array(EqData("","").input_data_set_.make_field_descriptor_type("Sorption")), Default::obligatory(), //
73  "Containes region specific data necessary to construct isotherms.")//;
74  .declare_key("reaction_liquid", ReactionTerm::it_abstract_reaction(), Default::optional(), "Reaction model following the sorption in the liquid.")
75  .declare_key("reaction_solid", ReactionTerm::it_abstract_reaction(), Default::optional(), "Reaction model following the sorption in the solid.")
76  .close();
77 }
78 
79 
80 SorptionBase::EqData::EqData(const string &output_field_name, const string &output_field_desc)
81 {
82  *this += rock_density.name("rock_density")
83  .description("Rock matrix density.")
84  .input_default("0.0")
85  .units( UnitSI().kg().m(-3) );
86 
87  *this += sorption_type.name("sorption_type")
88  .description("Considered sorption is described by selected isotherm.\n"
89  "If porosity on an element is equal to 1.0 (or even higher), meaning no sorbing surface, then type 'none' will be selected automatically.")
90  .input_selection(get_sorption_type_selection())
91  .units( UnitSI::dimensionless() );
92 
93  *this += distribution_coefficient.name("distribution_coefficient")
94  .description("Distribution coefficient (( $k_l, k_F, k_L $)) of linear, Freundlich or Langmuir isotherm respectively.")
95  .input_default("1.0")
96  .units( UnitSI().m(3).kg(-1) );
97 
98  *this += isotherm_other.name("isotherm_other")
99  .description("Additional parameter (($ \\alpha $)) of nonlinear isotherms.")
100  .input_default("1.0")
101  .units( UnitSI::dimensionless() );
102 
103  *this += init_conc_solid.name("init_conc_solid")
104  .description("Initial solid concentration of substances. It is a vector: one value for every substance.")
105  .input_default("0")
106  .units( UnitSI().dimensionless() );
107 
108  input_data_set_ += *this;
109 
110  // porosity field is set from governing equation (transport) later
111  // hence we do not add it to the input_data_set_
112  *this += porosity
113  .name("porosity")
114  .units( UnitSI::dimensionless() )
115  .flags(FieldFlag::input_copy)
116  .set_limits(0.0);
117 
118  output_fields += *this;
119  output_fields += conc_solid.name(output_field_name)
120  .description(output_field_desc)
121  .units( UnitSI().dimensionless() )
123 }
124 
125 
127  : ReactionTerm(init_mesh, in_rec),
128  data_(nullptr)
129 {
130  // creating reaction from input and setting their parameters
131  make_reactions();
132 }
133 
134 
136 {
137  if (data_ != nullptr) delete data_;
138 }
139 
141 {
143 
144  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_liquid");
145  if ( reactions_it )
146  {
147  // TODO: allowed instances in this case are only
148  // FirstOrderReaction, RadioactiveDecay
149  reaction_liquid = (*reactions_it).factory< ReactionTerm, Mesh &, Input::Record >(*mesh_, *reactions_it);
150  } else
151  {
152  reaction_liquid = nullptr;
153  }
154 
155  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_solid");
156  if ( reactions_it )
157  {
158  // TODO: allowed instances in this case are only
159  // FirstOrderReaction, RadioactiveDecay
160  reaction_solid = (*reactions_it).factory< ReactionTerm, Mesh &, Input::Record >(*mesh_, *reactions_it);
161  } else
162  {
163  reaction_solid = nullptr;
164  }
165 }
166 
168 {
169  ASSERT_PTR(time_).error("Time governor has not been set yet.\n");
170  ASSERT(output_stream_).error("Null output stream.\n");
171  ASSERT_LT(0, substances_.size());
172 
173  initialize_substance_ids(); //computes present substances and sets indices
174  initialize_from_input(); //reads non-field data from input
175 
176  //isotherms array resized bellow
177  unsigned int nr_of_regions = mesh_->region_db().bulk_size();
178  isotherms.resize(nr_of_regions);
179  max_conc.resize(nr_of_regions);
180  for(unsigned int i_reg = 0; i_reg < nr_of_regions; i_reg++)
181  {
182  isotherms[i_reg].resize(n_substances_);
183  max_conc[i_reg].resize(n_substances_, 0.0);
184  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
185  {
186  isotherms[i_reg][i_subst] = Isotherm();
187  }
188  }
189 
191 
192  if(reaction_liquid)
193  {
194  reaction_liquid->substances(substances_)
195  .concentration_fields(conc_mobile_fe)
196  .set_time_governor(*time_);
197  reaction_liquid->initialize();
198  }
199  if(reaction_solid)
200  {
201  reaction_solid->substances(substances_)
202  .concentration_fields(data_->conc_solid_fe)
203  .set_time_governor(*time_);
204  reaction_solid->initialize();
205  }
206 }
207 
208 
210 {
211  Input::Array substances_array = input_record_.val<Input::Array>("substances");
212  unsigned int k, global_idx, i_subst = 0;
213  bool found;
214  Input::Iterator<string> spec_iter = substances_array.begin<string>();
215 
216  for(; spec_iter != substances_array.end(); ++spec_iter, i_subst++)
217  {
218  //finding the name of a substance in the global array of names
219  found = false;
220  for(k = 0; k < substances_.size(); k++)
221  {
222  if (*spec_iter == substances_[k].name())
223  {
224  global_idx = k;
225  found = true;
226  break;
227  }
228  }
229 
230  if(!found)
231  THROW(ReactionTerm::ExcUnknownSubstance()
232  << ReactionTerm::EI_Substance(*spec_iter)
233  << substances_array.ei_address());
234 
235  //finding the global index of substance in the local array
236  found = false;
237  for(k = 0; k < substance_global_idx_.size(); k++)
238  {
239  if(substance_global_idx_[k] == global_idx)
240  {
241  found = true;
242  break;
243  }
244  }
245 
246  if(!found)
247  {
248  substance_global_idx_.push_back(global_idx);
249  }
250 
251  }
253 }
254 
256 {
257  // read number of interpolation steps - value checked by the record definition
258  n_interpolation_steps_ = input_record_.val<int>("substeps");
259 
260  // read the density of solvent - value checked by the record definition
261  solvent_density_ = input_record_.val<double>("solvent_density");
262 
263  // read the solubility vector
264  Input::Iterator<Input::Array> solub_iter = input_record_.find<Input::Array>("solubility");
265  if( solub_iter )
266  {
267  if (solub_iter->Array::size() != n_substances_)
268  {
269  THROW(SorptionBase::ExcSubstanceCountMatch()
270  << SorptionBase::EI_ArrayName("solubility")
272  // there is no way to get ei_address from 'solub_iter', only as a string
273  }
274 
275  else solub_iter->copy_to(solubility_vec_);
276  }
277  else{
278  // fill solubility_vec_ with zeros
279  solubility_vec_.clear();
280  solubility_vec_.resize(n_substances_,0.0);
281  }
282 
283  // read the interpolation table limits
284  Input::Iterator<Input::Array> interp_table_limits = input_record_.find<Input::Array>("table_limits");
285  if( interp_table_limits )
286  {
287  if (interp_table_limits->Array::size() != n_substances_)
288  {
289  THROW(SorptionBase::ExcSubstanceCountMatch()
290  << SorptionBase::EI_ArrayName("table_limits")
292  // there is no way to get ei_address from 'interp_table_limits', only as a string
293  }
294 
295  else interp_table_limits->copy_to(table_limit_);
296  }
297  else{
298  // fill table_limit_ with negative values -> automatic limit
299  table_limit_.clear();
300  table_limit_.resize(n_substances_,-1.0);
301  }
302 }
303 
305 {
306  ASSERT_GT(n_substances_, 0).error("Number of substances is wrong, they might have not been set yet.\n");
307 
308  // create vector of substances that are involved in sorption
309  // and initialize data_ with their names
310  std::vector<std::string> substances_sorption;
311  for (unsigned int i : substance_global_idx_)
312  substances_sorption.push_back(substances_[i].name());
313  data_->set_components(substances_sorption);
314 
315  // read fields from input file
317 
318  data_->set_mesh(*mesh_);
319 
320  //initialization of output
321  //output_array = input_record_.val<Input::Array>("output_fields");
326 
327  //creating field fe and output multifield for sorbed concentrations
328  data_->conc_solid_fe.resize(substances_.size());
329  for (unsigned int sbi = 0; sbi < substances_.size(); sbi++)
330  {
331  data_->conc_solid_fe[sbi] = create_field_fe< 3, FieldValue<3>::Scalar >(dof_handler_);
332  data_->conc_solid[sbi].set_field(mesh_->region_db().get_region_set("ALL"), data_->conc_solid_fe[sbi], 0);
333  }
334  //output_stream_->add_admissible_field_names(output_array);
336 }
337 
338 
340 {
341  ASSERT_PTR(time_).error("Time governor has not been set yet.\n");
342  ASSERT(output_stream_).error("Null output stream.\n");
343  ASSERT_LT(0, substances_.size());
344 
346  std::stringstream ss; // print warning message with table of uninitialized fields
347  if ( FieldCommon::print_message_table(ss, "sorption") ) {
348  WarningOut() << ss.str();
349  }
351 
352  update_max_conc();
353  make_tables();
354 
355  // write initial condition
356  //data_->output_fields.set_time(time_->step(), LimitSide::right);
357  //data_->output_fields.output(output_stream_);
358 
359  if(reaction_liquid) reaction_liquid->zero_time_step();
360  if(reaction_solid) reaction_solid->zero_time_step();
361 
362  output_data();
363 }
364 
366 {
367  for ( DHCellAccessor dh_cell : dof_handler_->own_range() ) {
368  IntIdx dof_p0 = dh_cell.get_loc_dof_indices()[0];
369  const ElementAccessor<3> ele = dh_cell.elm();
370 
371  //setting initial solid concentration for substances involved in adsorption
372  for (unsigned int sbi = 0; sbi < n_substances_; sbi++)
373  {
374  int subst_id = substance_global_idx_[sbi];
375  data_->conc_solid_fe[subst_id]->vec()[dof_p0] = data_->init_conc_solid[sbi].value(ele.centre(), ele);
376  }
377  }
378 }
379 
380 
382 {
383  data_->set_time(time_->step(), LimitSide::right); // set to the last computed time
384 
385  // if parameters changed during last time step, reinit isotherms and eventualy
386  // update interpolation tables in the case of constant rock matrix parameters
387  make_tables();
388  clear_max_conc();
389 
390  START_TIMER("Sorption");
391  for ( DHCellAccessor dh_cell : dof_handler_->own_range() )
392  {
393  compute_reaction(dh_cell);
394  }
395  END_TIMER("Sorption");
396 
397  if(reaction_liquid) reaction_liquid->update_solution();
398  if(reaction_solid) reaction_solid->update_solution();
399 }
400 
401 void SorptionBase::isotherm_reinit(unsigned int i_subst, const ElementAccessor<3> &elem)
402 {
403  START_TIMER("SorptionBase::isotherm_reinit");
404 
405  double mult_coef = data_->distribution_coefficient[i_subst].value(elem.centre(),elem);
406  double second_coef = data_->isotherm_other[i_subst].value(elem.centre(),elem);
407 
408  int reg_idx = elem.region().bulk_idx();
409  Isotherm & isotherm = isotherms[reg_idx][i_subst];
410 
411  bool limited_solubility_on = solubility_vec_[i_subst] > 0.0;
412 
413  // in case of no sorbing surface, set isotherm type None
414  if( common_ele_data.no_sorbing_surface_cond <= std::numeric_limits<double>::epsilon())
415  {
416  isotherm.reinit(Isotherm::none, false, solvent_density_,
418  0,0,0);
419  return;
420  }
421 
422  if ( common_ele_data.scale_sorbed <= 0.0)
423  xprintf(UsrErr, "Scaling parameter in sorption is not positive. Check the input for rock density and molar mass of %d. substance.",i_subst);
424 
425  isotherm.reinit(Isotherm::SorptionType(data_->sorption_type[i_subst].value(elem.centre(),elem)),
426  limited_solubility_on, solvent_density_,
428  solubility_vec_[i_subst], mult_coef, second_coef);
429 }
430 
432 {
433  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
434  {
435  isotherm_reinit(i_subst, elem);
436  }
437 }
438 
440 {
441  unsigned int reg_idx, i_subst;
442 
443  // clear max concetrations array
444  unsigned int nr_of_regions = mesh_->region_db().bulk_size();
445  for(reg_idx = 0; reg_idx < nr_of_regions; reg_idx++)
446  for(i_subst = 0; i_subst < n_substances_; i_subst++)
447  max_conc[reg_idx][i_subst] = 0.0;
448 }
449 
451 {
452  unsigned int reg_idx, i_subst, subst_id;
453 
454  clear_max_conc();
455 
456  for ( DHCellAccessor dh_cell : dof_handler_->own_range() ) {
457  IntIdx dof_p0 = dh_cell.get_loc_dof_indices()[0];
458  reg_idx = dh_cell.elm().region().bulk_idx();
459  for(i_subst = 0; i_subst < n_substances_; i_subst++){
460  subst_id = substance_global_idx_[i_subst];
461  max_conc[reg_idx][i_subst] = std::max(max_conc[reg_idx][i_subst], conc_mobile_fe[subst_id]->vec()[dof_p0]);
462  }
463  }
464 }
465 
467 {
468  START_TIMER("SorptionBase::make_tables");
469  try
470  {
471  ElementAccessor<3> elm;
472  for(const Region &reg_iter: this->mesh_->region_db().get_region_set("BULK"))
473  {
474  int reg_idx = reg_iter.bulk_idx();
475  // true if data has been changed and are constant on the region
476  bool call_reinit = data_->changed() && data_->is_constant(reg_iter);
477 
478  if(call_reinit)
479  {
480  ElementAccessor<3> elm(this->mesh_, reg_iter);
481 // DebugOut().fmt("isotherm reinit\n");
483  isotherm_reinit_all(elm);
484  }
485 
486  // find table limit and create interpolation table for every substance
487  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++){
488 
489  // clear interpolation tables, if not spacially constant OR switched off
490  if(! data_->is_constant(reg_iter) || table_limit_[i_subst] == 0.0){
491  isotherms[reg_idx][i_subst].clear_table();
492 // DebugOut().fmt("limit: 0.0 -> clear table\n");
493  continue;
494  }
495 
496  // if true then make_table will be called at the end
497  bool call_make_table = call_reinit;
498  // initialy try to keep the current table limit (it is zero at zero time step)
499  double subst_table_limit = isotherms[reg_idx][i_subst].table_limit();
500 
501  // if automatic, possibly remake tables with doubled range when table maximum was reached
502  if(table_limit_[i_subst] < 0.0)
503  {
504  if(subst_table_limit < max_conc[reg_idx][i_subst])
505  {
506  call_make_table = true;
507  subst_table_limit = 2*max_conc[reg_idx][i_subst];
508 // DebugOut().fmt("limit: max conc\n");
509  }
510  }
511  // if not automatic, set given table limit
512  else
513  {
514  subst_table_limit = table_limit_[i_subst];
515  }
516 
517  if(call_make_table){
518  isotherms[reg_idx][i_subst].make_table(n_interpolation_steps_, subst_table_limit);
519 // DebugOut().fmt("reg: {} i_subst {}: table_limit = {}\n", reg_idx, i_subst, isotherms[reg_idx][i_subst].table_limit());
520  }
521  }
522  }
523  }
524  catch(ExceptionBase const &e)
525  {
526  e << input_record_.ei_address();
527  throw;
528  }
529 }
530 
532 {
533  const ElementAccessor<3> ele = dh_cell.elm();
534  int reg_idx = ele.region().bulk_idx();
535  IntIdx dof_p0 = dh_cell.get_loc_dof_indices()[0];
536  unsigned int i_subst, subst_id;
537  // for checking, that the common element data are computed once at maximum
538  bool is_common_ele_data_valid = false;
539 
540  try{
541  for(i_subst = 0; i_subst < n_substances_; i_subst++)
542  {
543  subst_id = substance_global_idx_[i_subst];
544  Isotherm & isotherm = isotherms[reg_idx][i_subst];
545  if (isotherm.is_precomputed()){
546 // DebugOut().fmt("isotherms precomputed - interpolate, subst[{}]\n", i_subst);
547  isotherm.interpolate(conc_mobile_fe[subst_id]->vec()[dof_p0],
548  data_->conc_solid_fe[subst_id]->vec()[dof_p0]);
549  }
550  else{
551 // DebugOut().fmt("isotherms reinit - compute , subst[{}]\n", i_subst);
552  if(! is_common_ele_data_valid){
554  is_common_ele_data_valid = true;
555  }
556 
557  isotherm_reinit(i_subst, ele);
558  isotherm.compute(conc_mobile_fe[subst_id]->vec()[dof_p0],
559  data_->conc_solid_fe[subst_id]->vec()[dof_p0]);
560  }
561 
562  // update maximal concentration per region (optimization for interpolation)
563  if(table_limit_[i_subst] < 0)
564  max_conc[reg_idx][i_subst] = std::max(max_conc[reg_idx][i_subst],
565  conc_mobile_fe[subst_id]->vec()[dof_p0]);
566  }
567  }
568  catch(ExceptionBase const &e)
569  {
570  e << input_record_.ei_address();
571  throw;
572  }
573 }
574 
575 
576 /**************************************** OUTPUT ***************************************************/
577 
579 {
581  // Register fresh output data
582  data_->output_fields.output(time().step());
583 }
TimeGovernor & time()
Definition: equation.hh:151
void output_type(OutputTime::DiscreteSpace rt)
Definition: field_set.hh:214
std::shared_ptr< ReactionTerm > reaction_solid
Iterator< ValueType > begin() const
MultiField< 3, FieldValue< 3 >::Scalar > conc_solid
Calculated sorbed concentrations, for output only.
RegionSet get_region_set(const std::string &set_name) const
Definition: region.cc:329
void make_reactions()
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
double solvent_density_
ArmaVec< double, N > vec
Definition: armor.hh:861
EI_Address ei_address() const
Definition: accessors.cc:314
void compute(double &c_aqua, double &c_sorbed)
Definition: isotherm.cc:68
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.
unsigned int bulk_size() const
Definition: region.cc:269
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:61
int IntIdx
Definition: index_types.hh:25
void output(TimeStep step)
#define ASSERT_GT(a, b)
Definition of comparative assert macro (Greater Than)
Definition: asserts.hh:312
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
SubstanceList substances_
Names belonging to substances.
void zero_time_step() override
Definition: mesh.h:78
Iterator< Ret > find(const string &key) const
Cell accessor allow iterate over DOF handler cells.
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()
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
void compute_reaction(const DHCellAccessor &dh_cell) override
Compute reaction on a single element.
const RegionDB & region_db() const
Definition: mesh.h:143
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
const TimeStep & step(int index=-1) const
std::vector< double > table_limit_
Class for declaration of the integral input data.
Definition: type_base.hh:490
static Input::Type::Abstract & it_abstract_reaction()
void reinit(enum SorptionType sorption_type, bool limited_solubility_on, double aqua_density, double scale_aqua, double scale_sorbed, double c_aqua_limit, double mult_coef, double second_coef)
Definition: isotherm.cc:44
unsigned int size() const
Definition: substance.hh:87
Class for declaration of inputs sequences.
Definition: type_base.hh:346
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.
void isotherm_reinit(unsigned int i_subst, const ElementAccessor< 3 > &elm)
Reinitializes the isotherm.
Class Dual_por_exchange implements the model of dual porosity.
IteratorBase end() const
arma::vec::fixed< spacedim > centre() const
Computes the barycenter.
EI_Address ei_address() const
Definition: accessors.cc:178
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
void setup_components()
MultiField< 3, FieldValue< 3 >::Scalar > isotherm_other
Langmuir sorption coeficients alpha (in fraction c_s = omega * (alpha*c_a)/(1- alpha*c_a)).
FieldFEScalarVec conc_solid_fe
Underlaying FieldFE for each substance of conc_solid.
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:541
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
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_
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
unsigned int n_interpolation_steps_
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:93
void make_tables(void)
#define START_TIMER(tag)
Starts a timer with specified tag.
Mesh * mesh_
Definition: equation.hh:220
Selection & add_value(const int value, const std::string &key, const std::string &description="", TypeBase::attribute_map attributes=TypeBase::attribute_map())
Adds one new value with name given by key to the Selection.
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:503
void update_max_conc()
Computes maximal aqueous concentration at the current step.
virtual void compute_common_ele_data(const ElementAccessor< 3 > &elem)=0
MultiField< 3, FieldValue< 3 >::Enum > sorption_type
Discrete need Selection for initialization.
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:459
Region region() const
Definition: accessors.hh:165
SorptionType
Type of adsorption isotherm.
Definition: isotherm.hh:174
Definition: system.hh:65
Support classes for parallel programing.
void set_input_list(Input::Array input_list, const TimeGovernor &tg)
Definition: field_set.hh:193
Class SorptionBase is abstract class representing model of sorption in transport. ...
void interpolate(double &c_aqua, double &c_sorbed)
Definition: isotherm.cc:84
void initialize(std::shared_ptr< OutputTime > stream, Mesh *mesh, Input::Record in_rec, const TimeGovernor &tg)
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
const Selection & close() const
Close the Selection, no more values can be added.
Input::Record input_record_
Definition: equation.hh:222
void set_components(const std::vector< string > &names)
Definition: field_set.hh:180
void set_initial_condition()
Reads and sets initial condition for concentration in solid.
EqData(const string &output_field_name, const string &output_field_desc)
Collect all fields.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:296
FieldFEScalarVec conc_mobile_fe
FieldFEs representing P0 interpolation of mobile concentration (passed from transport).
bool set_time(const TimeStep &time, LimitSide limit_side)
Definition: field_set.cc:157
std::shared_ptr< DOFHandlerMultiDim > dof_handler_
Pointer to DOF handler used through the reaction tree.
bool is_constant(Region reg) const
Definition: field_set.cc:173
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Definition: region.hh:91
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:258
#define END_TIMER(tag)
Ends a timer with specified tag.
void clear_max_conc()
Sets max conc to zeros on all regins.
bool is_precomputed(void)
Definition: isotherm.hh:239
void set_mesh(const Mesh &mesh)
Definition: field_set.hh:186
void set_components(const std::vector< string > &names)
Record type proxy class.
Definition: type_record.hh:182
static const Input::Type::Record & get_input_type()
void isotherm_reinit_all(const ElementAccessor< 3 > &elm)
Calls isotherm_reinit for all isotherms.
Base of exceptions used in Flow123d.
Definition: exceptions.hh:75
MultiField< 3, FieldValue< 3 >::Scalar > distribution_coefficient
Multiplication coefficients (k, omega) for all types of isotherms.
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:55
static bool print_message_table(ostream &stream, std::string equation_name)
Definition: field_common.cc:96
std::vector< std::vector< double > > max_conc
Other possible transformation of coordinates:
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
bool changed() const
Definition: field_set.cc:165
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:62
struct SorptionBase::CommonElementData common_ele_data
TimeGovernor * time_
Definition: equation.hh:221
FieldSet input_data_set_
Input data set - fields in this set are read from the input file.
std::shared_ptr< ReactionTerm > reaction_liquid
void initialize() override
Prepares the object to usage.