Flow123d
transport_dg.hh
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 #ifndef TRANSPORT_DG_HH_
31 #define TRANSPORT_DG_HH_
32 
34 #include "la/linsys.hh"
35 #include "flow/mh_dofhandler.hh"
36 
37 class Distribution;
38 class OutputTime;
39 class DOFHandlerBase;
40 class DOFHandlerMultiDim;
41 template<unsigned int dim, unsigned int spacedim> class FEValuesBase;
42 template<unsigned int dim, unsigned int spacedim> class FiniteElement;
43 template<unsigned int dim, unsigned int spacedim> class Mapping;
44 template<unsigned int dim> class Quadrature;
45 
46 
47 
48 /**
49  * Auxiliary container class for Finite element and related objects of all dimensions.
50  * Its purpose is to provide templated access to these objects, applicable in
51  * the assembling methods.
52  */
53 class FEObjects {
54 public:
55 
56  FEObjects(Mesh *mesh_, unsigned int fe_order);
57  ~FEObjects();
58 
59  template<unsigned int dim>
60  inline FiniteElement<dim,3> *fe();
61 
62  template<unsigned int dim>
63  inline FiniteElement<dim,3> *fe_rt();
64 
65  template<unsigned int dim>
66  inline Quadrature<dim> *q();
67 
68  template<unsigned int dim>
69  inline Mapping<dim,3> *mapping();
70 
71  inline DOFHandlerMultiDim *dh();
72 
73 private:
74 
75  /// Finite elements for the solution of the advection-diffusion equation.
79 
80  /// Finite elements for the water velocity field.
84 
85  /// Quadratures used in assembling methods.
90 
91  /// Auxiliary mappings of reference elements.
96 
97  /// Object for distribution of dofs.
99 };
100 
101 
102 
103 /**
104  * @brief Transport with dispersion implemented using discontinuous Galerkin method.
105  *
106  * TransportDG implements the discontinuous Galerkin method for the transport and diffusion of substances.
107  * The concentration @f$ c_i ~[kg/m^3]@f$ of the i-th substance is governed by the advection-diffusion equation
108  * @f[
109  * \partial_t c_i + \mathbf v\cdot\nabla c_i - \mathrm{div}(D\nabla c_i) = F \mbox{ in }\Omega^d,
110  * @f]
111  * where @f$\mathbf v@f$ is the fluid velocity and @f$\Omega^d@f$ the @f$d@f$-dimensional domain, respectively.
112  * The hydrodynamic dispersivity tensor @f$\mathbf D ~[m^2/s]@f$ is given by:
113  * @f[
114  * \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).
115  * @f]
116  * 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.
117  *
118  * 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$.
119  *
120  * 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$.
121  * We prescribe the following boundary conditions:
122  * @f{eqnarray*}{
123  * c_i^d &= c_{iD}^d &\mbox{ on }\Gamma^d_D \mbox{ (Dirichlet)},\\
124  * \mathbf D^d\nabla c_i^d\cdot\mathbf n &= 0 &\mbox{ on }\Gamma^d_N \mbox{ (Neumann)},
125  * @f}
126  * The transfer of mass through fractures is described by the transmission conditions on @f$\Gamma^d_F@f$:
127  * @f[
128  * -\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
129  * F^{d-1} = (\sigma + |\mathbf v^d\cdot\mathbf n|)(c_i^d-c_i^{d-1}).
130  * @f]
131  * Here @f$\mathbf n@f$ stands for the unit outward normal vector to @f$\partial\Omega^d@f$.
132  * The coefficient @f$\sigma@f$ determines the transfer of mass through fractures due to diffusion.
133  *
134  * @ingroup transport_mod
135  *
136  */
137 template<class Model>
138 class TransportDG : public TransportBase, public Model
139 {
140 public:
141 
142  class EqData : public Model::ModelEqData {
143  public:
144 
145  enum BC_Type {
150  };
152 
154 
155  EqData();
156 
157  Field<3, FieldValue<3>::Vector> fracture_sigma; ///< Transition parameter for diffusive transfer on fractures (for each substance).
158  Field<3, FieldValue<3>::Vector> dg_penalty; ///< Penalty enforcing inter-element continuity of solution (for each substance).
159 
163 
164  };
165 
166 
167 
168  enum DGVariant {
169  // Non-symmetric weighted interior penalty DG
171 
172  // Incomplete weighted interior penalty DG
174 
175  // Symmetric weighted interior penalty DG
177  };
178 
179  /**
180  * @brief Constructor.
181  * @param init_mesh computational mesh
182  * @param in_rec input record
183  */
184  TransportDG(Mesh &init_mesh, const Input::Record &in_rec);
185  /**
186 
187  * @brief Declare input record type for the equation TransportDG.
188  */
190 
191  /**
192  * @brief Input type for the DG variant selection.
193  */
195 
196  /**
197  * @brief Initialize solution in the zero time.
198  */
199  void zero_time_step() override;
200 
201  /**
202  * @brief Computes the solution in one time instant.
203  */
204  void update_solution() override;
205 
206  /**
207  * @brief Updates the velocity field which determines some coefficients of the transport equation.
208  *
209  * @param dh mixed hybrid dof handler
210  *
211  * (So far it does not work since the flow module returns a vector of zeros.)
212  * @param velocity_vector Input array of velocity values.
213  */
214  virtual void set_velocity_field(const MH_DofHandler &dh);
215 
216  /**
217  * @brief Postprocesses the solution and writes to output file.
218  */
219  void output_data();
220 
221  /**
222  * @brief Sets pointer to data of other equations.
223  * TODO: there should be also passed the sigma parameter between dimensions
224  * @param cross_section is pointer to cross_section data of Darcy flow equation
225  */
226  //void set_cross_section_field(const Field< 3, FieldValue<3>::Scalar > &cross_section) { Model::set_cross_section_field(cross_section); }
227 
228  /**
229  * @brief Getter for field data.
230  */
231  virtual EqData *get_data() { return &data_; }
232 
234 
235  /**
236  * @brief Destructor.
237  */
238  ~TransportDG();
239 
240 private:
241 
242  typename Model::ModelEqData &data() { return data_; }
243 
244  void output_vector_gather();
245 
247  return Model::stiffness_matrix_changed() ||
250  }
251 
252  bool mass_matrix_changed() { return Model::mass_matrix_changed(); }
253 
254  bool rhs_changed() {
255  return Model::rhs_changed() ||
257  }
258 
259  /**
260  * @brief Assembles the mass matrix.
261  *
262  * The routine just calls templated method assemble_mass_matrix() for each
263  * space dimension.
264  */
265  void assemble_mass_matrix();
266 
267  /**
268  * @brief Assembles the mass matrix for the given dimension.
269  */
270  template<unsigned int dim>
271  void assemble_mass_matrix();
272 
273  /**
274  * @brief Assembles the stiffness matrix.
275  *
276  * This routine just calls assemble_volume_integrals(), assemble_fluxes_boundary(),
277  * assemble_fluxes_element_element() and assemble_fluxes_element_side() for each
278  * space dimension.
279  */
281 
282  /**
283  * @brief Assembles the volume integrals into the stiffness matrix.
284  */
285  template<unsigned int dim>
287 
288  /**
289  * @brief Assembles the right hand side due to volume sources.
290  *
291  * This method just calls set_sources() for each space dimension.
292  */
293  void set_sources();
294 
295  /**
296  * @brief Assembles the right hand side vector due to volume sources.
297  */
298  template<unsigned int dim>
299  void set_sources();
300 
301  /**
302  * @brief Assembles the fluxes on the boundary.
303  */
304  template<unsigned int dim>
306 
307  /**
308  * @brief Assembles the fluxes between elements of the same dimension.
309  */
310  template<unsigned int dim>
312 
313  /**
314  * @brief Assembles the fluxes between elements of different dimensions.
315  */
316  template<unsigned int dim>
318 
319 
320  /**
321  * @brief Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions.
322  *
323  * The routine just calls templated method set_boundary_condition() for each space dimension.
324  */
326 
327  /**
328  * @brief Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions
329  * for a given space dimension.
330  */
331  template<unsigned int dim>
333 
334  /**
335  * @brief Calculates the velocity field on a given @p dim dimensional cell.
336  *
337  * @param cell The cell.
338  * @param velocity The computed velocity field (at quadrature points).
339  * @param fv The FEValues class providing the quadrature points
340  * and the shape functions for velocity.
341  */
342  template<unsigned int dim>
344 
345  /**
346  * @brief Calculates the dispersivity (diffusivity) tensor from the velocity field.
347  *
348  * @param K The computed dispersivity tensor.
349  * @param velocity The velocity field (at quadrature points).
350  * @param Dm Molecular diffusivities.
351  * @param alphaL Longitudal dispersivities.
352  * @param alphaT Transversal dispersivities.
353  * @param porosity Porosities.
354  * @param cross_cut Cross-cuts of higher dimension.
355  */
356  void calculate_dispersivity_tensor(arma::mat33 &K, const arma::vec3 &velocity,
357  double Dm, double alphaL, double alphaT, double porosity,
358  double cross_cut);
359 
360  /**
361  * @brief Sets up some parameters of the DG method for two sides of an edge.
362  *
363  * @param edg The edge.
364  * @param s1 Side 1.
365  * @param s2 Side 2.
366  * @param K_size Size of vector of tensors K.
367  * @param K1 Dispersivity tensors on side s1 (in quadrature points).
368  * @param K2 Dispersivity tensors on side s2 (in quadrature points).
369  * @param normal_vector Normal vector to side 0 of the neighbour
370  * (assumed constant along the side).
371  * @param alpha1, alpha2 Penalty parameter that influences the continuity
372  * of the solution (large value=more continuity).
373  * @param gamma Computed penalty parameters.
374  * @param omega Computed weights.
375  * @param transport_flux Computed flux from side s1 to side s2.
376  */
377  void set_DG_parameters_edge(const Edge &edg,
378  const int s1,
379  const int s2,
380  const int K_size,
381  const std::vector<arma::mat33> &K1,
382  const std::vector<arma::mat33> &K2,
383  const std::vector<double> &fluxes,
384  const arma::vec3 &normal_vector,
385  const double alpha1,
386  const double alpha2,
387  double &gamma,
388  double *omega,
389  double &transport_flux);
390 
391  /**
392  * @brief Sets up parameters of the DG method on a given boundary edge.
393  *
394  * Assumption is that the edge consists of only 1 side.
395  * @param side The boundary side.
396  * @param K_size Size of vector of tensors K.
397  * @param K Dispersivity tensor.
398  * @param ad_vector Advection vector.
399  * @param normal_vector Normal vector (assumed constant along the edge).
400  * @param alpha Penalty parameter that influences the continuity
401  * of the solution (large value=more continuity).
402  * @param gamma Computed penalty parameters.
403  */
404  void set_DG_parameters_boundary(const SideIter side,
405  const int K_size,
406  const std::vector<arma::mat33> &K,
407  const double flux,
408  const arma::vec3 &normal_vector,
409  const double alpha,
410  double &gamma);
411 
412 
413  /**
414  * @brief Sets the initial condition.
415  */
416  void set_initial_condition();
417 
418  /**
419  * @brief Assembles the auxiliary linear system to calculate the initial solution
420  * as L^2-projection of the prescribed initial condition.
421  */
422  template<unsigned int dim>
424 
425  /**
426  * @brief Calculates flux through boundary of each region.
427  *
428  * This actually calls calc_fluxes<dim>() for each space dimension.
429  * @param bcd_balance Total fluxes.
430  * @param bcd_plus_balance Incoming fluxes.
431  * @param bcd_minus_balance Outgoing fluxes.
432  */
433  void calc_fluxes(vector<vector<double> > &bcd_balance, vector<vector<double> > &bcd_plus_balance, vector<vector<double> > &bcd_minus_balance);
434 
435  /**
436  * @brief Calculates flux through boundary of each region of specific dimension.
437  * @param bcd_balance Total fluxes.
438  * @param bcd_plus_balance Incoming fluxes.
439  * @param bcd_minus_balance Outgoing fluxes.
440  */
441  template<unsigned int dim>
442  void calc_fluxes(vector<vector<double> > &bcd_balance, vector<vector<double> > &bcd_plus_balance, vector<vector<double> > &bcd_minus_balance);
443 
444  /**
445  * @brief Calculates volume sources for each region.
446  *
447  * This method actually calls calc_elem_sources<dim>() for each space dimension.
448  * @param mass Vector of substance mass per region.
449  * @param src_balance Vector of sources per region.
450  */
451  void calc_elem_sources(vector<vector<double> > &mass, vector< vector<double> > &src_balance);
452 
453  /**
454  * @brief Calculates volume sources for each region of specific dimension.
455  * @param mass Vector of substance mass per region.
456  * @param src_balance Vector of sources per region.
457  */
458  template<unsigned int dim>
459  void calc_elem_sources(vector<vector<double> > &mass, vector< vector<double> > &src_balance);
460 
461 
462 
463  /// @name Physical parameters
464  // @{
465 
466  /// Field data for model parameters.
468 
469  // @}
470 
471 
472  /// @name Parameters of the numerical method
473  // @{
474 
475  /// Finite element objects
477 
478  /// Penalty parameters.
480 
481  /// DG variant ((non-)symmetric/incomplete
483 
484  /// Polynomial order of finite elements.
485  unsigned int dg_order;
486 
487  // @}
488 
489 
490 
491  /// @name Solution of algebraic system
492  // @{
493 
494  /// Vector of right hand side.
495  Vec *rhs;
496 
497  /// The stiffness matrix.
499 
500  /// The mass matrix.
502 
503  /// Linear algebra system for the transport equation.
505 
506  /// Linear algebra system for the time derivative (actually it is used only for handling the matrix structures).
508 
509  // @}
510 
511 
512  /// @name Output to file
513  // @{
514 
515  /// Array for storing the output solution data.
517 
518  /// Vector of solution data.
520 
521  /// Record with output specification.
523 
525 
526 
527  // @}
528 
529 
530  /// @name Auxiliary fields used during assembly
531  // @{
532 
533  /// Mass matrix coefficients.
535  /// Advection coefficients.
537  /// Diffusion coefficients.
539  /// Advection coefficients on edges.
541  /// Diffusion coefficients on edges.
543 
544  // @}
545 
546 
547 
548 
549  /// @name Other
550  // @{
551 
552  /// Indicates whether matrices have been preallocated.
554 
555  // @}
556 };
557 
558 
559 
560 
561 
562 
563 #endif /* TRANSPORT_DG_HH_ */