Flow123d  release_2.2.0-36-g163dc99
darcy_flow_mh.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 darcy_flow_mh.hh
15  * @brief mixed-hybrid model of linear Darcy flow, possibly unsteady.
16  * @author Jan Brezina
17  *
18  * Main object for mixed-hybrid discretization of the linear elliptic PDE (Laplace)
19  * on a multidimensional domain. Discretization of saturated Darcy flow using
20  * RT0 approximation for the velocity
21  */
22 
23 /*
24  * list of files dependent on this one:
25  *
26  * posprocess.cc
27  * problem.cc
28  * main.hh
29  * transport.cc
30  */
31 
32 
33 #ifndef DARCY_FLOW_MH_HH
34 #define DARCY_FLOW_MH_HH
35 
36 #include <memory>
38 
39 #include <petscmat.h>
40 #include "system/sys_vector.hh"
41 #include "coupling/equation.hh"
42 #include "flow/mh_dofhandler.hh"
43 #include "la/linsys_BDDC.hh"
44 #include "la/linsys_PETSC.hh"
45 
46 #include "fields/bc_field.hh"
47 #include "fields/field.hh"
48 #include "fields/field_set.hh"
50 #include "input/input_exception.hh"
51 
52 /// external types:
53 class LinSys;
54 class Mesh;
55 class SchurComplement;
56 class Distribution;
57 class SparseGraph;
58 class LocalToGlobalMap;
59 class DarcyFlowMHOutput;
60 class Balance;
61 class VectorSeqDouble;
62 class AssemblyBase;
63 
64 template<unsigned int dim, unsigned int spacedim> class FE_RT0;
65 template<unsigned int degree, unsigned int dim, unsigned int spacedim> class FE_P_disc;
66 template<unsigned int dim, unsigned int spacedim> class MappingP1;
67 template<unsigned int dim, unsigned int spacedim> class FEValues;
68 template<unsigned int dim, unsigned int spacedim> class FESideValues;
69 template<unsigned int dim> class QGauss;
70 
71 /**
72  * @brief Mixed-hybrid model of linear Darcy flow, possibly unsteady.
73  *
74  * Abstract class for various implementations of Darcy flow. In future there should be
75  * one further level of abstraction for general time dependent problem.
76  *
77  * maybe TODO:
78  * split compute_one_step to :
79  * 1) prepare_next_timestep
80  * 2) actualize_solution - this is for iterative nonlinear solvers
81  *
82  */
83 
84 
85 /**
86  * This should contain target large algebra object to be assembled.
87  * Since this should be passed only once per the whole assembly and may be equation specific
88  * this structure is passed with the data
89  */
91 public:
92  // temporary solution how to pass information about dirichlet BC on edges
93  // should be done better when we move whole assembly into assembly classes
94  // the vector is set in assembly_mh_matrix and used in LMH assembly of the time term
96  std::shared_ptr<arma::mat> local_matrix;
97  double loc_side_rhs[4];
98  std::shared_ptr<Balance> balance;
100 };
101 
102 
103 /**
104  * @brief Mixed-hybrid of steady Darcy flow with sources and variable density.
105  *
106  * solve equations:
107  * @f[
108  * q= -{\mathbf{K}} \nabla h -{\mathbf{K}} R \nabla z
109  * @f]
110  * @f[
111  * \mathrm{div} q = f
112  * @f]
113  *
114  * where
115  * - @f$ q @f$ is flux @f$[ms^{-1}]@f$ for 3d, @f$[m^2s^{-1}]@f$ for 2d and @f$[m^3s^{-1}]@f$ for 1d.
116  * - @f$ \mathbf{K} @f$ is hydraulic tensor ( its orientation for 2d, 1d case is questionable )
117  * - @f$ h = \frac{\pi}{\rho_0 g}+z @f$ is pressure head, @f$ \pi, \rho_0, g @f$ are the pressure, water density, and acceleration of gravity , respectively.
118  * Assumes gravity force acts counter to the direction of the @f$ z @f$ axis.
119  * - @f$ R @f$ is destity or gravity variability coefficient. For density driven flow it should be
120  * @f[
121  * R = \frac{\rho}{\rho_0} -1 = \rho_0^{-1}\sum_{i=1}^s c_i
122  * @f]
123  * where @f$ c_i @f$ is concentration in @f$ kg m^{-3} @f$.
124  *
125  * The time key is optional, when not specified the equation is forced to steady regime. Using Steady TimeGovernor which have no dt constraints.
126  *
127  *
128  * TODO:
129  * Make solution regular field (need FeSeystem and parallel DofHandler for edge pressures), then remove get_solution_vector from
130  * Equation interface.
131  */
132 /**
133  * Model for transition coefficients due to Martin, Jaffre, Roberts (see manual for full reference)
134  *
135  * TODO:
136  * - how we can reuse field values computed during assembly
137  *
138  */
139 
141 {
142 public:
143  TYPEDEF_ERR_INFO( EI_Reason, string);
144  DECLARE_EXCEPTION(ExcSolverDiverge,
145  << "Diverged nonlinear solver. Reason: " << EI_Reason::val
146  );
147  DECLARE_INPUT_EXCEPTION(ExcMissingTimeGovernor,
148  << "Missing the key 'time', obligatory for the transient problems.");
149 
151 
152  /// Class with all fields used in the equation DarcyFlow.
153  /// This is common to all implementations since this provides interface
154  /// to this equation for possible coupling.
155  class EqData : public FieldSet {
156  public:
157 
158  /**
159  * For compatibility with old BCD file we have to assign integer codes starting from 1.
160  */
161  enum BC_Type {
162  none=0,
163  dirichlet=1,
164  total_flux=4,
165  seepage=5,
166  river=6
167  };
168 
169  /// Return a Selection corresponding to enum BC_Type.
170  static const Input::Type::Selection & get_bc_type_selection();
171 
172  /// Creation of all fields.
173  EqData();
174 
175 
181 
182  BCField<3, FieldValue<3>::Enum > bc_type; // Discrete need Selection for initialization
187 
190 
191  /**
192  * Gravity vector and constant shift of pressure potential. Used to convert piezometric head
193  * to pressure head and vice versa.
194  */
195  arma::vec4 gravity_;
197 
200 
203 
204 
205  //FieldSet time_term_fields;
206  //FieldSet main_matrix_fields;
207  //FieldSet rhs_fields;
208  };
209 
210  /// Type of experimental Mortar-like method for non-compatible 1d-2d interaction.
212  NoMortar = 0,
213  MortarP0 = 1,
214  MortarP1 = 2
215  };
216  /// Selection for enum MortarMethod.
217  static const Input::Type::Selection & get_mh_mortar_selection();
218 
219 
220 
221 
222 
223  DarcyMH(Mesh &mesh, const Input::Record in_rec);
224 
225  static const Input::Type::Record & type_field_descriptor();
226  static const Input::Type::Record & get_input_type();
227 
228  const MH_DofHandler &get_mh_dofhandler() override {
229  double *array;
230  unsigned int size;
231  get_solution_vector(array, size);
232 
233  // here assume that velocity field is extended as constant
234  // to the previous time, so here we set left bound of the interval where the velocity
235  // has current value; this may not be good for every transport !!
236  // we can resolve this when we use FieldFE to store computed velocities in few last steps and
237  // let every equation set time according to nature of the time scheme
238 
239  // in particular this setting is necessary to prevent ConvectinTransport to recreate the transport matrix
240  // every timestep ( this may happen for unsteady flow if we would use time->t() here since it returns infinity.
241  mh_dh.set_solution(time_->last_t(), array, solution_precision());
242  return mh_dh;
243  }
244 
245  void init_eq_data();
246  void initialize() override;
247  virtual void initialize_specific();
248  void zero_time_step() override;
249  void update_solution() override;
250 
251  void get_solution_vector(double * &vec, unsigned int &vec_size) override;
252  void get_parallel_solution_vector(Vec &vector) override;
253 
254  /// postprocess velocity field (add sources)
255  virtual void prepare_new_time_step();
256  virtual void postprocess();
257  virtual void output_data() override;
258 
259  virtual ~DarcyMH() override;
260 
261 
262 protected:
263  /**
264  * Returns true is the fields involved in the time term have values that makes the time term zero.
265  * For time_global==true, it returns true if there are no field descriptors in the input list, so the
266  * fields )of the time ter) have their default values for whole simulation.
267  * If time_global==false (default), only the actual values are considered.
268  */
269  virtual bool zero_time_term(bool time_global=false);
270 
271  /// Solve method common to zero_time_step and update solution.
272  void solve_nonlinear();
273  void make_serial_scatter();
274  void modify_system();
275  virtual void setup_time_term();
276 
277 
278  //void prepare_parallel();
279  //void make_row_numberings();
280  /// Initialize global_row_4_sub_row.
281  //void prepare_parallel_bddc();
282 
283  /**
284  * Create and preallocate MH linear system (including matrix, rhs and solution vectors)
285  */
286  void create_linear_system(Input::AbstractRecord rec);
287 
288  /**
289  * Read initial condition into solution vector.
290  * Must be called after create_linear_system.
291  *
292  * For the LMH scheme we have to be able to save edge pressures in order to
293  * restart simulation or use results of one simulation as initial condition for other one.
294  */
295  virtual void read_initial_condition();
296 
297  /**
298  * Part of per element assembly that is specific for MH and LMH respectively.
299  *
300  * This implemnets MH case:
301  * - compute conductivity scaling
302  * - assembly source term
303  * - no time term, managed by diagonal extraction etc.
304  */
305  //virtual void local_assembly_specific(AssemblyData &local_data);
306 
307  /**
308  * Abstract assembly method used for both assembly and preallocation.
309  * Assembly only steady part of the equation.
310  * TODO:
311  * - use general preallocation methods in DofHandler
312  * - include time term
313  * - add support for Robin type sources
314  * - support for nonlinear solvers - assembly either residual vector, matrix, or both (using FADBAD++)
315  */
316  void assembly_mh_matrix( MultidimAssembler ma);
317 
318 
319  /// Source term is implemented differently in LMH version.
320  virtual void assembly_source_term();
321 
322  /**
323  * Assembly or update whole linear system.
324  */
325  virtual void assembly_linear_system();
326 
327  void set_mesh_data_for_bddc(LinSys_BDDC * bddc_ls);
328  /**
329  * Return a norm of residual vector.
330  * TODO: Introduce Equation::compute_residual() updating
331  * residual field, standard part of EqData.
332  */
333  virtual double solution_precision() const;
334 
336  //Vec velocity_vector;
337  MH_DofHandler mh_dh; // provides access to seq. solution fluxes and pressures on sides
338 
340 
341  std::shared_ptr<Balance> balance_;
342  /// index of water balance within the Balance object.
343  unsigned int water_balance_idx_;
344 
346 
347  int size; // global size of MH matrix
348  int n_schur_compls; // number of shur complements to make
349  double *solution; // sequantial scattered solution vector
350  int is_linear_; // Hack fo BDDC solver.
351 
352  // Propagate test for the time term to the assembly.
353  // This flag is necessary for switching BC to avoid setting zero neumann on the whole boundary in the steady case.
356 
357  // Setting of the nonlinear solver. TODO: Move to the solver class later on.
358  double tolerance_;
359  unsigned int min_n_it_;
360  unsigned int max_n_it_;
361  unsigned int nonlinear_iteration_; //< Actual number of completed nonlinear iterations, need to pass this information into assembly.
362 
363 
364  LinSys *schur0; //< whole MH Linear System
365 
366 
367 
368 
369 
370  /// Idicator of dirichlet or neumann type of switch boundary conditions.
372 
373 
374  // gather of the solution
375  Vec sol_vec; //< vector over solution array
376  VecScatter par_to_all;
377 
382 
383  std::shared_ptr<EqData> data_;
384 
385  friend class DarcyFlowMHOutput;
386  friend class P0_CouplingAssembler;
387  friend class P1_CouplingAssembler;
388 
389 private:
390  /// Registrar of class to factory
391  static const int registrar;
392 };
393 
394 
396 public:
398  : darcy_(darcy),
399  master_list_(darcy.mesh_->master_elements),
400  intersections_(darcy.mesh_->intersections),
401  master_(nullptr),
402  tensor_average(2)
403  {
404  arma::mat master_map(1,2), slave_map(1,3);
405  master_map.fill(1.0 / 2);
406  slave_map.fill(1.0 / 3);
407 
408  tensor_average[0].push_back( master_map.t() * master_map );
409  tensor_average[0].push_back( master_map.t() * slave_map );
410  tensor_average[1].push_back( slave_map.t() * master_map );
411  tensor_average[1].push_back( slave_map.t() * slave_map );
412  }
413 
414  void assembly(LinSys &ls);
415  void pressure_diff(int i_ele,
416  vector<int> &dofs,
417  unsigned int &ele_type,
418  double &delta,
419  arma::vec &dirichlet);
420 private:
422 
423  const DarcyMH &darcy_;
424 
427 
429  const Element *master_;
430 
431  /// Row matrices to compute element pressure as average of boundary pressures
433  /// measure of master element, should be sum of intersection measures
434  double delta_0;
435 };
436 
437 
438 
440 public:
442  : darcy_(darcy),
443  intersections_(darcy.mesh_->intersections),
444  rhs(5),
445  dofs(5),
446  dirichlet(5)
447  {
448  rhs.zeros();
449  }
450 
451  void assembly(LinSys &ls);
452  void add_sides(const Element * ele, unsigned int shift, vector<int> &dofs, vector<double> &dirichlet);
453 private:
454 
455  const DarcyMH &darcy_;
457 
458  arma::vec rhs;
461 };
462 
463 
464 
465 void mat_count_off_proc_values(Mat m, Vec v);
466 
467 
468 
469 /**
470  * @brief Mixed-hybrid solution of unsteady Darcy flow.
471  *
472  * Standard discretization with time term and sources picewise constant
473  * on the element. This leads to violation of the discrete maximum principle for
474  * non-acute meshes or to too small timesteps. For simplicial meshes this can be solved by lumping to the edges. See DarcyFlowLMH_Unsteady.
475  */
476 /*
477 class DarcyFlowMH_Unsteady : public DarcyFlowMH_Steady
478 {
479 public:
480 
481  DarcyFlowMH_Unsteady(Mesh &mesh, const Input::Record in_rec);
482  //DarcyFlowMH_Unsteady();
483 
484  static const Input::Type::Record & get_input_type();
485 protected:
486  void read_initial_condition() override;
487  void modify_system() override;
488  void setup_time_term();
489 
490 private:
491  /// Registrar of class to factory
492  static const int registrar;
493 
494 
495 };
496 */
497 
498 #endif //DARCY_FLOW_MH_HH
499 //-----------------------------------------------------------------------------
500 // vim: set cindent:
501 
Abstract base class for equation clasess.
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:61
Field< 3, FieldValue< 3 >::Scalar > init_pressure
MH_DofHandler * mh_dh
unsigned int uint
int is_linear_
Solver based on the original PETSc solver using MPIAIJ matrix and succesive Schur complement construc...
std::vector< unsigned int > dirichlet_edge
vector< vector< arma::mat > > tensor_average
Row matrices to compute element pressure as average of boundary pressures.
arma::vec3 gravity_vec_
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:62
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:158
static const int registrar
Registrar of class to factory.
unsigned int max_n_it_
VecScatter par_to_all
Field< 3, FieldValue< 3 >::Scalar > sigma
Vec steady_rhs
Definition: mesh.h:97
std::vector< char > bc_switch_dirichlet
Idicator of dirichlet or neumann type of switch boundary conditions.
arma::vec4 gravity_
vector< IsecList >::const_iterator ml_it_
P1_CouplingAssembler(const DarcyMH &darcy)
vector< double > dirichlet
RichardsSystem system_
LinSys * lin_sys
P0_CouplingAssembler(const DarcyMH &darcy)
bool solution_changed_for_scatter
std::shared_ptr< EqData > data_
void mat_count_off_proc_values(Mat m, Vec v)
class to manage local indices on sub-domain to global indices on domain
MortarMethod mortar_method_
vector< unsigned int > IsecList
Symmetric Gauss-Legendre quadrature formulae on simplices.
unsigned int min_n_it_
unsigned int nonlinear_iteration_
const DarcyMH & darcy_
BCField< 3, FieldValue< 3 >::Scalar > bc_flux
Discontinuous Lagrangean finite element on dim dimensional simplex.
Definition: fe_p.hh:202
std::shared_ptr< arma::mat > local_matrix
BCField< 3, FieldValue< 3 >::Scalar > bc_pressure
Field< 3, FieldValue< 3 >::Scalar > water_source_density
BCField< 3, FieldValue< 3 >::Scalar > bc_switch_pressure
Field< 3, FieldValue< 3 >::Scalar > storativity
std::shared_ptr< Balance > balance_
Virtual class for construction and partitioning of a distributed sparse graph.
Definition: sparse_graph.hh:54
int n_schur_compls
double loc_side_rhs[4]
Raviart-Thomas element of order 0.
Definition: fe_rt.hh:33
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
bool data_changed_
double * solution
const vector< IsecList > & master_list_
bool use_steady_assembly_
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:194
Affine mapping between reference and actual cell.
Definition: mapping_p1.hh:53
Mixed-hybrid model of linear Darcy flow, possibly unsteady.
const vector< Intersection > & intersections_
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:459
LinSys * schur0
const vector< Intersection > & intersections_
const DarcyMH & darcy_
#define DECLARE_INPUT_EXCEPTION(ExcName, Format)
Macro for simple definition of input exceptions.
double delta_0
measure of master element, should be sum of intersection measures
MH_DofHandler mh_dh
MortarMethod
Type of experimental Mortar-like method for non-compatible 1d-2d interaction.
std::shared_ptr< Balance > balance
Vector classes to support both Iterator, index and Id access and creating co-located vectors...
Vec steady_diagonal
Field< 3, FieldValue< 3 >::TensorFixed > anisotropy
unsigned int water_balance_idx_
index of water balance within the Balance object.
Abstract linear system class.
Calculates finite element data on the actual cell.
Definition: fe_values.hh:416
std::vector< std::shared_ptr< AssemblyBase > > MultidimAssembler
Record type proxy class.
Definition: type_record.hh:182
Field< 3, FieldValue< 3 >::Scalar > cross_section
BCField< 3, FieldValue< 3 >::Enum > bc_type
DarcyFlowMHOutput * output_object
Field< 3, FieldValue< 3 >::Scalar > conductivity
Vec new_diagonal
BCField< 3, FieldValue< 3 >::Scalar > bc_robin_sigma
Vec previous_solution
Template for classes storing finite set of named values.
double tolerance_
Solver based on Multilevel BDDC - using corresponding class of OpenFTL package.
const Element * master_
const MH_DofHandler & get_mh_dofhandler() override
Calculates finite element data on a side.
Definition: fe_values.hh:461
Mixed-hybrid of steady Darcy flow with sources and variable density.