Flow123d  JS_before_hm-1576-g4d0b70e
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")
164  .flags_add(FieldFlag::in_rhs & FieldFlag::in_main_matrix);
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")
181  .flags_add( in_main_matrix & in_rhs );
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")
187  .flags_add( in_main_matrix & in_rhs );
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
261 
262  // create FieldModels
267  0.0
268  );
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);
277  Model<3, FieldValue<3>::TensorFixed>::create_multi(
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 
336  ConcentrationTransportBase(mesh, in_rec)
337 {}
338 
339 
341 {
342  solvent_density_ = in_rec.val<double>("solvent_density");
343 }
344 
345 
347 {}
348 
349 
351 {
352  balance_ = balance;
353  eq_data().subst_idx_ = balance_->add_quantities(eq_data().substances_.names());
354 }
355 
356 
358 
359 
360 
MultiField< 3, FieldValue< 3 >::Scalar > sources_conc
void set_balance_object(std::shared_ptr< Balance > balance) override
ConcentrationTransportModel(Mesh &mesh, const Input::Record &in_rec)
MultiField< 3, FieldValue< 3 >::Scalar > output_field
Field< 3, FieldValue< 3 >::Scalar > mass_matrix_coef
Field represents coefficients of mass matrix.
FieldCommon & input_selection(Input::Type::Selection element_selection)
auto disable_where(const MultiField< spacedim, typename FieldValue< spacedim >::Enum > &control_field, const vector< FieldEnum > &value_list) -> MultiField &
static constexpr Mask in_main_matrix
A field is part of main "stiffness matrix" of the equation.
Definition: field_flag.hh:49
MultiField< 3, FieldValue< 3 >::Scalar > sources_density_out
Concentration sources - density output.
unsigned int size() const
Number of subfields that compose the multi-field.
Definition: multi_field.hh:206
Field< 3, FieldValue< 3 >::VectorFixed > flow_flux
Flow flux, can be result of water flow model.
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_robin_sigma
Transition coefficient in total/diffusive flux b.c.
Field< 3, FieldValue< 3 >::Scalar > water_content
Water content - result of unsaturated water flow model or porosity.
MultiField< 3, FieldValue< 3 >::Scalar > init_condition
Initial concentrations.
void init_from_input(const Input::Record &in_rec) override
Read necessary data from input record.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
const Mesh * mesh() const
Returns pointer to mesh.
Definition: field_set.hh:370
MultiField< 3, FieldValue< 3 >::Scalar > sources_sigma
Concentration sources - Robin type, in_flux = sources_sigma * (sources_conc - mobile_conc) ...
double Sclr
vector< unsigned int > subst_idx_
List of indices used to call balance methods for a set of quantities.
Definition: mesh.h:77
static constexpr const char * name()
MultiField< 3, FieldValue< 3 >::Scalar > sorption_coefficient
Coefficient of linear sorption.
static Input::Type::Abstract & get_input_type()
Common specification of the input record for secondary equations.
MultiField< 3, FieldValue< 3 >::TensorFixed > diff_m
Molecular diffusivity (for each substance).
Discontinuous Galerkin method for equation of transport with dispersion.
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
void set(std::vector< typename Field< spacedim, Value >::FieldBasePtr > field_vec, double time, std::vector< std::string > region_set_names={"ALL"})
MultiField< 3, FieldValue< 3 >::Scalar > disp_l
Longitudal dispersivity (for each substance).
double solvent_density_
Density of liquid (a global constant).
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_dirichlet_value
Prescribed concentration for Dirichlet/reference concentration for flux b.c.
virtual ModelEqData & eq_data()=0
Derived class should implement getter for ModelEqData instance.
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:196
Field< 3, FieldValue< 3 >::Scalar > rock_density
Rock matrix density.
void setup_components()
void set(FieldBasePtr field, double time, std::vector< std::string > region_set_names={"ALL"})
Definition: field.impl.hh:258
#define FMT_UNUSED
Definition: posix.h:75
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
MultiField< 3, FieldValue< 3 >::VectorFixed > advection_coef
Advection coefficients.
static constexpr Mask equation_result
Match result fields. These are never given by input or copy of input.
Definition: field_flag.hh:55
static constexpr Mask in_time_term
A field is part of time term of the equation.
Definition: field_flag.hh:47
MultiField< 3, FieldValue< 3 >::Scalar > sources_sigma_out
Concentration sources - sigma output.
FieldCommon & input_default(const string &input_default)
MultiField< 3, FieldValue< 3 >::Scalar > retardation_coef
Field represents retardation coefficients due to sorption.
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_flux
Flux value in total/diffusive flux b.c.
const Ret val(const string &key) const
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.
std::shared_ptr< Balance > balance_
object for calculation and writing the mass balance to file.
Definition: equation.hh:230
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
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
Definition: field_flag.hh:51
BCMultiField< 3, FieldValue< 3 >::Enum > bc_type
Type of boundary condition (see also BC_Type)
static const Input::Type::Selection & get_bc_type_selection()
std::shared_ptr< Balance > balance() const
Definition: equation.hh:185
Field< 3, FieldValue< 3 >::Scalar > porosity
Mobile porosity - usually saturated water content in the case of unsaturated flow model...
FieldCommon & description(const string &description)
Field< 3, FieldValue< 3 >::Scalar > v_norm
Velocity norm field.
const Selection & close() const
Close the Selection, no more values can be added.
MultiField< 3, FieldValue< 3 >::Scalar > sources_conc_out
Concentration sources - concentration output.
FieldCommon & name(const string &name)
Record type proxy class.
Definition: type_record.hh:182
MultiField< 3, FieldValue< 3 >::TensorFixed > diffusion_coef
Diffusion coefficients.
FieldCommon & flags(FieldFlag::Flags::Mask mask)
void init_balance(const Input::Record &in_rec)
Class for representation SI units of Fields.
Definition: unit_si.hh:40
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:55
Template for classes storing finite set of named values.
MultiField< 3, FieldValue< 3 >::Scalar > disp_t
Transversal dispersivity (for each substance).
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
MultiField< 3, FieldValue< 3 >::Scalar > sources_density
Concentration sources - density of substance source, only positive part is used.