Flow123d  jenkins-Flow123d-windows32-release-multijob-51
sorption_base.cc
Go to the documentation of this file.
1 #include <boost/foreach.hpp>
2 
3 #include "reaction/reaction.hh"
8 #include "reaction/isotherm.hh"
10 
11 #include "system/system.hh"
12 #include "system/sys_profiler.hh"
13 
14 #include "la/distribution.hh"
15 #include "mesh/mesh.h"
16 #include "mesh/elements.h"
17 #include "input/type_selection.hh"
18 
19 #include "fields/field_set.hh"
21 
22 
23 using namespace std;
24 using namespace Input::Type;
25 
27  .add_value(Isotherm::none,"none", "No adsorption considered.")
28  .add_value(Isotherm::linear, "linear",
29  "Linear isotherm runs the concentration exchange between liquid and solid.")
30  .add_value(Isotherm::langmuir, "langmuir",
31  "Langmuir isotherm runs the concentration exchange between liquid and solid.")
32  .add_value(Isotherm::freundlich, "freundlich",
33  "Freundlich isotherm runs the concentration exchange between liquid and solid.");
34 
35 
36 
38  = Record("Adsorption", "AUXILIARY RECORD. Should not be directly part of the input tree.")
39  .declare_key("substances", Array(String()), Default::obligatory(),
40  "Names of the substances that take part in the adsorption model.")
41  .declare_key("solvent_density", Double(), Default("1.0"),
42  "Density of the solvent.")
43  .declare_key("substeps", Integer(), Default("1000"),
44  "Number of equidistant substeps, molar mass and isotherm intersections")
45  .declare_key("molar_mass", Array(Double()), Default::obligatory(),
46  "Specifies molar masses of all the adsorbing species.")
47  .declare_key("solubility", Array(Double(0.0)), Default::optional(), //("-1.0"), //
48  "Specifies solubility limits of all the adsorbing species.")
49  .declare_key("table_limits", Array(Double(0.0)), Default::optional(), //("-1.0"), //
50  "Specifies highest aqueous concentration in interpolation table.")
51  .declare_key("input_fields", Array(EqData("").input_data_set_.make_field_descriptor_type("Sorption")), Default::obligatory(), //
52  "Containes region specific data necessary to construct isotherms.")//;
53  .declare_key("reaction_liquid", ReactionTerm::input_type, Default::optional(), "Reaction model following the sorption in the liquid.")
54  .declare_key("reaction_solid", ReactionTerm::input_type, Default::optional(), "Reaction model following the sorption in the solid.");
55 
56 
57 SorptionBase::EqData::EqData(const string &output_field_name)
58 {
59  ADD_FIELD(rock_density, "Rock matrix density.", "0.0");
60  rock_density.units( UnitSI().kg().m(-3) );
61 
62  ADD_FIELD(sorption_type,"Considered adsorption is described by selected isotherm."); //
63  sorption_type.input_selection(&sorption_type_selection);
64  sorption_type.units( UnitSI::dimensionless() );
65 
66  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");
67  isotherm_mult.units( UnitSI().mol().kg(-1) );
68 
69  ADD_FIELD(isotherm_other,"Second parameters (alpha, ...) defining isotherm c_s = omega * (alpha*c_a)/(1- alpha*c_a).","1.0");
70  isotherm_other.units( UnitSI::dimensionless() );
71 
72  ADD_FIELD(init_conc_solid, "Initial solid concentration of substances."
73  " Vector, one value for every substance.", "0");
74  init_conc_solid.units( UnitSI().mol().kg(-1) );
75 
76  input_data_set_ += *this;
77 
78  // porosity field is set from governing equation (transport) later
79  // hence we do not add it to the input_data_set_
80  *this += porosity
81  .name("porosity")
82  .units( UnitSI::dimensionless() )
83  .flags(FieldFlag::input_copy);
84 
85  output_fields += *this;
86  output_fields += conc_solid.name(output_field_name).units( UnitSI().kg().m(-3) );
87 }
88 
90 {
91  IT::Record rec;
92  switch(fact)
93  {
94  case SorptionRecord::mobile:
95  rec = IT::Record("SorptionMobile", "Adsorption model in the mobile zone, following the dual porosity model.")
98  .declare_key("output_fields", IT::Array(make_output_selection("conc_solid", "SorptionMobile_Output")),
99  IT::Default("conc_solid"), "List of fields to write to output stream.");
100  break;
101  case SorptionRecord::immobile:
102  rec = IT::Record("SorptionImmobile", "Adsorption model in the immobile zone, following the dual porosity model.")
105  .declare_key("output_fields", IT::Array(make_output_selection("conc_immobile_solid", "SorptionImmobile_Output")),
106  IT::Default("conc_immobile_solid"), "List of fields to write to output stream.");
107  break;
108 
109  default:
110  rec = IT::Record("Sorption", "Adsorption model in the reaction term of transport.")
113  .declare_key("output_fields", IT::Array(make_output_selection("conc_solid", "Sorption_Output")),
114  IT::Default("conc_solid"), "List of fields to write to output stream.");
115  break;
116  }
117  return rec;
118 }
119 
120 
122  : ReactionTerm(init_mesh, in_rec),
123  data_(nullptr)
124 {
125  // creating reaction from input and setting their parameters
126  make_reactions();
127 }
128 
129 
131 {
132  if(reaction_liquid != nullptr) delete reaction_liquid;
133  if(reaction_solid != nullptr) delete reaction_solid;
134  if (data_ != nullptr) delete data_;
135 
136  VecScatterDestroy(&(vconc_out_scatter));
137  VecDestroy(vconc_solid);
138  VecDestroy(vconc_solid_out);
139 
140  for (unsigned int sbi = 0; sbi < names_.size(); sbi++)
141  {
142  //no mpi vectors
143  xfree(conc_solid[sbi]);
144  xfree(conc_solid_out[sbi]);
145  }
146  xfree(conc_solid);
148 }
149 
151 {
153 
154  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_liquid");
155  if ( reactions_it )
156  {
157  if (reactions_it->type() == LinearReaction::input_type ) {
158  reaction_liquid = new LinearReaction(*mesh_, *reactions_it);
159  } else
160  if (reactions_it->type() == PadeApproximant::input_type) {
161  reaction_liquid = new PadeApproximant(*mesh_, *reactions_it);
162  } else
163  if (reactions_it->type() == SorptionBase::input_type ) {
164  xprintf(UsrErr, "Sorption model cannot have another descendant sorption model.\n");
165  } else
166  if (reactions_it->type() == DualPorosity::input_type ) {
167  xprintf(UsrErr, "Sorption model cannot have descendant dual porosity model.\n");
168  } else
169  if (reactions_it->type() == Semchem_interface::input_type )
170  {
171  xprintf(UsrErr, "Semchem chemistry model is not supported at current time.\n");
172  } else
173  {
174  xprintf(UsrErr, "Unknown reactions type in Sorption model.\n");
175  }
176  } else
177  {
178  reaction_liquid = nullptr;
179  }
180 
181  reactions_it = input_record_.find<Input::AbstractRecord>("reaction_solid");
182  if ( reactions_it )
183  {
184  if (reactions_it->type() == LinearReaction::input_type ) {
185  reaction_solid = new LinearReaction(*mesh_, *reactions_it);
186  } else
187  if (reactions_it->type() == PadeApproximant::input_type) {
188  reaction_solid = new PadeApproximant(*mesh_, *reactions_it);
189  } else
190  if (reactions_it->type() == SorptionBase::input_type ) {
191  xprintf(UsrErr, "Sorption model cannot have another descendant sorption model.\n");
192  } else
193  if (reactions_it->type() == DualPorosity::input_type ) {
194  xprintf(UsrErr, "Sorption model cannot have descendant dual porosity model.\n");
195  } else
196  if (reactions_it->type() == Semchem_interface::input_type )
197  {
198  xprintf(UsrErr, "Semchem chemistry model is not supported at current time.\n");
199  } else
200  {
201  xprintf(UsrErr, "Unknown reactions type in Sorption model.\n");
202  }
203  } else
204  {
205  reaction_solid = nullptr;
206  }
207 }
208 
210 {
211  ASSERT(distribution_ != nullptr, "Distribution has not been set yet.\n");
212  ASSERT(time_ != nullptr, "Time governor has not been set yet.\n");
213  ASSERT(output_stream_,"Null output stream.");
214  ASSERT_LESS(0, names_.size());
215 
216  initialize_substance_ids(); //computes present substances and sets indices
217  initialize_from_input(); //reads non-field data from input
218 
219  //isotherms array resized bellow
220  unsigned int nr_of_regions = mesh_->region_db().bulk_size();
221  isotherms.resize(nr_of_regions);
222  for(unsigned int i_reg = 0; i_reg < nr_of_regions; i_reg++)
223  {
224  isotherms[i_reg].resize(n_substances_);
225  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
226  {
227  isotherms[i_reg][i_subst] = Isotherm();
228  }
229  }
230 
231  //allocating new array for sorbed concentrations
232  conc_solid = (double**) xmalloc(names_.size() * sizeof(double*));//new double * [n_substances_];
233  conc_solid_out = (double**) xmalloc(names_.size() * sizeof(double*));
234  for (unsigned int sbi = 0; sbi < names_.size(); sbi++)
235  {
236  conc_solid[sbi] = (double*) xmalloc(distribution_->lsize() * sizeof(double));//new double[ nr_of_local_elm ];
237  conc_solid_out[sbi] = (double*) xmalloc(distribution_->size() * sizeof(double));
238  //zero initialization of solid concentration for all substances
239  for(unsigned int i=0; i < distribution_->lsize(); i++)
240  conc_solid[sbi][i] = 0;
241  }
242 
244 
246 
247  if(reaction_liquid != nullptr)
248  {
253  }
254  if(reaction_solid != nullptr)
255  {
260  }
261 }
262 
263 
265 {
266  Input::Array substances_array = input_record_.val<Input::Array>("substances");
267  unsigned int k, global_idx, i_subst = 0;
268  bool found;
269  Input::Iterator<string> spec_iter = substances_array.begin<string>();
270 
271  for(; spec_iter != substances_array.end(); ++spec_iter, i_subst++)
272  {
273  //finding the name of a substance in the global array of names
274  found = false;
275  for(k = 0; k < names_.size(); k++)
276  {
277  if (*spec_iter == names_[k])
278  {
279  global_idx = k;
280  found = true;
281  break;
282  }
283  }
284 
285  if(!found)
286  xprintf(UsrErr,"Wrong name of %d-th substance - not found in global set of transported substances.\n",
287  i_subst);
288 
289  //finding the global index of substance in the local array
290  found = false;
291  for(k = 0; k < substance_global_idx_.size(); k++)
292  {
293  if(substance_global_idx_[k] == global_idx)
294  {
295  found = true;
296  break;
297  }
298  }
299 
300  if(!found)
301  substance_global_idx_.push_back(global_idx);
302 
303  }
305 }
306 
308 {
309  n_interpolation_steps_ = input_record_.val<int>("substeps");
310  if(n_interpolation_steps_ < 1)
311  xprintf(UsrErr,"Number of 'substeps'=%d in isotherm interpolation table must be be >0.\n",
313 
314  // Common data for all the isotherms loaded bellow
315  solvent_density_ = input_record_.val<double>("solvent_density");
316 
317  molar_masses_.resize( n_substances_ );
318 
319  Input::Array molar_mass_array = input_record_.val<Input::Array>("molar_mass");
320 
321  if (molar_mass_array.size() == molar_masses_.size() ) molar_mass_array.copy_to( molar_masses_ );
322  else xprintf(UsrErr,"Number of molar masses %d has to match number of adsorbing species %d.\n",
323  molar_mass_array.size(), molar_masses_.size());
324 
325  Input::Iterator<Input::Array> solub_iter = input_record_.find<Input::Array>("solubility");
326  if( solub_iter )
327  {
328  solub_iter->copy_to(solubility_vec_);
329  if (solubility_vec_.size() != n_substances_)
330  {
331  xprintf(UsrErr,"Number of given solubility limits %d has to match number of adsorbing species %d.\n",
333  }
334  }else{
335  // fill solubility_vec_ with zeros or resize it at least
337  }
338 
339  Input::Iterator<Input::Array> interp_table_limits = input_record_.find<Input::Array>("table_limits");
340  if( interp_table_limits )
341  {
342  interp_table_limits->copy_to(table_limit_);
343  if (table_limit_.size() != n_substances_)
344  {
345  xprintf(UsrErr,"Number of given table limits %d has to match number of adsorbing species %d.\n",
346  table_limit_.size(), n_substances_);
347  }
348  }else{
349  // fill table_limit_ with zeros or resize it at least
350  table_limit_.resize(n_substances_);
351  }
352 }
353 
355 {
356  ASSERT(n_substances_ > 0, "Number of substances is wrong, they might have not been set yet.\n");
358 
359 
360  // read fields from input file
362 
363  data_->set_mesh(*mesh_);
365 
366  //initialization of output
367  output_array = input_record_.val<Input::Array>("output_fields");
368  //initialization of output
372  for (unsigned int sbi=0; sbi<names_.size(); sbi++)
373  {
374  // create shared pointer to a FieldElementwise and push this Field to output_field on all regions
375  std::shared_ptr<FieldElementwise<3, FieldValue<3>::Scalar> > output_field_ptr(
377  data_->conc_solid[sbi].set_field(mesh_->region_db().get_region_set("ALL"), output_field_ptr, 0);
378  }
381 }
382 
383 
385 {
386  ASSERT(distribution_ != nullptr, "Distribution has not been set yet.\n");
387  ASSERT(time_ != nullptr, "Time governor has not been set yet.\n");
388  ASSERT(output_stream_,"Null output stream.");
389  ASSERT_LESS(0, names_.size());
390 
391  data_->set_time(*time_);
393  make_tables();
394 
395  // write initial condition
399 
401  if(reaction_solid != nullptr) reaction_solid->zero_time_step();
402 }
403 
405 {
406  for (unsigned int loc_el = 0; loc_el < distribution_->lsize(); loc_el++)
407  {
408  unsigned int index = el_4_loc_[loc_el];
409  ElementAccessor<3> ele_acc = mesh_->element_accessor(index);
410  arma::vec value = data_->init_conc_solid.value(ele_acc.centre(),
411  ele_acc);
412 
413  //setting initial solid concentration for substances involved in adsorption
414  for (unsigned int sbi = 0; sbi < n_substances_; sbi++)
415  {
416  int subst_id = substance_global_idx_[sbi];
417  conc_solid[subst_id][loc_el] = value(sbi);
418  }
419  }
420 }
421 
422 
424 {
425  data_->set_time(*time_); // set to the last computed time
426 
427  // if parameters changed during last time step, reinit isotherms and eventualy
428  // update interpolation tables in the case of constant rock matrix parameters
429  if(data_->changed())
430  make_tables();
431 
432 
433  START_TIMER("Sorption");
434  for (unsigned int loc_el = 0; loc_el < distribution_->lsize(); loc_el++)
435  {
437  }
438  END_TIMER("Sorption");
439 
442 }
443 
445 {
446  ElementAccessor<3> elm;
447  BOOST_FOREACH(const Region &reg_iter, this->mesh_->region_db().get_region_set("BULK") )
448  {
449  int reg_idx = reg_iter.bulk_idx();
450 
451  if(data_->is_constant(reg_iter))
452  {
453  ElementAccessor<3> elm(this->mesh_, reg_iter); // constant element accessor
454  isotherm_reinit(isotherms[reg_idx],elm);
455  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
456  {
457  isotherms[reg_idx][i_subst].make_table(n_interpolation_steps_);
458  }
459  }
460  }
461 }
462 
463 double **SorptionBase::compute_reaction(double **concentrations, int loc_el)
464 {
465  ElementFullIter elem = mesh_->element(el_4_loc_[loc_el]);
466  int reg_idx = elem->region().bulk_idx();
467  unsigned int i_subst, subst_id;
468 
469  std::vector<Isotherm> & isotherms_vec = isotherms[reg_idx];
470 
471  // Constant value of rock density and mobile porosity over the whole region
472  // => interpolation_table is precomputed
473  if (isotherms_vec[0].is_precomputed())
474  {
475  for(i_subst = 0; i_subst < n_substances_; i_subst++)
476  {
477  subst_id = substance_global_idx_[i_subst];
478 
479  isotherms_vec[i_subst].interpolate(concentration_matrix_[subst_id][loc_el],
480  conc_solid[subst_id][loc_el]);
481  }
482  }
483  else
484  {
485  isotherm_reinit(isotherms_vec, elem->element_accessor());
486 
487  for(i_subst = 0; i_subst < n_substances_; i_subst++)
488  {
489  subst_id = substance_global_idx_[i_subst];
490  isotherms_vec[i_subst].compute(concentration_matrix_[subst_id][loc_el],
491  conc_solid[subst_id][loc_el]);
492  }
493  }
494 
495  return concentrations;
496 }
497 
498 
499 /**************************************** OUTPUT ***************************************************/
500 
502 {
503  int sbi, n_subst;
504  n_subst = names_.size();
505 
506  vconc_solid = (Vec*) xmalloc(n_subst * (sizeof(Vec)));
507  vconc_solid_out = (Vec*) xmalloc(n_subst * (sizeof(Vec))); // extend to all
508 
509  for (sbi = 0; sbi < n_subst; sbi++) {
510  VecCreateMPIWithArray(PETSC_COMM_WORLD,1, distribution_->lsize(), mesh_->n_elements(), conc_solid[sbi],
511  &vconc_solid[sbi]);
512  VecZeroEntries(vconc_solid[sbi]);
513 
514  VecCreateSeqWithArray(PETSC_COMM_SELF,1, mesh_->n_elements(), conc_solid_out[sbi], &vconc_solid_out[sbi]);
515  VecZeroEntries(vconc_solid_out[sbi]);
516  }
517 
518  // creating output vector scatter
519  IS is;
520  ISCreateGeneral(PETSC_COMM_SELF, mesh_->n_elements(), row_4_el_, PETSC_COPY_VALUES, &is); //WithArray
521  VecScatterCreate(vconc_solid[0], is, vconc_solid_out[0], PETSC_NULL, &vconc_out_scatter);
522  ISDestroy(&(is));
523 }
524 
525 
527 {
528  unsigned int sbi;
529 
530  for (sbi = 0; sbi < names_.size(); sbi++) {
531  VecScatterBegin(vconc_out_scatter, vconc_solid[sbi], vconc_solid_out[sbi], INSERT_VALUES, SCATTER_FORWARD);
532  VecScatterEnd(vconc_out_scatter, vconc_solid[sbi], vconc_solid_out[sbi], INSERT_VALUES, SCATTER_FORWARD);
533  }
534 }
535 
536 
538 {
540 
541  int rank;
542  MPI_Comm_rank(PETSC_COMM_WORLD, &rank);
543  if (rank == 0)
544  {
545  // Register fresh output data
548  }
549 
550  //for synchronization when measuring time by Profiler
552 }
void output_type(OutputTime::DiscreteSpace rt)
Definition: field_set.hh:194
unsigned int size() const
get global size
void set_input_list(Input::Array input_list)
Definition: field_set.hh:164
Iterator< ValueType > begin() const
virtual void zero_time_step()
Definition: equation.hh:97
void allocate_output_mpi(void)
Allocates petsc vectors, prepares them for output and creates vector scatter.
void set_limit_side(LimitSide side)
Definition: field_set.hh:171
MultiField< 3, FieldValue< 3 >::Scalar > conc_solid
Calculated sorbed concentrations, for output only.
OutputTime * output_stream_
Pointer to a transport output stream.
Definition: reaction.hh:112
void make_reactions()
void init(const vector< string > &names)
Definition: field.impl.hh:473
Accessor to input data conforming to declared Array.
Definition: accessors.hh:521
double solvent_density_
ReactionTerm * reaction_liquid
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_
Definition: reaction.hh:95
unsigned int bulk_size() const
Definition: region.cc:252
virtual void initialize()
Initialize fields.
Definition: equation.hh:114
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:39
EqData(const string &output_field_name)
Collect all fields.
Input::Type::Selection output_selection
Vec * vconc_solid_out
PETSC sorbed concentration vector output (gathered - sequential)
double ** compute_reaction(double **concentrations, int loc_el)
vector< string > names_
Names belonging to substances.
Definition: reaction.hh:109
???
void zero_time_step() override
static Input::Type::Record input_type
RegionSet get_region_set(const string &set_name) const
Definition: region.cc:361
static Input::Type::Record input_type
Definition: mesh.h:108
Iterator< Ret > find(const string &key) const
int * row_4_el_
Indices of rows belonging to elements.
Definition: reaction.hh:100
std::vector< double > molar_masses_
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:169
const RegionDB & region_db() const
Definition: mesh.h:148
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
Definition: mesh.cc:638
static Input::Type::Selection sorption_type_selection
Field< 3, FieldValue< 3 >::Vector > init_conc_solid
Initial sorbed concentrations.
std::vector< double > table_limit_
Class for declaration of the integral input data.
Definition: type_base.hh:341
#define ADD_FIELD(name,...)
Definition: field_set.hh:260
Class for declaration of inputs sequences.
Definition: type_base.hh:230
std::vector< unsigned int > substance_global_idx_
Mapping from local indexing of substances to global.
void initialize_fields()
Initializes field sets.
IteratorBase end() const
static Input::Type::AbstractRecord input_type
Definition: reaction.hh:24
unsigned int n_elements() const
Definition: mesh.h:137
#define ASSERT(...)
Definition: global_defs.h:121
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:376
static Input::Type::Record input_type
Distribution * distribution_
Pointer to reference to distribution of elements between processors.
Definition: reaction.hh:103
void output_data(void) override
Output method.
static constexpr Mask input_copy
A field that is input of its equation and cna not read from input, thus muzt be set by copy...
Definition: field_flag.hh:29
Vec * vconc_solid
PETSC sorbed concentration vector (parallel).
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="")
Accessor to the data with type Type::Record.
Definition: accessors.hh:308
unsigned int n_interpolation_steps_
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:100
void make_tables(void)
#define ASSERT_LESS(a, b)
Definition: global_defs.h:164
#define START_TIMER(tag)
Starts a timer with specified tag.
Mesh * mesh_
Definition: equation.hh:218
virtual void isotherm_reinit(std::vector< Isotherm > &isotherms, const ElementAccessor< 3 > &elm)=0
Reinitializes the isotherm.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:399
ReactionTerm * reaction_solid
static Input::Type::Record input_type
static Input::Type::Record record_factory(SorptionRecord::Type)
Creates the input record for different cases of sorption model (simple or in dual porosity)...
double ** conc_solid_out
sorbed concentration array output (gathered - sequential)
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.
static Input::Type::AbstractRecord input_type
void * xmalloc(size_t size)
Memory allocation with checking.
Definition: system.cc:209
void set_time(const TimeGovernor &time)
Definition: field_set.hh:186
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:423
#define MPI_Comm_rank
Definition: mpi.h:236
virtual void set_time_governor(TimeGovernor &time)
Definition: equation.cc:80
Record & copy_keys(const Record &other)
Definition: type_record.cc:183
Definition: system.hh:72
Support classes for parallel programing.
void set_n_components(unsigned int n_comp)
Definition: field_set.hh:151
void copy_to(Container &out) const
virtual void update_solution()
Definition: equation.hh:105
void output(OutputTime *stream)
Definition: field_set.cc:136
Input::Record input_record_
Definition: equation.hh:220
int * el_4_loc_
Indices of elements belonging to local dofs.
Definition: reaction.hh:98
void add_admissible_field_names(const Input::Array &in_array, const Input::Type::Selection &in_sel)
Registers names of output fields that can be written using this stream.
Definition: output.cc:231
void set_initial_condition()
Reads and sets initial condition for concentration in solid.
bool is_constant(Region reg) const
Definition: field_set.cc:128
ReactionTerm & names(const std::vector< string > &names)
Sets the names of substances considered in transport.
Definition: reaction.hh:46
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Definition: region.hh:80
#define MPI_COMM_WORLD
Definition: mpi.h:123
#define END_TIMER(tag)
Ends a timer with specified tag.
arma::vec::fixed< spacedim > centre() const
Definition: accessors.hh:81
double ** conc_solid
void set_mesh(const Mesh &mesh)
Definition: field_set.hh:157
unsigned int size() const
Record type proxy class.
Definition: type_record.hh:161
VecScatter vconc_out_scatter
Output vector scatter.
unsigned int n_substances_
#define xfree(p)
Definition: system.hh:108
Class for representation SI units of Fields.
Definition: unit_si.hh:31
#define MPI_Barrier(comm)
Definition: mpi.h:531
EqData * data_
Pointer to equation data. The object is constructed in descendants.
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:44
ReactionTerm & concentration_matrix(double **concentration, Distribution *conc_distr, int *el_4_loc, int *row_4_el)
Definition: reaction.hh:57
void set_mesh(const Mesh &mesh) override
Definition: field.impl.hh:520
bool changed() const
Definition: field_set.cc:120
Template for classes storing finite set of named values.
TimeGovernor * time_
Definition: equation.hh:219
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:198
FieldSet input_data_set_
Input data set - fields in this set are read from the input file.
unsigned int lsize(int proc) const
get local size
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:386
void initialize() override
Prepares the object to usage.