Flow123d  jenkins-Flow123d-linux-release-multijob-282
heat_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 "heat_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 {
53 
54  *this+=bc_temperature
55  .name("bc_temperature")
56  .description("Boundary value of temperature.")
57  .units( UnitSI().K() )
58  .input_default("0.0")
59  .flags_add(in_rhs);
60 
61  *this+=init_temperature
62  .name("init_temperature")
63  .description("Initial temperature.")
64  .units( UnitSI().K() )
65  .input_default("0.0");
66 
67  *this+=porosity
68  .name("porosity")
69  .description("Porosity.")
70  .units( UnitSI::dimensionless() )
71  .input_default("1.0")
72  .flags_add(in_main_matrix & in_time_term);
73 
74  *this+=fluid_density
75  .name("fluid_density")
76  .description("Density of fluid.")
77  .units( UnitSI().kg().m(-3) )
78  .flags_add(in_main_matrix & in_time_term);
79 
80  *this+=fluid_heat_capacity
81  .name("fluid_heat_capacity")
82  .description("Heat capacity of fluid.")
83  .units( UnitSI::J() * UnitSI().kg(-1).K(-1) )
84  .flags_add(in_main_matrix & in_time_term);
85 
86  *this+=fluid_heat_conductivity
87  .name("fluid_heat_conductivity")
88  .description("Heat conductivity of fluid.")
89  .units( UnitSI::W() * UnitSI().m(-1).K(-1) )
90  .flags_add(in_main_matrix);
91 
92 
93  *this+=solid_density
94  .name("solid_density")
95  .description("Density of solid (rock).")
96  .units( UnitSI().kg().m(-3) )
97  .flags_add(in_time_term);
98 
99  *this+=solid_heat_capacity
100  .name("solid_heat_capacity")
101  .description("Heat capacity of solid (rock).")
102  .units( UnitSI::J() * UnitSI().kg(-1).K(-1) )
103  .flags_add(in_time_term);
104 
105  *this+=solid_heat_conductivity
106  .name("solid_heat_conductivity")
107  .description("Heat conductivity of solid (rock).")
108  .units( UnitSI::W() * UnitSI().m(-1).K(-1) )
109  .flags_add(in_main_matrix);
110 
111  *this+=disp_l
112  .name("disp_l")
113  .description("Longitudal heat dispersivity in fluid.")
114  .units( UnitSI().m() )
115  .input_default("0.0")
116  .flags_add(in_main_matrix);
117 
118  *this+=disp_t
119  .name("disp_t")
120  .description("Transversal heat dispersivity in fluid.")
121  .units( UnitSI().m() )
122  .input_default("0.0")
123  .flags_add(in_main_matrix);
124 
125  *this+=fluid_thermal_source
126  .name("fluid_thermal_source")
127  .description("Thermal source density in fluid.")
128  .units( UnitSI::W() * UnitSI().m(-3) )
129  .input_default("0.0")
130  .flags_add(in_rhs);
131 
132  *this+=solid_thermal_source
133  .name("solid_thermal_source")
134  .description("Thermal source density in solid.")
135  .units( UnitSI::W() * UnitSI().m(-3) )
136  .input_default("0.0")
137  .flags_add(in_rhs);
138 
139  *this+=fluid_heat_exchange_rate
140  .name("fluid_heat_exchange_rate")
141  .description("Heat exchange rate in fluid.")
142  .units( UnitSI().s(-1) )
143  .input_default("0.0")
144  .flags_add(in_rhs);
145 
146  *this+=solid_heat_exchange_rate
147  .name("solid_heat_exchange_rate")
148  .description("Heat exchange rate of source in solid.")
149  .units( UnitSI().s(-1) )
150  .input_default("0.0")
151  .flags_add(in_rhs);
152 
153  *this+=fluid_ref_temperature
154  .name("fluid_ref_temperature")
155  .description("Reference temperature of source in fluid.")
156  .units( UnitSI().K() )
157  .input_default("0.0")
158  .flags_add(in_rhs);
159 
160  *this+=solid_ref_temperature
161  .name("solid_ref_temperature")
162  .description("Reference temperature in solid.")
163  .units( UnitSI().K() )
164  .input_default("0.0")
165  .flags_add(in_rhs);
166 
167  *this+=cross_section
168  .name("cross_section")
169  .units( UnitSI().m(3).md() )
170  .flags(input_copy & in_time_term & in_main_matrix);
171 
172  *this+=output_field
173  .name("temperature")
174  .units( UnitSI().K() )
175  .flags(equation_result);
176 }
177 
178 
180 {
181  return data().cross_section.units()*UnitSI().md(1)
182  *data().output_field.units()
183  *data().porosity.units()
184  *data().fluid_density.units()
185  *data().fluid_heat_capacity.units();
186 }
187 
188 IT::Record &HeatTransferModel::get_input_type(const string &implementation, const string &description)
189 {
190  static IT::Record input_type = IT::Record(
191  std::string(ModelEqData::name()) + "_" + implementation,
192  description + " for heat transfer.")
194 
195  return input_type;
196 
197 }
198 
199 
200 IT::Selection &HeatTransferModel::ModelEqData::get_output_selection_input_type(const string &implementation, const string &description)
201 {
202  static IT::Selection input_type = IT::Selection(
203  std::string(ModelEqData::name()) + "_" + implementation + "_Output",
204  "Selection for output fields of " + description + " for heat transfer.");
205 
206  return input_type;
207 }
208 
209 
211  flux_changed(true)
212 {}
213 
214 
216 {
217  substances.initialize({""});
218 }
219 
220 
222  const ElementAccessor<3> &ele_acc,
223  std::vector<double> &mm_coef)
224 {
225  vector<double> elem_csec(point_list.size()),
226  por(point_list.size()),
227  f_rho(point_list.size()),
228  s_rho(point_list.size()),
229  f_c(point_list.size()),
230  s_c(point_list.size());
231 
232  data().cross_section.value_list(point_list, ele_acc, elem_csec);
233  data().porosity.value_list(point_list, ele_acc, por);
234  data().fluid_density.value_list(point_list, ele_acc, f_rho);
235  data().fluid_heat_capacity.value_list(point_list, ele_acc, f_c);
236  data().solid_density.value_list(point_list, ele_acc, s_rho);
237  data().solid_heat_capacity.value_list(point_list, ele_acc, s_c);
238 
239  for (unsigned int i=0; i<point_list.size(); i++)
240  mm_coef[i] = elem_csec[i]*(por[i]*f_rho[i]*f_c[i] + (1.-por[i])*s_rho[i]*s_c[i]);
241 }
242 
243 
245  const std::vector<arma::vec3> &velocity,
246  const ElementAccessor<3> &ele_acc,
249 {
250  const unsigned int qsize = point_list.size();
251  std::vector<double> f_rho(qsize), f_cap(qsize), f_cond(qsize),
252  s_cond(qsize), por(qsize), csection(qsize), disp_l(qsize), disp_t(qsize);
253 
254  data().fluid_density.value_list(point_list, ele_acc, f_rho);
255  data().fluid_heat_capacity.value_list(point_list, ele_acc, f_cap);
256  data().fluid_heat_conductivity.value_list(point_list, ele_acc, f_cond);
257  data().solid_heat_conductivity.value_list(point_list, ele_acc, s_cond);
258  data().disp_l.value_list(point_list, ele_acc, disp_l);
259  data().disp_t.value_list(point_list, ele_acc, disp_t);
260  data().porosity.value_list(point_list, ele_acc, por);
261  data().cross_section.value_list(point_list, ele_acc, csection);
262 
263  for (unsigned int k=0; k<qsize; k++) {
264  ad_coef[0][k] = velocity[k]*f_rho[k]*f_cap[k];
265 
266  // dispersive part of thermal diffusion
267  // Note that the velocity vector is in fact the Darcian flux,
268  // so to obtain |v| we have to divide vnorm by porosity and cross_section.
269  double vnorm = arma::norm(velocity[k], 2);
270  if (fabs(vnorm) > 0)
271  for (int i=0; i<3; i++)
272  for (int j=0; j<3; j++)
273  dif_coef[0][k](i,j) = ((velocity[k][i]/vnorm)*(velocity[k][j]/vnorm)*(disp_l[k]-disp_t[k]) + disp_t[k]*(i==j?1:0))
274  *vnorm*f_rho[k]*f_cond[k];
275  else
276  dif_coef[0][k].zeros();
277 
278  // conductive part of thermal diffusion
279  dif_coef[0][k] += csection[k]*(por[k]*f_cond[k] + (1.-por[k])*s_cond[k])*arma::eye(3,3);
280  }
281 }
282 
283 
285  const ElementAccessor<3> &ele_acc,
286  std::vector< arma::vec > &init_values)
287 {
288  vector<double> init_value(point_list.size());
289  data().init_temperature.value_list(point_list, ele_acc, init_value);
290  for (unsigned int i=0; i<point_list.size(); i++)
291  init_values[i] = init_value[i];
292 }
293 
294 
296  const ElementAccessor<3> &ele_acc,
297  std::vector< arma::vec > &bc_values)
298 {
299  vector<double> bc_value(point_list.size());
300  data().bc_temperature.value_list(point_list, ele_acc, bc_value);
301  for (unsigned int i=0; i<point_list.size(); i++)
302  bc_values[i] = bc_value[i];
303 }
304 
305 
307  const ElementAccessor<3> &ele_acc,
308  std::vector<arma::vec> &sources_value,
309  std::vector<arma::vec> &sources_density,
310  std::vector<arma::vec> &sources_sigma)
311 {
312  const unsigned int qsize = point_list.size();
313  std::vector<double> por(qsize), csection(qsize), f_rho(qsize), s_rho(qsize), f_cap(qsize), s_cap(qsize),
314  f_source(qsize), s_source(qsize), f_sigma(qsize), s_sigma(qsize), f_temp(qsize), s_temp(qsize);
315  data().porosity.value_list(point_list, ele_acc, por);
316  data().cross_section.value_list(point_list, ele_acc, csection);
317  data().fluid_density.value_list(point_list, ele_acc, f_rho);
318  data().solid_density.value_list(point_list, ele_acc, s_rho);
319  data().fluid_heat_capacity.value_list(point_list, ele_acc, f_cap);
320  data().solid_heat_capacity.value_list(point_list, ele_acc, s_cap);
321  data().fluid_thermal_source.value_list(point_list, ele_acc, f_source);
322  data().solid_thermal_source.value_list(point_list, ele_acc, s_source);
323  data().fluid_heat_exchange_rate.value_list(point_list, ele_acc, f_sigma);
324  data().solid_heat_exchange_rate.value_list(point_list, ele_acc, s_sigma);
325  data().fluid_ref_temperature.value_list(point_list, ele_acc, f_temp);
326  data().solid_ref_temperature.value_list(point_list, ele_acc, s_temp);
327 
328  for (unsigned int k=0; k<point_list.size(); k++)
329  {
330  sources_density[k].resize(1);
331  sources_sigma[k].resize(1);
332  sources_value[k].resize(1);
333 
334  sources_density[k][0] = csection[k]*(por[k]*f_source[k] + (1.-por[k])*s_source[k]);
335  sources_sigma[k][0] = csection[k]*(por[k]*f_rho[k]*f_cap[k]*f_sigma[k] + (1.-por[k])*s_rho[k]*s_cap[k]*s_sigma[k]);
336  if (fabs(sources_sigma[k][0]) > numeric_limits<double>::epsilon())
337  sources_value[k][0] = csection[k]*(por[k]*f_rho[k]*f_cap[k]*f_sigma[k]*f_temp[k]
338  + (1.-por[k])*s_rho[k]*s_cap[k]*s_sigma[k]*s_temp[k])/sources_sigma[k][0];
339  else
340  sources_value[k][0] = 0;
341  }
342 }
343 
344 
346  const ElementAccessor<3> &ele_acc,
347  std::vector<arma::vec> &sources_sigma)
348 {
349  const unsigned int qsize = point_list.size();
350  std::vector<double> por(qsize), csection(qsize), f_rho(qsize), s_rho(qsize), f_cap(qsize), s_cap(qsize),
351  f_source(qsize), s_source(qsize), f_sigma(qsize), s_sigma(qsize), f_temp(qsize), s_temp(qsize);
352  data().porosity.value_list(point_list, ele_acc, por);
353  data().cross_section.value_list(point_list, ele_acc, csection);
354  data().fluid_density.value_list(point_list, ele_acc, f_rho);
355  data().solid_density.value_list(point_list, ele_acc, s_rho);
356  data().fluid_heat_capacity.value_list(point_list, ele_acc, f_cap);
357  data().solid_heat_capacity.value_list(point_list, ele_acc, s_cap);
358  data().fluid_heat_exchange_rate.value_list(point_list, ele_acc, f_sigma);
359  data().solid_heat_exchange_rate.value_list(point_list, ele_acc, s_sigma);
360  for (unsigned int k=0; k<point_list.size(); k++)
361  {
362  sources_sigma[k].resize(1);
363  sources_sigma[k][0] = csection[k]*(por[k]*f_rho[k]*f_cap[k]*f_sigma[k] + (1.-por[k])*s_rho[k]*s_cap[k]*s_sigma[k]);
364  }
365 }
366 
367 
369 {}
370 
Field< 3, FieldValue< 3 >::Scalar > solid_heat_capacity
Heat capacity of solid.
Definition: heat_model.hh:59
void compute_sources_sigma(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &sources_sigma) override
Definition: heat_model.cc:345
UnitSI balance_units()
Definition: heat_model.cc:179
Field< 3, FieldValue< 3 >::Scalar > fluid_density
Density of fluid.
Definition: heat_model.hh:51
BCField< 3, FieldValue< 3 >::Scalar > bc_temperature
Dirichlet boundary condition for temperature.
Definition: heat_model.hh:45
static Input::Type::AbstractRecord input_type
Common specification of the input record for secondary equations.
Field< 3, FieldValue< 3 >::Scalar > disp_t
Transversal heat dispersivity.
Definition: heat_model.hh:65
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
Definition: heat_model.hh:80
???
void initialize(const Input::Array &in_array)
Read from input array.
Definition: substance.cc:68
Field< 3, FieldValue< 3 >::Scalar > fluid_heat_exchange_rate
Heat exchange rate in fluid.
Definition: heat_model.hh:71
Field< 3, FieldValue< 3 >::Scalar > solid_heat_exchange_rate
Heat exchange rate in solid.
Definition: heat_model.hh:73
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:197
void compute_init_cond(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &init_values) override
Definition: heat_model.cc:284
Field< 3, FieldValue< 3 >::Scalar > fluid_heat_capacity
Heat capacity of fluid.
Definition: heat_model.hh:53
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
Field< 3, FieldValue< 3 >::Scalar > porosity
Porosity of solid.
Definition: heat_model.hh:49
Field< 3, FieldValue< 3 >::Scalar > fluid_thermal_source
Thermal source in fluid.
Definition: heat_model.hh:67
void init_from_input(const Input::Record &in_rec, SubstanceList &substances) override
Read necessary data from input record.
Definition: heat_model.cc:215
Field< 3, FieldValue< 3 >::Scalar > fluid_heat_conductivity
Heat conductivity of fluid.
Definition: heat_model.hh:55
Field< 3, FieldValue< 3 >::Scalar > fluid_ref_temperature
Reference temperature in fluid.
Definition: heat_model.hh:75
Field< 3, FieldValue< 3 >::Scalar > init_temperature
Initial temperature.
Definition: heat_model.hh:47
Field< 3, FieldValue< 3 >::Scalar > solid_thermal_source
Thermal source in solid.
Definition: heat_model.hh:69
void compute_mass_matrix_coefficient(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< double > &mm_coef) override
Definition: heat_model.cc:221
void compute_dirichlet_bc(const std::vector< arma::vec3 > &point_list, const ElementAccessor< 3 > &ele_acc, std::vector< arma::vec > &bc_values) override
Definition: heat_model.cc:295
static UnitSI & W()
Returns Watt.
Definition: unit_si.cc:34
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
static UnitSI & J()
Returns Joule.
Definition: unit_si.cc:29
Field< 3, FieldValue< 3 >::Scalar > solid_heat_conductivity
Heat conductivity of solid.
Definition: heat_model.hh:61
const double epsilon
Definition: mathfce.h:6
Field< 3, FieldValue< 3 >::Scalar > solid_ref_temperature
Reference temperature in solid.
Definition: heat_model.hh:77
static IT::Selection & get_output_selection_input_type(const string &implementation, const string &description)
Definition: heat_model.cc:200
virtual ModelEqData & data()=0
Derived class should implement getter for ModelEqData instance.
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
Definition: heat_model.cc:244
~HeatTransferModel() override
Definition: heat_model.cc:368
Field< 3, FieldValue< 3 >::Scalar > solid_density
Density of solid.
Definition: heat_model.hh:57
Discontinuous Galerkin method for equation of transport with dispersion.
mixed-hybrid model of linear Darcy flow, possibly unsteady.
Record type proxy class.
Definition: type_record.hh:169
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
Definition: heat_model.cc:306
Class for representation SI units of Fields.
Definition: unit_si.hh:31
UnitSI & md(int exp=-1)
Method sets value of exponent for m^{-d}, where d is dimension of region.
Definition: unit_si.cc:91
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:44
Template for classes storing finite set of named values.
static IT::Record & get_input_type(const string &implementation, const string &description)
Definition: heat_model.cc:188
Field< 3, FieldValue< 3 >::Scalar > disp_l
Longitudal heat dispersivity.
Definition: heat_model.hh:63