Flow123d  jenkins-Flow123d-linux-release-multijob-282
sorption.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <limits>
3 
4 #include "reaction/isotherm.hh"
5 #include "reaction/sorption.hh"
6 #include "system/sys_profiler.hh"
7 #include "mesh/accessors.hh"
8 
9 /********************************* *********************************************************/
10 /********************************* SORPTION_SIMPLE *********************************************************/
11 /********************************* *********************************************************/
12 
14 
16  : SorptionBase(init_mesh, in_rec)
17 {
18  data_ = new EqData("conc_solid");
19  this->eq_data_ = data_;
20  output_selection = make_output_selection("conc_solid", "SorptionSimple_Output");
21 }
22 
24 {}
25 
27 {
28  START_TIMER("SorptionSimple::isotherm_reinit");
29 
30  double rock_density = data_->rock_density.value(elem.centre(),elem);
31  double por_m = data_->porosity.value(elem.centre(),elem);
32 
33  // List of types of isotherms in particular regions
34  arma::uvec adsorption_type = data_->sorption_type.value(elem.centre(),elem);
35  arma::Col<double> mult_coef_vec = data_->isotherm_mult.value(elem.centre(),elem);
36  arma::Col<double> second_coef_vec = data_->isotherm_other.value(elem.centre(),elem);
37 
38  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
39  {
40  double mult_coef = mult_coef_vec[i_subst];
41  double second_coef = second_coef_vec[i_subst];
42  Isotherm & isotherm = isotherms_vec[i_subst];
43 
44  //scales are different for the case of sorption in mobile and immobile pores
45  double scale_aqua = por_m,
46  scale_sorbed = (1 - por_m) * rock_density * substances_[substance_global_idx_[i_subst]].molar_mass();
47 
48  bool limited_solubility_on = false;
49  double table_limit;
50  if (solubility_vec_[i_subst] <= 0.0) {
51  limited_solubility_on = false;
52  table_limit=table_limit_[i_subst];
53  } else {
54  limited_solubility_on = true;
55  table_limit=solubility_vec_[i_subst];
56  }
57 
58  if( (1-por_m) <= std::numeric_limits<double>::epsilon()) //means there is no sorbing surface
59  {
60  isotherm.reinit(Isotherm::none, false, solvent_density_, scale_aqua, scale_sorbed,table_limit,0,0);
61  continue;
62  }
63 
64  if ( scale_sorbed <= 0.0)
65  xprintf(UsrErr, "Scaling parameter in sorption is not positive. Check the input for rock density and molar mass of %d. substance.",i_subst);
66 
67  isotherm.reinit(Isotherm::SorptionType(adsorption_type[i_subst]), limited_solubility_on,
68  solvent_density_, scale_aqua, scale_sorbed, table_limit, mult_coef, second_coef);
69 
70  }
71 
72  END_TIMER("SorptionSimple::isotherm_reinit");
73 }
74 
75 
76 /*********************************** *********************************************************/
77 /*********************************** SORPTION_DUAL *********************************************************/
78 /*********************************** *********************************************************/
79 
81  const string &output_conc_name,
82  const string &output_selection_name)
83  : SorptionBase(init_mesh, in_rec)
84 {
85  data_ = new EqData(output_conc_name);
88  .name("porosity_immobile");
89  this->eq_data_ = data_;
90  output_selection = make_output_selection(output_conc_name, output_selection_name);
91 }
92 
94 {}
95 
96 /********************************** *******************************************************/
97 /*********************************** SORPTION_MOBILE *******************************************************/
98 /********************************** *******************************************************/
99 
101 
103  : SorptionDual(init_mesh, in_rec, "conc_solid", "SorptionMobile_Output")
104 {}
105 
106 
108 {}
109 
110 /*
111 double SorptionMob::compute_sorbing_scale(double por_m, double por_imm)
112 {
113  double phi = por_m/(por_m + por_imm);
114  return phi;
115 }
116 */
117 
119 {
120  START_TIMER("SorptionMob::isotherm_reinit");
121 
122  double rock_density = data_->rock_density.value(elem.centre(),elem);
123 
124  double por_m = data_->porosity.value(elem.centre(),elem);
125  double por_imm = immob_porosity_.value(elem.centre(),elem);
126  double phi = por_m/(por_m + por_imm);
127 
128  // List of types of isotherms in particular regions
129  arma::uvec adsorption_type = data_->sorption_type.value(elem.centre(),elem);
130  arma::Col<double> mult_coef_vec = data_->isotherm_mult.value(elem.centre(),elem);
131  arma::Col<double> second_coef_vec = data_->isotherm_other.value(elem.centre(),elem);
132 
133  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
134  {
135  double mult_coef = mult_coef_vec[i_subst];
136  double second_coef = second_coef_vec[i_subst];
137  Isotherm & isotherm = isotherms_vec[i_subst];
138 
139  //scales are different for the case of sorption in mobile and immobile pores
140  double scale_aqua = por_m,
141  scale_sorbed = phi * (1 - por_m - por_imm) * rock_density * substances_[substance_global_idx_[i_subst]].molar_mass();
142 
143  bool limited_solubility_on;
144  double table_limit;
145  if (solubility_vec_[i_subst] <= 0.0) {
146  limited_solubility_on = false;
147  table_limit=table_limit_[i_subst];
148 
149  } else {
150  limited_solubility_on = true;
151  table_limit=solubility_vec_[i_subst];
152  }
153 
154  if( (1-por_m-por_imm) <= std::numeric_limits<double>::epsilon()) //means there is no sorbing surface
155  {
156  isotherm.reinit(Isotherm::none, false, solvent_density_, scale_aqua, scale_sorbed,table_limit,0,0);
157  continue;
158  }
159 
160  if ( scale_sorbed <= 0.0)
161  xprintf(UsrErr, "Scaling parameter in sorption is not positive. Check the input for rock density and molar mass of %d. substance.",i_subst);
162 
163  isotherm.reinit(Isotherm::SorptionType(adsorption_type[i_subst]), limited_solubility_on,
164  solvent_density_, scale_aqua, scale_sorbed, table_limit, mult_coef, second_coef);
165 
166  }
167 
168  END_TIMER("SorptionMob::isotherm_reinit");
169 }
170 
171 
172 /*********************************** *****************************************************/
173 /*********************************** SORPTION_IMMOBILE *****************************************************/
174 /*********************************** *****************************************************/
175 
177 
179 : SorptionDual(init_mesh, in_rec, "conc_immobile_solid", "SorptionImmobile_Output")
180 {}
181 
183 {}
184 
185 /*
186 double SorptionImmob::compute_sorbing_scale(double por_m, double por_imm)
187 {
188  double phi = por_imm / (por_m + por_imm);
189  return phi;
190 }
191 */
192 
194 {
195  START_TIMER("SorptionImmob::isotherm_reinit");
196 
197  double rock_density = data_->rock_density.value(elem.centre(),elem);
198 
199  double por_m = data_->porosity.value(elem.centre(),elem);
200  double por_imm = immob_porosity_.value(elem.centre(),elem);
201  double phi = por_m/(por_m + por_imm);
202 
203  // List of types of isotherms in particular regions
204  arma::uvec adsorption_type = data_->sorption_type.value(elem.centre(),elem);
205  arma::Col<double> mult_coef_vec = data_->isotherm_mult.value(elem.centre(),elem);
206  arma::Col<double> second_coef_vec = data_->isotherm_other.value(elem.centre(),elem);
207 
208  for(unsigned int i_subst = 0; i_subst < n_substances_; i_subst++)
209  {
210  double mult_coef = mult_coef_vec[i_subst];
211  double second_coef = second_coef_vec[i_subst];
212  Isotherm & isotherm = isotherms_vec[i_subst];
213 
214  //scales are different for the case of sorption in mobile and immobile pores
215  double scale_aqua = por_imm,
216  scale_sorbed = (1 - phi) * (1 - por_m - por_imm) * rock_density * substances_[substance_global_idx_[i_subst]].molar_mass();
217 
218  bool limited_solubility_on;
219  double table_limit;
220  if (solubility_vec_[i_subst] <= 0.0) {
221  limited_solubility_on = false;
222  table_limit=table_limit_[i_subst];
223 
224  } else {
225  limited_solubility_on = true;
226  table_limit=solubility_vec_[i_subst];
227  }
228 
229  if( (1-por_m-por_imm) <= std::numeric_limits<double>::epsilon()) //means there is no sorbing surface
230  {
231  isotherm.reinit(Isotherm::none, false, solvent_density_, scale_aqua, scale_sorbed,0,0,0);
232  continue;
233  }
234 
235  if ( scale_sorbed <= 0.0)
236  xprintf(UsrErr, "Scaling parameter in sorption is not positive. Check the input for rock density and molar mass of %d. substance.",i_subst);
237 
238  isotherm.reinit(Isotherm::SorptionType(adsorption_type[i_subst]), limited_solubility_on,
239  solvent_density_, scale_aqua, scale_sorbed, table_limit, mult_coef, second_coef);
240 
241  }
242 
243  END_TIMER("SorptionImmob::isotherm_reinit");
244 }
static Input::Type::Record input_type
Definition: sorption.hh:77
FieldSet * eq_data_
Definition: equation.hh:227
double solvent_density_
~SorptionDual(void)
Destructor.
Definition: sorption.cc:93
Field< 3, FieldValue< 3 >::EnumVector > sorption_type
Discrete need Selection for initialization.
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
Field< 3, FieldValue< 3 >::Vector > isotherm_other
Langmuir sorption coeficients alpha (in fraction c_s = omega * (alpha*c_a)/(1- alpha*c_a)).
Input::Type::Selection output_selection
~SorptionMob(void)
Destructor.
Definition: sorption.cc:107
Abstract class of sorption model in case dual porosity is considered.
Definition: sorption.hh:44
SubstanceList substances_
Names belonging to substances.
static Input::Type::Record input_type
Definition: sorption.hh:99
Field< 3, FieldValue< 3 >::Scalar > rock_density
Rock matrix density.
void isotherm_reinit(std::vector< Isotherm > &isotherms_vec, const ElementAccessor< 3 > &elem) override
Reinitializes the isotherm.
Definition: sorption.cc:118
Definition: mesh.h:109
std::vector< double > table_limit_
Field< 3, FieldValue< 3 >::Vector > isotherm_mult
Multiplication coefficients (k, omega) for all types of isotherms.
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.hh:326
std::vector< unsigned int > substance_global_idx_
Mapping from local indexing of substances to global.
Field< 3, FieldValue< 3 >::Scalar > porosity
Porosity field copied from transport.
Field< 3, FieldValue< 3 >::Scalar > immob_porosity_
Definition: sorption.hh:65
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:29
std::vector< double > solubility_vec_
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
#define xprintf(...)
Definition: system.hh:100
#define START_TIMER(tag)
Starts a timer with specified tag.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:312
static Input::Type::Record record_factory(SorptionRecord::Type)
Creates the input record for different cases of sorption model (simple or in dual porosity)...
static Input::Type::Selection make_output_selection(const string &output_field_name, const string &selection_name)
SorptionType
Type of adsorption isotherm.
Definition: isotherm.hh:162
Definition: system.hh:72
const double epsilon
Definition: mathfce.h:6
SorptionImmob(Mesh &init_mesh, Input::Record in_rec)
Constructor.
Definition: sorption.cc:178
static Input::Type::Record input_type
Definition: sorption.hh:27
void isotherm_reinit(std::vector< Isotherm > &isotherms, const ElementAccessor< 3 > &elm) override
Reinitializes the isotherm.
Definition: sorption.cc:26
SorptionSimple(Mesh &init_mesh, Input::Record in_rec)
Constructor.
Definition: sorption.cc:15
~SorptionSimple(void)
Destructor.
Definition: sorption.cc:23
FieldCommon & name(const string &name)
Definition: field_common.hh:73
#define END_TIMER(tag)
Ends a timer with specified tag.
arma::vec::fixed< spacedim > centre() const
Definition: accessors.hh:81
Record type proxy class.
Definition: type_record.hh:169
unsigned int n_substances_
SorptionDual(Mesh &init_mesh, Input::Record in_rec, const string &output_conc_name, const string &output_selection_name)
Constructor.
Definition: sorption.cc:80
EqData * data_
Pointer to equation data. The object is constructed in descendants.
void isotherm_reinit(std::vector< Isotherm > &isotherms_vec, const ElementAccessor< 3 > &elem) override
Reinitializes the isotherm.
Definition: sorption.cc:193
SorptionMob(Mesh &init_mesh, Input::Record in_rec)
Constructor.
Definition: sorption.cc:102
~SorptionImmob(void)
Destructor.
Definition: sorption.cc:182