Flow123d  JS_before_hm-1710-g489f4168f
concentration_model.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 concentration_model.cc
15  * @brief Discontinuous Galerkin method for equation of transport with dispersion.
16  * @author Jan Stebel
17  */
18 
19 #include "input/input_type.hh"
20 #include "mesh/mesh.h"
21 #include "mesh/accessors.hh"
22 //#include "flow/darcy_flow_mh.hh"
23 
25 #include "concentration_model.hh"
26 #include "tools/unit_si.hh"
27 #include "coupling/balance.hh"
28 #include "fields/field_model.hh"
29 
30 
31 
32 using namespace std;
33 using namespace Input::Type;
34 
35 
36 /*******************************************************************************
37  * Functors of FieldModels
38  */
39 using Sclr = double;
40 using Vect = arma::vec3;
41 using Tens = arma::mat33;
42 
43 // Functor computing velocity norm
45  inline Sclr operator() (Vect vel) {
46  return arma::norm(vel, 2);
47  }
48 };
49 
50 // Functor computing mass matrix coefficients (cross_section * water_content)
52  inline Sclr operator() (Sclr csec, Sclr wcont) {
53  return csec * wcont;
54  }
55 };
56 
57 // Functor computing retardation coefficients:
58 // (1-porosity) * rock_density * sorption_coefficient * rock_density
60  inline Sclr operator() (Sclr csec, Sclr por_m, Sclr rho_s, Sclr sorp_mult) {
61  return (1.-por_m)*rho_s*sorp_mult*csec;
62  }
63 };
64 
65 // Functor computing sources density output (cross_section * sources_density)
67  inline Sclr operator() (Sclr csec, Sclr sdens) {
68  return csec * sdens;
69  }
70 };
71 
72 // Functor computing sources sigma output (cross_section * sources_sigma)
74  inline Sclr operator() (Sclr csec, Sclr ssigma) {
75  return csec * ssigma;
76  }
77 };
78 
79 // Functor computing sources concentration output (sources_conc)
81  inline Sclr operator() (Sclr sconc) {
82  return sconc;
83  }
84 };
85 
86 // Functor computing advection coefficient (velocity)
88  inline Vect operator() (Vect velocity) {
89  return velocity;
90  }
91 };
92 
93 // Functor computing diffusion coefficient (see notes in function)
95  inline Tens operator() (Tens diff_m, Vect velocity, Sclr v_norm, Sclr alphaL, Sclr alphaT, Sclr water_content, Sclr porosity, Sclr c_sec) {
96 
97  // used tortuosity model dues to Millington and Quirk(1961) (should it be with power 10/3 ?)
98  // for an overview of other models see: Chou, Wu, Zeng, Chang (2011)
99  double tortuosity = pow(water_content, 7.0 / 3.0)/ (porosity * porosity);
100 
101  // result
102  Tens K;
103 
104  // Note that the velocity vector is in fact the Darcian flux,
105  // so we need not to multiply vnorm by water_content and cross_section.
106  //K = ((alphaL-alphaT) / vnorm) * K + (alphaT*vnorm + Dm*tortuosity*cross_cut*water_content) * arma::eye(3,3);
107 
108  if (fabs(v_norm) > 0) {
109  /*
110  for (int i=0; i<3; i++)
111  for (int j=0; j<3; j++)
112  K(i,j) = (velocity[i]/vnorm)*(velocity[j]);
113  */
114  K = ((alphaL - alphaT) / v_norm) * arma::kron(velocity.t(), velocity);
115 
116  //arma::mat33 abs_diff_mat = arma::abs(K - kk);
117  //double diff = arma::min( arma::min(abs_diff_mat) );
118  //ASSERT( diff < 1e-12 )(diff)(K)(kk);
119  } else
120  K.zeros();
121 
122  // Note that the velocity vector is in fact the Darcian flux,
123  // so to obtain |v| we have to divide vnorm by porosity and cross_section.
124  K += alphaT*v_norm*arma::eye(3,3) + diff_m*(tortuosity*c_sec*water_content);
125 
126  return K;
127  }
128 };
129 
130 
131 
132 
133 
136 {
137  *this+=bc_type
138  .name("bc_type")
139  .description(
140  "Type of boundary condition.")
142  .input_default("\"inflow\"")
145  *this+=bc_dirichlet_value
146  .name("bc_conc")
147  .units( UnitSI().kg().m(-3) )
148  .description("Dirichlet boundary condition (for each substance).")
149  .input_default("0.0")
150  .flags_add( in_rhs );
151  *this+=bc_flux
153  .name("bc_flux")
154  .description("Flux in Neumann boundary condition.")
155  .units( UnitSI().kg().m().s(-1).md() )
156  .input_default("0.0")
157  .flags_add(FieldFlag::in_rhs);
158  *this+=bc_robin_sigma
160  .name("bc_robin_sigma")
161  .description("Conductivity coefficient in Robin boundary condition.")
162  .units( UnitSI().m(4).s(-1).md() )
163  .input_default("0.0")
165  *this+=init_condition
166  .name("init_conc")
167  .units( UnitSI().kg().m(-3) )
168  .description("Initial values for concentration of substances.")
169  .input_default("0.0");
170  *this+=disp_l
171  .name("disp_l")
172  .description("Longitudinal dispersivity in the liquid (for each substance).")
173  .units( UnitSI().m() )
174  .input_default("0.0")
176  *this+=disp_t
177  .name("disp_t")
178  .description("Transverse dispersivity in the liquid (for each substance).")
179  .units( UnitSI().m() )
180  .input_default("0.0")
182  *this+=diff_m
183  .name("diff_m")
184  .description("Molecular diffusivity in the liquid (for each substance).")
185  .units( UnitSI().m(2).s(-1) )
186  .input_default("0.0")
188  *this+=rock_density
189  .name("rock_density")
190  .description("Rock matrix density.")
191  .units(UnitSI().kg().m(-3))
192  .input_default("0.0")
194  *this+=sorption_coefficient
195  .name("sorption_coefficient")
196  .description("Coefficient of linear sorption.")
197  .units(UnitSI().m(3).kg(-1))
198  .input_default("0.0")
200 
201  *this+=output_field
202  .name("conc")
203  .description("Concentration solution.")
204  .units( UnitSI().kg().m(-3) )
206 
207 
208  // initiaization of FieldModels
209  *this += v_norm.name("v_norm")
210  .description("Velocity norm field.")
211  .input_default("0.0")
212  .units( UnitSI().m().s(-1) );
213 
214  *this += mass_matrix_coef.name("mass_matrix_coef")
215  .description("Matrix coefficients computed by model in mass assemblation.")
216  .input_default("0.0")
217  .units( UnitSI().m(3).md() );
218 
219  *this += retardation_coef.name("retardation_coef")
220  .description("Retardation coefficients computed by model in mass assemblation.")
221  .input_default("0.0")
222  .units( UnitSI().m(3).md() );
223  *this += sources_density_out.name("sources_density_out")
224  .description("Concentration sources output - density of substance source, only positive part is used..")
225  .input_default("0.0")
226  .units( UnitSI().kg().s(-1).md() );
227 
228  *this += sources_sigma_out.name("sources_sigma_out")
229  .description("Concentration sources - Robin type, in_flux = sources_sigma * (sources_conc - mobile_conc).")
230  .input_default("0.0")
231  .units( UnitSI().s(-1).m(3).md() );
232 
233  *this += sources_conc_out.name("sources_conc_out")
234  .description("Concentration sources output.")
235  .input_default("0.0")
236  .units( UnitSI().kg().m(-3) );
237 
238  *this += advection_coef.name("advection_coef")
239  .description("Advection coefficients model.")
240  .input_default("0.0")
241  .units( UnitSI().m().s(-1) );
242 
243  *this += diffusion_coef.name("diffusion_coef")
244  .description("Diffusion coefficients model.")
245  .input_default("0.0")
246  .units( UnitSI().m(2).s(-1) );
247 
248 }
249 
250 
252 {
253  // initialize multifield components
254  sorption_coefficient.setup_components();
255  sources_conc.setup_components();
256  sources_density.setup_components();
257  sources_sigma.setup_components();
258  diff_m.setup_components();
259  disp_l.setup_components();
260  disp_t.setup_components();
261 
262  // create FieldModels
263  v_norm.set(Model<3, FieldValue<3>::Scalar>::create(fn_conc_v_norm(), flow_flux), 0.0);
264  mass_matrix_coef.set(Model<3, FieldValue<3>::Scalar>::create(fn_conc_mass_matrix(), cross_section, water_content), 0.0);
265  retardation_coef.set(
266  Model<3, FieldValue<3>::Scalar>::create_multi(fn_conc_retardation(), cross_section, porosity, rock_density, sorption_coefficient),
267  0.0
268  );
269  sources_density_out.set(Model<3, FieldValue<3>::Scalar>::create_multi(fn_conc_sources_dens(), cross_section, sources_density), 0.0);
270  sources_sigma_out.set(Model<3, FieldValue<3>::Scalar>::create_multi(fn_conc_sources_sigma(), cross_section, sources_sigma), 0.0);
271  sources_conc_out.set(Model<3, FieldValue<3>::Scalar>::create_multi(fn_conc_sources_conc(), sources_conc), 0.0);
272  std::vector<typename Field<3, FieldValue<3>::VectorFixed>::FieldBasePtr> ad_coef_ptr_vec;
273  for (unsigned int sbi=0; sbi<sorption_coefficient.size(); sbi++)
274  ad_coef_ptr_vec.push_back( Model<3, FieldValue<3>::VectorFixed>::create(fn_conc_ad_coef(), flow_flux) );
275  advection_coef.set(ad_coef_ptr_vec, 0.0);
276  diffusion_coef.set(
277  Model<3, FieldValue<3>::TensorFixed>::create_multi(
278  fn_conc_diff_coef(), diff_m, flow_flux, v_norm, disp_l, disp_t, water_content, porosity, cross_section
279  ),
280  0.0
281  );
282 }
283 
284 
285 
287  return Selection("Solute_AdvectionDiffusion_BC_Type", "Types of boundary conditions for advection-diffusion solute transport model.")
288  .add_value(bc_inflow, "inflow",
289  "Default transport boundary condition.\n"
290  "On water inflow (($(q_w \\le 0)$)), total flux is given by the reference concentration 'bc_conc'. "
291  "On water outflow we prescribe zero diffusive flux, "
292  "i.e. the mass flows out only due to advection.")
293  .add_value(bc_dirichlet, "dirichlet",
294  "Dirichlet boundary condition (($ c = c_D $)).\n"
295  "The prescribed concentration (($c_D$)) is specified by the field 'bc_conc'.")
296  .add_value(bc_total_flux, "total_flux",
297  "Total mass flux boundary condition.\n"
298  "The prescribed total incoming flux can have the general form (($\\delta(f_N+\\sigma_R(c_R-c) )$)), "
299  "where the absolute flux (($f_N$)) is specified by the field 'bc_flux', "
300  "the transition parameter (($\\sigma_R$)) by 'bc_robin_sigma', "
301  "and the reference concentration (($c_R$)) by 'bc_conc'.")
302  .add_value(bc_diffusive_flux, "diffusive_flux",
303  "Diffusive flux boundary condition.\n"
304  "The prescribed incoming mass flux due to diffusion can have the general form (($\\delta(f_N+\\sigma_R(c_R-c) )$)), "
305  "where the absolute flux (($f_N$)) is specified by the field 'bc_flux', "
306  "the transition parameter (($\\sigma_R$)) by 'bc_robin_sigma', "
307  "and the reference concentration (($c_R$)) by 'bc_conc'.")
308  .close();
309 }
310 
311 
312 
313 
315 {
316  // Return empty selection just to provide model specific selection name and description.
317  // The fields are added by TransportDG using an auxiliary selection.
318  return IT::Selection(
319  std::string(ModelEqData::name()) + "_DG_output_fields",
320  "Selection of output fields for Diffusive Solute Transport DG model.");
321 }
322 
323 
324 IT::Record ConcentrationTransportModel::get_input_type(const string &implementation, const string &description)
325 {
326  return IT::Record(
327  std::string(ModelEqData::name()) + "_" + implementation,
328  description + " for solute transport.")
330  .declare_key("solvent_density", IT::Double(0), IT::Default("1.0"),
331  "Density of the solvent [ (($kg.m^{-3}$)) ].");
332 }
333 
334 
337 {}
338 
339 
341 {
342  solvent_density_ = in_rec.val<double>("solvent_density");
343 }
344 
345 
347 {}
348 
349 
350 void ConcentrationTransportModel::set_balance_object(std::shared_ptr<Balance> balance)
351 {
352  balance_ = balance;
353  eq_data().subst_idx_ = balance_->add_quantities(eq_data().substances_.names());
354 }
355 
356 
358 
359 
360 
FieldCommon::units
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
Definition: field_common.hh:150
fn_conc_ad_coef
Definition: concentration_model.cc:87
ConcentrationTransportModel::ModelEqData::get_output_selection
static IT::Selection get_output_selection()
Definition: concentration_model.cc:314
FieldFlag::in_rhs
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
Definition: field_flag.hh:51
ConcentrationTransportModel::ModelEqFields::sources_density_out
MultiField< 3, FieldValue< 3 >::Scalar > sources_density_out
Concentration sources - density output.
Definition: concentration_model.hh:86
fn_conc_mass_matrix
Definition: concentration_model.cc:51
ConcentrationTransportModel::ModelEqFields::init_condition
MultiField< 3, FieldValue< 3 >::Scalar > init_condition
Initial concentrations.
Definition: concentration_model.hh:63
UnitSI::dimensionless
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:55
ConcentrationTransportModel::set_balance_object
void set_balance_object(std::shared_ptr< Balance > balance) override
Definition: concentration_model.cc:350
ConcentrationTransportModel::ModelEqFields::advection_coef
MultiField< 3, FieldValue< 3 >::VectorFixed > advection_coef
Advection coefficients.
Definition: concentration_model.hh:92
ConcentrationTransportModel::ModelEqFields::bc_robin_sigma
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_robin_sigma
Transition coefficient in total/diffusive flux b.c.
Definition: concentration_model.hh:61
MultiField::disable_where
auto disable_where(const MultiField< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> MultiField &
Definition: multi_field.impl.hh:133
ConcentrationTransportModel::ModelEqData::subst_idx_
vector< unsigned int > subst_idx_
List of indices used to call balance methods for a set of quantities.
Definition: concentration_model.hh:149
ConcentrationTransportModel::eq_data
virtual ModelEqData & eq_data()=0
Derived class should implement getter for ModelEqData instance.
fn_conc_sources_sigma
Definition: concentration_model.cc:73
Input::Record::val
const Ret val(const string &key) const
Definition: accessors_impl.hh:31
Input::Type::Selection::close
const Selection & close() const
Close the Selection, no more values can be added.
Definition: type_selection.cc:65
ConcentrationTransportModel::ModelEqFields::initialize
void initialize()
Definition: concentration_model.cc:251
ConcentrationTransportModel::ModelEqFields::disp_t
MultiField< 3, FieldValue< 3 >::Scalar > disp_t
Transversal dispersivity (for each substance).
Definition: concentration_model.hh:67
Input::Type::Double
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
ConcentrationTransportModel::init_from_input
void init_from_input(const Input::Record &in_rec) override
Read necessary data from input record.
Definition: concentration_model.cc:340
fn_conc_sources_conc
Definition: concentration_model.cc:80
std::vector
Definition: doxy_dummy_defs.hh:7
arma::vec3
Definition: doxy_dummy_defs.hh:17
FieldCommon::flags
FieldCommon & flags(FieldFlag::Flags::Mask mask)
Definition: field_common.hh:189
ConcentrationTransportModel::ModelEqFields::sources_conc_out
MultiField< 3, FieldValue< 3 >::Scalar > sources_conc_out
Concentration sources - concentration output.
Definition: concentration_model.hh:90
FieldCommon::flags_add
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
Definition: field_common.hh:195
ConcentrationTransportModel::ModelEqFields::sources_sigma_out
MultiField< 3, FieldValue< 3 >::Scalar > sources_sigma_out
Concentration sources - sigma output.
Definition: concentration_model.hh:88
EquationBase::mesh
Mesh & mesh()
Definition: equation.hh:177
Input::Type::Default
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
Input::Type::Record::derive_from
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:196
ConcentrationTransportModel::init_balance
void init_balance(const Input::Record &in_rec)
Definition: concentration_model.cc:357
EquationBase::balance
std::shared_ptr< Balance > balance() const
Definition: equation.hh:185
ConcentrationTransportModel::ModelEqFields::get_bc_type_selection
static const Input::Type::Selection & get_bc_type_selection()
Definition: concentration_model.cc:286
ConcentrationTransportModel::ModelEqFields::diffusion_coef
MultiField< 3, FieldValue< 3 >::TensorFixed > diffusion_coef
Diffusion coefficients.
Definition: concentration_model.hh:94
accessors.hh
EquationBase::balance_
std::shared_ptr< Balance > balance_
object for calculation and writing the mass balance to file.
Definition: equation.hh:230
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
ConcentrationTransportModel::~ConcentrationTransportModel
~ConcentrationTransportModel() override
Definition: concentration_model.cc:346
FieldFlag::equation_result
static constexpr Mask equation_result
Match result fields. These are never given by input or copy of input.
Definition: field_flag.hh:55
fn_conc_retardation
Definition: concentration_model.cc:59
field_model.hh
fn_conc_diff_coef
Definition: concentration_model.cc:94
ConcentrationTransportModel::ModelEqFields::bc_dirichlet
@ bc_dirichlet
Definition: concentration_model.hh:102
ConcentrationTransportModel::ModelEqFields::bc_flux
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_flux
Flux value in total/diffusive flux b.c.
Definition: concentration_model.hh:59
ConcentrationTransportModel::ModelEqFields::bc_type
BCMultiField< 3, FieldValue< 3 >::Enum > bc_type
Type of boundary condition (see also BC_Type)
Definition: concentration_model.hh:55
UnitSI
Class for representation SI units of Fields.
Definition: unit_si.hh:40
ConcentrationTransportModel::ModelEqFields::rock_density
Field< 3, FieldValue< 3 >::Scalar > rock_density
Rock matrix density.
Definition: concentration_model.hh:71
Input::Type::Record::declare_key
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
mesh.h
Input::Type::Selection
Template for classes storing finite set of named values.
Definition: type_selection.hh:65
fn_conc_sources_dens
Definition: concentration_model.cc:66
ConcentrationTransportModel::ModelEqFields::retardation_coef
MultiField< 3, FieldValue< 3 >::Scalar > retardation_coef
Field represents retardation coefficients due to sorption.
Definition: concentration_model.hh:84
Input::Type
Definition: balance.hh:41
ConcentrationTransportModel::ModelEqFields::diff_m
MultiField< 3, FieldValue< 3 >::TensorFixed > diff_m
Molecular diffusivity (for each substance).
Definition: concentration_model.hh:69
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
FieldFlag::in_main_matrix
static constexpr Mask in_main_matrix
A field is part of main "stiffness matrix" of the equation.
Definition: field_flag.hh:49
FieldCommon::input_default
FieldCommon & input_default(const string &input_default)
Definition: field_common.hh:137
input_type.hh
ConcentrationTransportModel::ModelEqFields::disp_l
MultiField< 3, FieldValue< 3 >::Scalar > disp_l
Longitudal dispersivity (for each substance).
Definition: concentration_model.hh:65
ConcentrationTransportBase
Definition: transport_operator_splitting.hh:61
Mesh
Definition: mesh.h:77
ConcentrationTransportModel::solvent_density_
double solvent_density_
Density of liquid (a global constant).
Definition: concentration_model.hh:210
Model
Definition: field_model.hh:304
ConcentrationTransportModel::ModelEqFields::bc_inflow
@ bc_inflow
Definition: concentration_model.hh:101
unit_si.hh
ConcentrationTransportModel::ModelEqFields::sorption_coefficient
MultiField< 3, FieldValue< 3 >::Scalar > sorption_coefficient
Coefficient of linear sorption.
Definition: concentration_model.hh:72
ConcentrationTransportModel::ConcentrationTransportModel
ConcentrationTransportModel(Mesh &mesh, const Input::Record &in_rec)
Definition: concentration_model.cc:335
std
Definition: doxy_dummy_defs.hh:5
ConcentrationTransportModel::ModelEqFields::bc_dirichlet_value
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_dirichlet_value
Prescribed concentration for Dirichlet/reference concentration for flux b.c.
Definition: concentration_model.hh:57
ConcentrationTransportModel::ModelEqData::name
static constexpr const char * name()
Definition: concentration_model.hh:123
fn_conc_v_norm
Definition: concentration_model.cc:44
concentration_model.hh
Discontinuous Galerkin method for equation of transport with dispersion.
ConcentrationTransportBase::get_input_type
static Input::Type::Abstract & get_input_type()
Common specification of the input record for secondary equations.
Definition: transport_operator_splitting.cc:62
balance.hh
ConcentrationTransportModel::ModelEqFields::output_field
MultiField< 3, FieldValue< 3 >::Scalar > output_field
Definition: concentration_model.hh:75
FieldCommon::input_selection
FieldCommon & input_selection(Input::Type::Selection element_selection)
Definition: field_common.hh:169
FieldCommon::description
FieldCommon & description(const string &description)
Definition: field_common.hh:125
TransportEqFields
Definition: transport_operator_splitting.hh:143
Input::Type::Selection::add_value
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.
Definition: type_selection.cc:50
FieldFlag::in_time_term
static constexpr Mask in_time_term
A field is part of time term of the equation.
Definition: field_flag.hh:47
ConcentrationTransportModel::ModelEqFields::ModelEqFields
ModelEqFields()
Definition: concentration_model.cc:134
transport_operator_splitting.hh
ConcentrationTransportModel::ModelEqFields::v_norm
Field< 3, FieldValue< 3 >::Scalar > v_norm
Velocity norm field.
Definition: concentration_model.hh:96
Sclr
double Sclr
Definition: concentration_model.cc:39
arma::mat33
Definition: doxy_dummy_defs.hh:18
FieldCommon::name
FieldCommon & name(const string &name)
Definition: field_common.hh:118
FieldValue
Definition: field_values.hh:645
FMT_UNUSED
#define FMT_UNUSED
Definition: posix.h:75
ConcentrationTransportModel::ModelEqFields::mass_matrix_coef
Field< 3, FieldValue< 3 >::Scalar > mass_matrix_coef
Field represents coefficients of mass matrix.
Definition: concentration_model.hh:82