Flow123d  jenkins-Flow123d-linux-release-multijob-282
concentration_model.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @brief Discontinuous Galerkin method for equation of transport with dispersion.
27  * @author Jan Stebel
28  */
29 
30 #include "input/input_type.hh"
31 #include "mesh/mesh.h"
32 #include "mesh/accessors.hh"
33 #include "flow/darcy_flow_mh.hh"
35 #include "concentration_model.hh"
36 #include "fields/unit_si.hh"
37 
38 
39 
40 using namespace std;
41 using namespace Input::Type;
42 
43 
44 
45 
46 
47 
48 
49 
50 
52 : TransportBase::TransportEqData()
53 {
54  *this+=bc_conc
55  .name("bc_conc")
56  .units( UnitSI().kg().m(-3) )
57  .description("Dirichlet boundary condition (for each substance).")
58  .input_default("0.0")
59  .flags_add( in_rhs );
60  *this+=init_conc
61  .name("init_conc")
62  .units( UnitSI().kg().m(-3) )
63  .description("Initial concentrations.")
64  .input_default("0.0");
65  *this+=disp_l
66  .name("disp_l")
67  .description("Longitudal dispersivity (for each substance).")
68  .units( UnitSI().m() )
69  .input_default("0.0")
71  *this+=disp_t
72  .name("disp_t")
73  .description("Transversal dispersivity (for each substance).")
74  .units( UnitSI().m() )
75  .input_default("0.0")
76  .flags_add( in_main_matrix & in_rhs );
77  *this+=diff_m
78  .name("diff_m")
79  .description("Molecular diffusivity (for each substance).")
80  .units( UnitSI().m(2).s(-1) )
81  .input_default("0.0")
82  .flags_add( in_main_matrix & in_rhs );
83  *this+=rock_density
84  .name("rock_density")
85  .description("Rock matrix density.")
86  .units(UnitSI().kg().m(-3))
87  .input_default("0.0")
89  *this+=sorption_mult
90  .name("sorption_mult")
91  .description("Coefficient of linear sorption.")
92  .units(UnitSI().mol().kg(-1))
93  .input_default("0.0")
95 
96  *this+=output_field
97  .name("conc")
98  .units( UnitSI().kg().m(-3) )
100 }
101 
102 
103 
105 {
106  return data().cross_section.units()*UnitSI().md(1)
107  *data().porosity.units()
108  *data().output_field.units();
109 }
110 
111 
112 IT::Record &ConcentrationTransportModel::get_input_type(const string &implementation, const string &description)
113 {
114  static IT::Record rec = IT::Record(
115  std::string(ModelEqData::name()) + "_" + implementation,
116  description + " for solute transport.")
119  "Names of transported substances.")
120  .declare_key("solvent_density", IT::Double(0), IT::Default("1.0"),
121  "Density of the solvent [kg.m^(-3)].");
122 
123  return rec;
124 }
125 
126 IT::Selection &ConcentrationTransportModel::ModelEqData::get_output_selection_input_type(const string &implementation, const string &description)
127 {
128  static IT::Selection sel = IT::Selection(
129  std::string(ModelEqData::name()) + "_" + implementation + "_Output",
130  "Output record for " + description + " for solute transport.");
131 
132  return sel;
133 }
134 
135 
137  flux_changed(true)
138 {}
139 
140 
142 {
143  substances.initialize(in_rec.val<Input::Array>("substances"));
144  substances_ = &substances;
145 
146  solvent_density_ = in_rec.val<double>("solvent_density");
147 }
148 
149 
150 
152  const ElementAccessor<3> &ele_acc,
153  std::vector<double> &mm_coef)
154 {
155  vector<double> elem_csec(point_list.size()), por_m(point_list.size());
156 
157  data().cross_section.value_list(point_list, ele_acc, elem_csec);
158  data().porosity.value_list(point_list, ele_acc, por_m);
159 
160  for (unsigned int i=0; i<point_list.size(); i++)
161  mm_coef[i] = elem_csec[i]*por_m[i];
162 }
163 
164 
166  const ElementAccessor<3> &ele_acc,
167  std::vector<std::vector<double> > &ret_coef)
168 {
169  vector<double> elem_csec(point_list.size()),
170  por_m(point_list.size()),
171  rho_l(point_list.size()),
172  rho_s(point_list.size());
173  vector<arma::vec > sorp_mult(point_list.size(), arma::vec(substances_->size()));
174 
175  data().cross_section.value_list(point_list, ele_acc, elem_csec);
176  data().porosity.value_list(point_list, ele_acc, por_m);
177  data().rock_density.value_list(point_list, ele_acc, rho_s);
178  data().sorption_mult.value_list(point_list, ele_acc, sorp_mult);
179 
180  for (unsigned int sbi=0; sbi<substances_->size(); sbi++)
181  {
182  for (unsigned int i=0; i<point_list.size(); i++)
183  {
184  ret_coef[sbi][i] = (1.-por_m[i])*rho_s[i]/solvent_density_*sorp_mult[i][sbi]*(*substances_)[sbi].molar_mass()*elem_csec[i];
185  }
186  }
187 }
188 
189 
191  double Dm, double alphaL, double alphaT, double porosity, double cross_cut, arma::mat33 &K)
192 {
193  double vnorm = arma::norm(velocity, 2);
194 
195  if (fabs(vnorm) > 0)
196  for (int i=0; i<3; i++)
197  for (int j=0; j<3; j++)
198  K(i,j) = (velocity[i]/vnorm)*(velocity[j]/vnorm)*(alphaL-alphaT) + alphaT*(i==j?1:0);
199  else
200  K.zeros();
201 
202  // Note that the velocity vector is in fact the Darcian flux,
203  // so to obtain |v| we have to divide vnorm by porosity and cross_section.
204  K = (vnorm*K + (Dm*pow(porosity, 1./3)*porosity*cross_cut)*arma::eye(3,3));
205 }
206 
207 
208 
209 
211  const std::vector<arma::vec3> &velocity,
212  const ElementAccessor<3> &ele_acc,
215 {
216  const unsigned int qsize = point_list.size();
217  const unsigned int n_subst = dif_coef.size();
218  std::vector<arma::vec> Dm(qsize, arma::vec(n_subst) ), alphaL(qsize, arma::vec(n_subst) ), alphaT(qsize, arma::vec(n_subst) );
219  std::vector<double> por_m(qsize), csection(qsize);
220 
221  data().diff_m.value_list(point_list, ele_acc, Dm);
222  data().disp_l.value_list(point_list, ele_acc, alphaL);
223  data().disp_t.value_list(point_list, ele_acc, alphaT);
224  data().porosity.value_list(point_list, ele_acc, por_m);
225  data().cross_section.value_list(point_list, ele_acc, csection);
226 
227  for (unsigned int i=0; i<qsize; i++) {
228  for (unsigned int sbi=0; sbi<n_subst; sbi++) {
229  ad_coef[sbi][i] = velocity[i];
230  calculate_dispersivity_tensor(velocity[i],
231  Dm[i][sbi], alphaL[i][sbi], alphaT[i][sbi], por_m[i], csection[i],
232  dif_coef[sbi][i]);
233  }
234  }
235 }
236 
237 
239  const ElementAccessor<3> &ele_acc,
240  std::vector< arma::vec > &init_values)
241 {
242  data().init_conc.value_list(point_list, ele_acc, init_values);
243 }
244 
245 
247  const ElementAccessor<3> &ele_acc,
248  std::vector< arma::vec > &bc_values)
249 {
250  data().bc_conc.value_list(point_list, ele_acc, bc_values);
251 }
252 
253 
255  const ElementAccessor<3> &ele_acc,
256  std::vector<arma::vec> &sources_value,
257  std::vector<arma::vec> &sources_density,
258  std::vector<arma::vec> &sources_sigma)
259 {
260  const unsigned int qsize = point_list.size();
261  vector<double> csection(qsize);
262  data().cross_section.value_list(point_list, ele_acc, csection);
263  data().sources_conc.value_list(point_list, ele_acc, sources_value);
264  data().sources_density.value_list(point_list, ele_acc, sources_density);
265  data().sources_sigma.value_list(point_list, ele_acc, sources_sigma);
266 
267  for (unsigned int k=0; k<qsize; k++)
268  {
269  sources_density[k] *= csection[k];
270  sources_sigma[k] *= csection[k];
271  }
272 }
273 
274 
276  const ElementAccessor<3> &ele_acc,
277  std::vector<arma::vec> &sources_sigma)
278 {
279  const unsigned int qsize = point_list.size();
280  vector<double> csection(qsize);
281  data().cross_section.value_list(point_list, ele_acc, csection);
282  data().sources_sigma.value_list(point_list, ele_acc, sources_sigma);
283 
284  for (unsigned int k=0; k<qsize; k++)
285  sources_sigma[k] *= csection[k];
286 }
287 
288 
290 {}
291 
292 
293 
void compute_retardation_coefficient(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< std::vector< double > > &ret_coef) override
Field< 3, FieldValue< 3 >::Vector > disp_l
Longitudal dispersivity (for each substance).
MultiField< 3, FieldValue< 3 >::Scalar > output_field
Accessor to input data conforming to declared Array.
Definition: accessors.hh:558
static Input::Type::AbstractRecord input_type
Common specification of the input record for secondary equations.
Field< 3, FieldValue< 3 >::Vector > disp_t
Transversal dispersivity (for each substance).
static constexpr Mask in_main_matrix
A field is part of main &quot;stiffness matrix&quot; of the equation.
Definition: field_flag.hh:34
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
Field< 3, FieldValue< 3 >::Vector > diff_m
Molecular diffusivity (for each substance).
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:39
static IT::Record & get_input_type(const string &implementation, const string &description)
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
void compute_dirichlet_bc(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &bc_values) override
static Default obligatory()
Definition: type_record.hh:89
???
void initialize(const Input::Array &in_array)
Read from input array.
Definition: substance.cc:68
Field< 3, FieldValue< 3 >::Vector > sources_conc
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:197
Field< 3, FieldValue< 3 >::Scalar > porosity
Mobile porosity.
bool flux_changed
Indicator of change in advection vector field.
static constexpr const char * name()
Field< 3, FieldValue< 3 >::Vector > init_conc
Initial concentrations.
void compute_mass_matrix_coefficient(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< double > &mm_coef) override
Discontinuous Galerkin method for equation of transport with dispersion.
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list) const
Definition: field.hh:326
unsigned int size() const
Definition: substance.hh:99
double solvent_density_
Density of liquid (a global constant).
Class for declaration of inputs sequences.
Definition: type_base.hh:239
Specification of transport model interface.
Field< 3, FieldValue< 3 >::Scalar > rock_density
Rock matrix density.
void compute_init_cond(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &init_values) override
void compute_sources_sigma(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &sources_sigma) override
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:392
static constexpr Mask equation_result
Match result fields. These are never given by input or copy of input.
Definition: field_flag.hh:39
static IT::Selection & get_output_selection_input_type(const string &implementation, const string &description)
static constexpr Mask in_time_term
A field is part of time term of the equation.
Definition: field_flag.hh:32
FieldCommon & input_default(const string &input_default)
Definition: field_common.hh:92
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
void calculate_dispersivity_tensor(const arma::vec3 &velocity, double Dm, double alphaL, double alphaT, double porosity, double cross_cut, arma::mat33 &K)
const Ret val(const string &key) const
Field< 3, FieldValue< 3 >::Vector > sorption_mult
Coefficient of linear sorption.
void init_from_input(const Input::Record &in_rec, SubstanceList &substances) override
Read necessary data from input record.
BCField< 3, FieldValue< 3 >::Vector > bc_conc
Boundary conditions (Dirichlet) for concentrations.
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
Definition: field_flag.hh:36
void compute_source_coefficients(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &sources_conc, std::vector< arma::vec > &sources_density, std::vector< arma::vec > &sources_sigma) override
SubstanceList * substances_
Pointer to list of substances (needed e.g. for access to molar masses).
Field< 3, FieldValue< 3 >::Vector > sources_sigma
Concentration sources - Robin type, in_flux = sources_sigma * (sources_conc - mobile_conc) ...
FieldCommon & description(const string &description)
Definition: field_common.hh:80
Field< 3, FieldValue< 3 >::Vector > sources_density
Concentration sources - density of substance source, only positive part is used.
FieldCommon & name(const string &name)
Definition: field_common.hh:73
mixed-hybrid model of linear Darcy flow, possibly unsteady.
Record type proxy class.
Definition: type_record.hh:169
FieldCommon & flags(FieldFlag::Flags::Mask mask)
Class for representation SI units of Fields.
Definition: unit_si.hh:31
void compute_advection_diffusion_coefficients(const std::vector< arma::vec3 > &point_list, const std::vector< arma::vec3 > &velocity, const ElementAccessor< 3 > &ele_acc, std::vector< std::vector< arma::vec3 > > &ad_coef, std::vector< std::vector< arma::mat33 > > &dif_coef) override
static Input::Type::Record input_type
Input type for a substance.
Definition: substance.hh:62
UnitSI & md(int exp=-1)
Method sets value of exponent for m^{-d}, where d is dimension of region.
Definition: unit_si.cc:91
virtual ModelEqData & data()=0
Derived class should implement getter for ModelEqData instance.
Template for classes storing finite set of named values.
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:430