Flow123d  release_2.2.0-914-gf1a3a4f
transport_dg.hh
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 transport_dg.hh
15  * @brief Discontinuous Galerkin method for equation of transport with dispersion.
16  * @author Jan Stebel
17  */
18 
19 #ifndef TRANSPORT_DG_HH_
20 #define TRANSPORT_DG_HH_
21 
23 #include "fields/bc_field.hh"
24 #include "fields/field.hh"
25 #include "fields/multi_field.hh"
26 #include "fields/vec_seq_double.hh"
27 #include "la/linsys.hh"
28 #include "flow/mh_dofhandler.hh"
30 #include "fem/mapping_p1.hh"
31 
32 class Distribution;
33 class OutputTime;
34 class DOFHandlerMultiDim;
35 template<unsigned int dim, unsigned int spacedim> class FEValuesBase;
36 template<unsigned int dim, unsigned int spacedim> class FiniteElement;
37 template<unsigned int dim, unsigned int spacedim> class Mapping;
38 template<unsigned int dim> class Quadrature;
39 
40 
41 
42 /**
43  * Auxiliary container class for Finite element and related objects of all dimensions.
44  * Its purpose is to provide templated access to these objects, applicable in
45  * the assembling methods.
46  */
47 class FEObjects {
48 public:
49 
50  FEObjects(Mesh *mesh_, unsigned int fe_order);
51  ~FEObjects();
52 
53  template<unsigned int dim>
54  inline FiniteElement<dim,3> *fe();
55 
56  template<unsigned int dim>
57  inline FiniteElement<dim,3> *fe_rt();
58 
59  template<unsigned int dim>
60  inline Quadrature<dim> *q();
61 
62  template<unsigned int dim>
63  inline MappingP1<dim,3> *mapping();
64 
65  inline std::shared_ptr<DOFHandlerMultiDim> dh();
66 
67 private:
68 
69  /// Finite elements for the solution of the advection-diffusion equation.
73 
74  /// Finite elements for the water velocity field.
78 
79  /// Quadratures used in assembling methods.
84 
85  /// Auxiliary mappings of reference elements.
89 
90  /// Object for distribution of dofs.
91  std::shared_ptr<DOFHandlerMultiDim> dh_;
92 };
93 
94 
95 
96 /**
97  * @brief Transport with dispersion implemented using discontinuous Galerkin method.
98  *
99  * TransportDG implements the discontinuous Galerkin method for the transport and diffusion of substances.
100  * The concentration @f$ c_i ~[kg/m^3]@f$ of the i-th substance is governed by the advection-diffusion equation
101  * @f[
102  * \partial_t c_i + \mathbf v\cdot\nabla c_i - \mathrm{div}(D\nabla c_i) = F \mbox{ in }\Omega^d,
103  * @f]
104  * where @f$\mathbf v@f$ is the fluid velocity and @f$\Omega^d@f$ the @f$d@f$-dimensional domain, respectively.
105  * The hydrodynamic dispersivity tensor @f$\mathbf D ~[m^2/s]@f$ is given by:
106  * @f[
107  * \mathbf D = D_m\mathbf I + |\mathbf v|\left(\alpha_T\mathbf I + (\alpha_L-\alpha_T)\frac{\mathbf v\otimes\mathbf v}{|\mathbf v|^2}\right).
108  * @f]
109  * The molecular dispersivity @f$D_m~[m^2/s]@f$, as well as the longitudal and transversal dispersivity @f$\alpha_L,~\alpha_T~[m]@f$ are input parameters of the model.
110  *
111  * For lower dimensions @f$d=1,2@f$ the advection-diffusion equation is multiplied by the fracture cross-cut @f$\delta^d~[m^{3-d}]@f$.
112  *
113  * The boundary @f$\partial\Omega^d@f$ is divided into three disjoint parts @f$\Gamma^d_D\cup\Gamma^d_N\cup\Gamma^d_F@f$.
114  * We prescribe the following boundary conditions:
115  * @f{eqnarray*}{
116  * c_i^d &= c_{iD}^d &\mbox{ on }\Gamma^d_D \mbox{ (Dirichlet)},\\
117  * \mathbf D^d\nabla c_i^d\cdot\mathbf n &= 0 &\mbox{ on }\Gamma^d_N \mbox{ (Neumann)},
118  * @f}
119  * The transfer of mass through fractures is described by the transmission conditions on @f$\Gamma^d_F@f$:
120  * @f[
121  * -\mathbf D^d\nabla c_i^d\cdot\mathbf n = \sigma(c_i^d-c_i^{d-1}) + \left\{\begin{array}{cl}0 &\mbox{ if }\mathbf v^d\cdot\mathbf n\ge 0\\\mathbf v^d\cdot\mathbf n(c_i^{d-1}-c_i^d) & \mbox{ if }\mathbf v^d\cdot\mathbf n<0\end{array}\right.,\qquad
122  * F^{d-1} = (\sigma + |\mathbf v^d\cdot\mathbf n|)(c_i^d-c_i^{d-1}).
123  * @f]
124  * Here @f$\mathbf n@f$ stands for the unit outward normal vector to @f$\partial\Omega^d@f$.
125  * The coefficient @f$\sigma@f$ determines the transfer of mass through fractures due to diffusion.
126  *
127  * @ingroup transport_mod
128  *
129  */
130 template<class Model>
131 class TransportDG : public Model
132 {
133 public:
134 
135  class EqData : public Model::ModelEqData {
136  public:
137 
138  EqData();
139 
140  MultiField<3, FieldValue<3>::Scalar> fracture_sigma; ///< Transition parameter for diffusive transfer on fractures (for each substance).
141  MultiField<3, FieldValue<3>::Scalar> dg_penalty; ///< Penalty enforcing inter-element continuity of solution (for each substance).
144 
146 
147  };
148 
149 
150 
151  enum DGVariant {
152  // Non-symmetric weighted interior penalty DG
153  non_symmetric = -1,
154 
155  // Incomplete weighted interior penalty DG
156  incomplete = 0,
157 
158  // Symmetric weighted interior penalty DG
159  symmetric = 1
160  };
161 
162  /**
163  * @brief Constructor.
164  * @param init_mesh computational mesh
165  * @param in_rec input record
166  */
167  TransportDG(Mesh &init_mesh, const Input::Record in_rec);
168  /**
169 
170  * @brief Declare input record type for the equation TransportDG.
171  */
172  static const Input::Type::Record & get_input_type();
173 
174  /**
175  * @brief Input type for the DG variant selection.
176  */
177  static const Input::Type::Selection & get_dg_variant_selection_input_type();
178 
179  /**
180  * @brief Initialize solution in the zero time.
181  */
182  void zero_time_step() override;
183 
184  bool evaluate_time_constraint(double &time_constraint)
185  { return false; }
186 
187  /**
188  * @brief Computes the solution in one time instant.
189  */
190  void update_solution() override;
191 
192  /**
193  * @brief Postprocesses the solution and writes to output file.
194  */
195  void output_data();
196 
197  /**
198  * @brief Destructor.
199  */
200  ~TransportDG();
201 
202  void initialize() override;
203 
204  void calculate_cumulative_balance();
205 
206  const Vec &get_solution(unsigned int sbi)
207  { return ls[sbi]->get_solution(); }
208 
210  { return solution_elem_; }
211 
212  void calculate_concentration_matrix();
213 
214  void update_after_reactions(bool solution_changed);
215 
216  void get_par_info(IdxInt * &el_4_loc, Distribution * &el_ds);
217 
218  IdxInt *get_row_4_el();
219 
220 
221 
222 
223 private:
224  /// Registrar of class to factory
225  static const int registrar;
226 
227  inline typename Model::ModelEqData &data() { return data_; }
228 
229  void output_vector_gather();
230 
231  void preallocate();
232 
233  /**
234  * @brief Assembles the mass matrix.
235  *
236  * The routine just calls templated method assemble_mass_matrix() for each
237  * space dimension.
238  */
239  void assemble_mass_matrix();
240 
241  /**
242  * @brief Assembles the mass matrix for the given dimension.
243  */
244  template<unsigned int dim>
245  void assemble_mass_matrix();
246 
247  /**
248  * @brief Assembles the stiffness matrix.
249  *
250  * This routine just calls assemble_volume_integrals(), assemble_fluxes_boundary(),
251  * assemble_fluxes_element_element() and assemble_fluxes_element_side() for each
252  * space dimension.
253  */
254  void assemble_stiffness_matrix();
255 
256  /**
257  * @brief Assembles the volume integrals into the stiffness matrix.
258  */
259  template<unsigned int dim>
260  void assemble_volume_integrals();
261 
262  /**
263  * @brief Assembles the right hand side due to volume sources.
264  *
265  * This method just calls set_sources() for each space dimension.
266  */
267  void set_sources();
268 
269  /**
270  * @brief Assembles the right hand side vector due to volume sources.
271  */
272  template<unsigned int dim>
273  void set_sources();
274 
275  /**
276  * @brief Assembles the fluxes on the boundary.
277  */
278  template<unsigned int dim>
279  void assemble_fluxes_boundary();
280 
281  /**
282  * @brief Assembles the fluxes between elements of the same dimension.
283  */
284  template<unsigned int dim>
285  void assemble_fluxes_element_element();
286 
287  /**
288  * @brief Assembles the fluxes between elements of different dimensions.
289  */
290  template<unsigned int dim>
291  void assemble_fluxes_element_side();
292 
293 
294  /**
295  * @brief Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions.
296  *
297  * The routine just calls templated method set_boundary_condition() for each space dimension.
298  */
299  void set_boundary_conditions();
300 
301  /**
302  * @brief Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions
303  * for a given space dimension.
304  */
305  template<unsigned int dim>
306  void set_boundary_conditions();
307 
308  /**
309  * @brief Calculates the velocity field on a given @p dim dimensional cell.
310  *
311  * @param cell The cell.
312  * @param velocity The computed velocity field (at quadrature points).
313  * @param fv The FEValues class providing the quadrature points
314  * and the shape functions for velocity.
315  */
316  template<unsigned int dim>
317  void calculate_velocity(const ElementFullIter &cell, std::vector<arma::vec3> &velocity, FEValuesBase<dim,3> &fv);
318 
319  /**
320  * @brief Calculates the dispersivity (diffusivity) tensor from the velocity field.
321  *
322  * @param K The computed dispersivity tensor.
323  * @param velocity The velocity field (at quadrature points).
324  * @param Dm Molecular diffusivities.
325  * @param alphaL Longitudal dispersivities.
326  * @param alphaT Transversal dispersivities.
327  * @param porosity Porosities.
328  * @param cross_cut Cross-cuts of higher dimension.
329  */
330 // void calculate_dispersivity_tensor(arma::mat33 &K, const arma::vec3 &velocity,
331 // double Dm, double alphaL, double alphaT, double porosity,
332 // double cross_cut);
333 
334  /**
335  * @brief Sets up some parameters of the DG method for two sides of an edge.
336  *
337  * @param edg The edge.
338  * @param s1 Side 1.
339  * @param s2 Side 2.
340  * @param K_size Size of vector of tensors K.
341  * @param K1 Dispersivity tensors on side s1 (in quadrature points).
342  * @param K2 Dispersivity tensors on side s2 (in quadrature points).
343  * @param normal_vector Normal vector to side 0 of the neighbour
344  * (assumed constant along the side).
345  * @param alpha1, alpha2 Penalty parameter that influences the continuity
346  * of the solution (large value=more continuity).
347  * @param gamma Computed penalty parameters.
348  * @param omega Computed weights.
349  * @param transport_flux Computed flux from side s1 to side s2.
350  */
351  void set_DG_parameters_edge(const Edge &edg,
352  const int s1,
353  const int s2,
354  const int K_size,
355  const std::vector<arma::mat33> &K1,
356  const std::vector<arma::mat33> &K2,
357  const std::vector<double> &fluxes,
358  const arma::vec3 &normal_vector,
359  const double alpha1,
360  const double alpha2,
361  double &gamma,
362  double *omega,
363  double &transport_flux);
364 
365  /**
366  * @brief Sets up parameters of the DG method on a given boundary edge.
367  *
368  * Assumption is that the edge consists of only 1 side.
369  * @param side The boundary side.
370  * @param K_size Size of vector of tensors K.
371  * @param K Dispersivity tensor.
372  * @param ad_vector Advection vector.
373  * @param normal_vector Normal vector (assumed constant along the edge).
374  * @param alpha Penalty parameter that influences the continuity
375  * of the solution (large value=more continuity).
376  * @param gamma Computed penalty parameters.
377  */
378  void set_DG_parameters_boundary(const SideIter side,
379  const int K_size,
380  const std::vector<arma::mat33> &K,
381  const double flux,
382  const arma::vec3 &normal_vector,
383  const double alpha,
384  double &gamma);
385 
386 
387  /**
388  * @brief Sets the initial condition.
389  */
390  void set_initial_condition();
391 
392  /**
393  * @brief Assembles the auxiliary linear system to calculate the initial solution
394  * as L^2-projection of the prescribed initial condition.
395  */
396  template<unsigned int dim>
397  void prepare_initial_condition();
398 
399 
400 
401  /// @name Physical parameters
402  // @{
403 
404  /// Field data for model parameters.
406 
407  // @}
408 
409 
410  /// @name Parameters of the numerical method
411  // @{
412 
413  /// Finite element objects
415 
416  /// Penalty parameters.
418 
419  /// DG variant ((non-)symmetric/incomplete
421 
422  /// Polynomial order of finite elements.
423  unsigned int dg_order;
424 
425  // @}
426 
427 
428 
429  /// @name Solution of algebraic system
430  // @{
431 
432  /// Vector of right hand side.
434 
435  /// The stiffness matrix.
437 
438  /// The mass matrix.
440 
441  /// Mass from previous time instant (necessary when coefficients of mass matrix change in time).
443 
444  /// Auxiliary vectors for calculation of sources in balance due to retardation (e.g. sorption).
446 
447  /// Linear algebra system for the transport equation.
449 
450  /// Linear algebra system for the time derivative (actually it is used only for handling the matrix structures).
452 
453  /// Element averages of solution (the array is passed to reactions in operator splitting).
454  double **solution_elem_;
455 
456  // @}
457 
458 
459  /// @name Output to file
460  // @{
461 
462  /// Array for storing the output solution data.
463  //vector<double*> output_solution;
464 
465  /// Vector of solution data.
467 
468  /// Record with input specification.
470 
471 
472  // @}
473 
474 
475  /// @name Auxiliary fields used during assembly
476  // @{
477 
478  /// Mass matrix coefficients.
480  /// Retardation coefficient due to sorption.
482  /// Temporary values of increments due to retardation (e.g. sorption)
484  /// Advection coefficients.
486  /// Diffusion coefficients.
488  /// Advection coefficients on edges.
490  /// Diffusion coefficients on edges.
492 
493  // @}
494 
495 
496 
497 
498  /// @name Other
499  // @{
500 
501  /// Indicates whether matrices have been preallocated.
503 
504  // @}
505 };
506 
507 
508 
509 
510 
511 
512 #endif /* TRANSPORT_DG_HH_ */
Input::Record input_rec
Record with input specification.
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
int IdxInt
Define integers that are indices into large arrays (elements, nodes, dofs etc.)
Definition: mesh.h:85
vector< VectorSeqDouble > output_vec
Array for storing the output solution data.
FiniteElement< dim, 3 > * fe()
vector< double > mm_coef
Mass matrix coefficients.
MappingP1< 3, 3 > * map3_
Definition: transport_dg.hh:88
Transport with dispersion implemented using discontinuous Galerkin method.
Field< 3, FieldValue< 3 >::Integer > region_id
Quadrature< 1 > * q1_
Definition: transport_dg.hh:81
FiniteElement< 2, 3 > * fe_rt2_
Definition: transport_dg.hh:76
Wrappers for linear systems based on MPIAIJ and MATIS format.
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:62
FiniteElement< 2, 3 > * fe2_
Definition: transport_dg.hh:71
int dg_variant
DG variant ((non-)symmetric/incomplete.
Definition: mesh.h:99
FiniteElement< 3, 3 > * fe3_
Definition: transport_dg.hh:72
vector< vector< arma::vec3 > > ad_coef
Advection coefficients.
Definition: edges.h:26
std::shared_ptr< DOFHandlerMultiDim > dh()
vector< vector< vector< arma::mat33 > > > dif_coef_edg
Diffusion coefficients on edges.
const Vec & get_solution(unsigned int sbi)
vector< double > ret_sources_prev
MultiField< 3, FieldValue< 3 >::Scalar > dg_penalty
Penalty enforcing inter-element continuity of solution (for each substance).
Quadrature< 2 > * q2_
Definition: transport_dg.hh:82
EquationOutput output_fields
std::vector< Mat > mass_matrix
The mass matrix.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: fe_values.hh:32
vector< vector< double > > ret_coef
Retardation coefficient due to sorption.
vector< vector< vector< arma::vec3 > > > ad_coef_edg
Advection coefficients on edges.
double ** get_concentration_matrix()
MultiField< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures (for each substance).
vector< vector< arma::mat33 > > dif_coef
Diffusion coefficients.
FEObjects * feo
Finite element objects.
static const int registrar
Registrar of class to factory.
FiniteElement< 1, 3 > * fe_rt1_
Finite elements for the water velocity field.
Definition: transport_dg.hh:75
Abstract class for the mapping between reference and actual cell.
Definition: fe_values.hh:35
FiniteElement< 1, 3 > * fe1_
Finite elements for the solution of the advection-diffusion equation.
Definition: transport_dg.hh:70
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
Quadrature< 3 > * q3_
Definition: transport_dg.hh:83
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Definition: dofhandler.hh:268
std::vector< Vec > rhs
Vector of right hand side.
bool evaluate_time_constraint(double &time_constraint)
FiniteElement< dim, 3 > * fe_rt()
unsigned int dg_order
Polynomial order of finite elements.
The class for outputting data during time.
Definition: output_time.hh:44
MappingP1< 2, 3 > * map2_
Definition: transport_dg.hh:87
double ** solution_elem_
Element averages of solution (the array is passed to reactions in operator splitting).
Model::ModelEqData & data()
FiniteElement< 3, 3 > * fe_rt3_
Definition: transport_dg.hh:77
std::vector< Mat > stiffness_matrix
The stiffness matrix.
EqData data_
Field data for model parameters.
bool allocation_done
Indicates whether matrices have been preallocated.
std::vector< std::vector< double > > gamma
Penalty parameters.
MappingP1< dim, 3 > * mapping()
std::vector< Vec > ret_vec
Auxiliary vectors for calculation of sources in balance due to retardation (e.g. sorption).
Quadrature< dim > * q()
std::vector< Vec > mass_vec
Mass from previous time instant (necessary when coefficients of mass matrix change in time)...
Record type proxy class.
Definition: type_record.hh:182
Class for representation of a vector of fields of the same physical quantity.
Definition: multi_field.hh:55
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
Definition: dofhandler.hh:30
Base class for FEValues and FESideValues.
Definition: fe_values.hh:34
Field< 3, FieldValue< 3 >::Integer > subdomain
MappingP1< 1, 3 > * map1_
Auxiliary mappings of reference elements.
Definition: transport_dg.hh:86
LinSys ** ls
Linear algebra system for the transport equation.
LinSys ** ls_dt
Linear algebra system for the time derivative (actually it is used only for handling the matrix struc...
Template for classes storing finite set of named values.
Quadrature< 0 > * q0_
Quadratures used in assembling methods.
Definition: transport_dg.hh:80
std::shared_ptr< DOFHandlerMultiDim > dh_
Object for distribution of dofs.
Definition: transport_dg.hh:91
FEObjects(Mesh *mesh_, unsigned int fe_order)