Flow123d  release_1.8.2-1603-g0109a2b
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 
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 
63 template<unsigned int dim, unsigned int spacedim> class FE_RT0;
64 template<unsigned int degree, unsigned int dim, unsigned int spacedim> class FE_P_disc;
65 template<unsigned int dim, unsigned int spacedim> class MappingP1;
66 template<unsigned int dim, unsigned int spacedim> class FEValues;
67 template<unsigned int dim, unsigned int spacedim> class FESideValues;
68 template<unsigned int dim> class QGauss;
69 
70 /**
71  * @brief Mixed-hybrid model of linear Darcy flow, possibly unsteady.
72  *
73  * Abstract class for various implementations of Darcy flow. In future there should be
74  * one further level of abstraction for general time dependent problem.
75  *
76  * maybe TODO:
77  * split compute_one_step to :
78  * 1) prepare_next_timestep
79  * 2) actualize_solution - this is for iterative nonlinear solvers
80  *
81  */
82 
83 
84 /**
85  * @brief Mixed-hybrid of steady Darcy flow with sources and variable density.
86  *
87  * solve equations:
88  * @f[
89  * q= -{\mathbf{K}} \nabla h -{\mathbf{K}} R \nabla z
90  * @f]
91  * @f[
92  * \mathrm{div} q = f
93  * @f]
94  *
95  * where
96  * - @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.
97  * - @f$ \mathbf{K} @f$ is hydraulic tensor ( its orientation for 2d, 1d case is questionable )
98  * - @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.
99  * Assumes gravity force acts counter to the direction of the @f$ z @f$ axis.
100  * - @f$ R @f$ is destity or gravity variability coefficient. For density driven flow it should be
101  * @f[
102  * R = \frac{\rho}{\rho_0} -1 = \rho_0^{-1}\sum_{i=1}^s c_i
103  * @f]
104  * where @f$ c_i @f$ is concentration in @f$ kg m^{-3} @f$.
105  *
106  * The time key is optional, when not specified the equation is forced to steady regime. Using Steady TimeGovernor which have no dt constraints.
107  *
108  *
109  * TODO:
110  * Make solution regular field (need FeSeystem and parallel DofHandler for edge pressures), then remove get_solution_vector from
111  * Equation interface.
112  */
113 /**
114  * Model for transition coefficients due to Martin, Jaffre, Roberts (see manual for full reference)
115  *
116  * TODO:
117  * - how we can reuse field values computed during assembly
118  *
119  */
120 
122 {
123 public:
124  TYPEDEF_ERR_INFO( EI_Reason, string);
125  DECLARE_EXCEPTION(ExcSolverDiverge,
126  << "Diverged nonlinear solver. Reason: " << EI_Reason::val
127  );
128 
129  /// Class with all fields used in the equation DarcyFlow.
130  /// This is common to all implementations since this provides interface
131  /// to this equation for possible coupling.
132  class EqData : public FieldSet {
133  public:
134 
135  /**
136  * For compatibility with old BCD file we have to assign integer codes starting from 1.
137  */
138  enum BC_Type {
139  none=0,
141  //neumann=2,
142  //robin=3,
146  };
147 
148  /// Return a Selection corresponding to enum BC_Type.
150 
151  /// Creation of all fields.
152  EqData();
153 
154 
160 
161  BCField<3, FieldValue<3>::Enum > bc_type; // Discrete need Selection for initialization
166 
169 
170  /**
171  * Gravity vector and constant shift of pressure potential. Used to convert piezometric head
172  * to pressure head and vice versa.
173  */
174  arma::vec4 gravity_;
175 
176  //FieldSet time_term_fields;
177  //FieldSet main_matrix_fields;
178  //FieldSet rhs_fields;
179  };
180 
181  /// Type of experimental Mortar-like method for non-compatible 1d-2d interaction.
183  NoMortar = 0,
184  MortarP0 = 1,
186  };
187  /// Selection for enum MortarMethod.
189 
190 
191 
192 
193 
194 
195 
196 
197  DarcyFlowMH_Steady(Mesh &mesh, const Input::Record in_rec);
198 
199  static const Input::Type::Record & get_input_type();
200 
202  double *array;
203  unsigned int size;
204  get_solution_vector(array, size);
205 
206  // here assume that velocity field is extended as constant
207  // to the previous time, so here we set left bound of the interval where the velocity
208  // has current value; this may not be good for every transport !!
209  // we can resolve this when we use FieldFE to store computed velocities in few last steps and
210  // let every equation set time according to nature of the time scheme
211 
212  // in particular this setting is necessary to prevent ConvectinTransport to recreate the transport matrix
213  // every timestep ( this may happen for unsteady flow if we would use time->t() here since it returns infinity.
215  return mh_dh;
216  }
217 
218  void update_solution() override;
219  void zero_time_step() override;
220 
221  void get_solution_vector(double * &vec, unsigned int &vec_size) override;
222  void get_parallel_solution_vector(Vec &vector) override;
223 
224  /// postprocess velocity field (add sources)
225  virtual void postprocess();
226  virtual void output_data() override;
227 
229 
230 
231 protected:
232  //class AssemblyBase;
233  //template<unsigned int dim> class Assembly;
234 
236  {
240  };
241 
243  {
244  public:
245  // assembly just A block of local matrix
246  virtual void assembly_local_matrix(arma::mat &local_matrix,
247  ElementFullIter ele) = 0;
248 
249  // assembly compatible neighbourings
250  virtual void assembly_local_vb(double *local_vb,
251  ElementFullIter ele,
252  Neighbour *ngh) = 0;
253 
254  // compute velocity value in the barycenter
255  // TOTO: implement and use general interpolations between discrete spaces
256  virtual arma::vec3 make_element_vector(ElementFullIter ele) = 0;
257  };
258 
259  template<unsigned int dim>
260  class Assembly : public AssemblyBase
261  {
262  public:
264  ~Assembly<dim>();
265  void assembly_local_matrix(arma::mat &local_matrix,
266  ElementFullIter ele) override;
267  void assembly_local_vb(double *local_vb,
268  ElementFullIter ele,
269  Neighbour *ngh
270  ) override;
271  arma::vec3 make_element_vector(ElementFullIter ele) override;
272 
273  // assembly volume integrals
278 
279  // assembly face integrals (BC)
283 
284  // Interpolation of velocity into barycenters
287 
288  // data shared by assemblers of different dimension
290 
291  };
292 
293  /*
294  void setup_velocity_vector() {
295  double *velocity_array;
296  unsigned int size;
297 
298  get_solution_vector(velocity_array, size);
299  VecCreateSeqWithArray(PETSC_COMM_SELF, 1, mesh_->n_sides(), velocity_array, &velocity_vector);
300 
301  }*/
302 
303 
304  /// Solve method common to zero_time_step and update solution.
305  void solve_nonlinear();
306  void make_serial_scatter();
307  virtual void modify_system();
308  virtual void setup_time_term();
309 
310 
311  void prepare_parallel();
312  void make_row_numberings();
313  /// Initialize global_row_4_sub_row.
314  void prepare_parallel_bddc();
315 
316  /**
317  * Create and preallocate MH linear system (including matrix, rhs and solution vectors)
318  */
320 
321  /**
322  * Read initial condition into solution vector.
323  * Must be called after create_linear_system.
324  *
325  * For the LMH scheme we have to be able to save edge pressures in order to
326  * restart simulation or use results of one simulation as initial condition for other one.
327  */
328  virtual void read_initial_condition();
329 
330  /**
331  * Abstract assembly method used for both assembly and preallocation.
332  * Assembly only steady part of the equation.
333  * TODO:
334  * - use general preallocation methods in DofHandler
335  * - include alos time term
336  * - add support for Robin type sources
337  * - support for nonlinear solvers - assembly either residual vector, matrix, or both (using FADBAD++)
338  *
339  */
341 
342 
343  /// Source term is implemented differently in LMH version.
344  virtual void assembly_source_term();
345 
346  /**
347  * Assembly or update whole linear system.
348  */
349  void assembly_linear_system();
350 
351  void set_mesh_data_for_bddc(LinSys_BDDC * bddc_ls);
352  /**
353  * Return a norm of residual vector.
354  * TODO: Introduce Equation::compute_residual() updating
355  * residual field, standard part of EqData.
356  */
357  virtual double solution_precision() const;
358 
360  //Vec velocity_vector;
361  MH_DofHandler mh_dh; // provides access to seq. solution fluxes and pressures on sides
362 
364 
365  /// object for calculation and writing the water balance to file.
366  boost::shared_ptr<Balance> balance_;
367  /// index of water balance within the Balance object.
368  unsigned int water_balance_idx_;
369 
371 
372  int size; // global size of MH matrix
373  int n_schur_compls; // number of shur complements to make
374  double *solution; // sequantial scattered solution vector
375  int is_linear_; // Hack fo BDDC solver.
376 
377  // Propagate test for the time term to the assembly.
378  // This flag is necessary for switching BC to avoid setting zero neumann on the whole boundary in the steady case.
380 
381  // Setting of the nonlinear solver. TODO: Move to the solver class later on.
382  double tolerance_;
383  unsigned int max_n_it_;
384  unsigned int nonlinear_iteration_; //< Actual number of completed nonlinear iterations, need to pass this information into assembly.
385 
386 
387  LinSys *schur0; //< whole MH Linear System
388 
389  //AssemblyData *assembly_data_;
391 
392  // parallel
393  Distribution *edge_ds; //< optimal distribution of edges
394  Distribution *el_ds; //< optimal distribution of elements
395  Distribution *side_ds; //< optimal distribution of elements
396  boost::shared_ptr<Distribution> rows_ds; //< final distribution of rows of MH matrix
397 
398  int *el_4_loc; //< array of idexes of local elements (in ordering matching the optimal global)
399  int *row_4_el; //< element index to matrix row
400  int *side_id_4_loc; //< array of ids of local sides
401  int *side_row_4_id; //< side id to matrix row
402  int *edge_4_loc; //< array of indexes of local edges
403  int *row_4_edge; //< edge index to matrix row
404 
405  /// Idicator of dirichlet or neumann type of switch boundary conditions.
407 
408  /// Necessary only for BDDC solver.
409  boost::shared_ptr<LocalToGlobalMap> global_row_4_sub_row; //< global dof index for subdomain index
410 
411  // gather of the solution
412  Vec sol_vec; //< vector over solution array
413  VecScatter par_to_all;
414 
419 
421 
422  friend class DarcyFlowMHOutput;
423  friend class P0_CouplingAssembler;
424  friend class P1_CouplingAssembler;
425 
426 private:
427  /// Registrar of class to factory
428  static const int registrar;
429 };
430 
431 
433 public:
435  : darcy_(darcy),
436  master_list_(darcy.mesh_->master_elements),
437  intersections_(darcy.mesh_->intersections),
438  master_(nullptr),
439  tensor_average(2)
440  {
441  arma::mat master_map(1,2), slave_map(1,3);
442  master_map.fill(1.0 / 2);
443  slave_map.fill(1.0 / 3);
444 
445  tensor_average[0].push_back( trans( master_map ) * master_map );
446  tensor_average[0].push_back( trans( master_map ) * slave_map );
447  tensor_average[1].push_back( trans( slave_map ) * master_map );
448  tensor_average[1].push_back( trans( slave_map ) * slave_map );
449  }
450 
451  void assembly(LinSys &ls);
452  void pressure_diff(int i_ele,
453  vector<int> &dofs,
454  unsigned int &ele_type,
455  double &delta,
456  arma::vec &dirichlet);
457 private:
459 
461 
464 
466  const Element *master_;
467 
468  /// Row matrices to compute element pressure as average of boundary pressures
470  /// measure of master element, should be sum of intersection measures
471  double delta_0;
472 };
473 
474 
475 
477 public:
479  : darcy_(darcy),
480  intersections_(darcy.mesh_->intersections),
481  rhs(5),
482  dofs(5),
483  dirichlet(5)
484  {
485  rhs.zeros();
486  }
487 
488  void assembly(LinSys &ls);
489  void add_sides(const Element * ele, unsigned int shift, vector<int> &dofs, vector<double> &dirichlet);
490 private:
491 
494 
495  arma::vec rhs;
498 };
499 
500 
501 
502 void mat_count_off_proc_values(Mat m, Vec v);
503 
504 
505 
506 /**
507  * @brief Mixed-hybrid solution of unsteady Darcy flow.
508  *
509  * Standard discretization with time term and sources picewise constant
510  * on the element. This leads to violation of the discrete maximum principle for
511  * non-acute meshes or to too small timesteps. For simplicial meshes this can be solved by lumping to the edges. See DarcyFlowLMH_Unsteady.
512  */
513 /*
514 class DarcyFlowMH_Unsteady : public DarcyFlowMH_Steady
515 {
516 public:
517 
518  DarcyFlowMH_Unsteady(Mesh &mesh, const Input::Record in_rec);
519  //DarcyFlowMH_Unsteady();
520 
521  static const Input::Type::Record & get_input_type();
522 protected:
523  void read_initial_condition() override;
524  void modify_system() override;
525  void setup_time_term();
526 
527 private:
528  /// Registrar of class to factory
529  static const int registrar;
530 
531 
532 };
533 */
534 
535 #endif //DARCY_FLOW_MH_HH
536 //-----------------------------------------------------------------------------
537 // vim: set cindent:
538 
MappingP1< dim, 3 > map_
Abstract base class for equation clasess.
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:61
BCField< 3, FieldValue< 3 >::Scalar > bc_robin_sigma
unsigned int max_n_it_
Field< 3, FieldValue< 3 >::Scalar > water_source_density
static const int registrar
Registrar of class to factory.
FEValues< dim, 3 > fe_values_
P1_CouplingAssembler(const DarcyFlowMH_Steady &darcy)
Solver based on the original PETSc solver using MPIAIJ matrix and succesive Schur complement construc...
void prepare_parallel_bddc()
Initialize global_row_4_sub_row.
void get_parallel_solution_vector(Vec &vector) override
vector< vector< arma::mat > > tensor_average
Row matrices to compute element pressure as average of boundary pressures.
Field< 3, FieldValue< 3 >::Scalar > cross_section
static const Input::Type::Selection & get_bc_type_selection()
Return a Selection corresponding to enum BC_Type.
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:62
Field< 3, FieldValue< 3 >::TensorFixed > anisotropy
virtual void modify_system()
const DarcyFlowMH_Steady & darcy_
void zero_time_step() override
FE_P_disc< 0, dim, 3 > fe_p_disc_
Definition: mesh.h:99
virtual void read_initial_condition()
boost::shared_ptr< Distribution > rows_ds
vector< IsecList >::const_iterator ml_it_
vector< double > dirichlet
unsigned int water_balance_idx_
index of water balance within the Balance object.
void solve_nonlinear()
Solve method common to zero_time_step and update solution.
void mat_count_off_proc_values(Mat m, Vec v)
class to manage local indices on sub-domain to global indices on domain
static const Input::Type::Record & get_input_type()
vector< unsigned int > IsecList
Symmetric Gauss-Legendre quadrature formulae on simplices.
BCField< 3, FieldValue< 3 >::Scalar > bc_pressure
double last_t() const
const DarcyFlowMH_Steady & darcy_
Field< 3, FieldValue< 3 >::Scalar > sigma
MortarMethod mortar_method_
Discontinuous Lagrangean finite element on dim dimensional simplex.
Definition: fe_p.hh:202
virtual void assembly_source_term()
Source term is implemented differently in LMH version.
P0_CouplingAssembler(const DarcyFlowMH_Steady &darcy)
Mesh & mesh()
Definition: equation.hh:174
Virtual class for construction and partitioning of a distributed sparse graph.
Definition: sparse_graph.hh:54
BCField< 3, FieldValue< 3 >::Enum > bc_type
Raviart-Thomas element of order 0.
Definition: fe_rt.hh:33
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
MortarMethod
Type of experimental Mortar-like method for non-compatible 1d-2d interaction.
Mesh * mesh_
Definition: equation.hh:221
MH_DofHandler mh_dh
TYPEDEF_ERR_INFO(EI_Reason, string)
const vector< IsecList > & master_list_
unsigned int nonlinear_iteration_
FESideValues< dim, 3 > fe_side_values_
Affine mapping between reference and actual cell.
Definition: mapping_p1.hh:53
virtual double solution_precision() const
DarcyFlowMH_Steady(Mesh &mesh, const Input::Record in_rec)
CREATE AND FILL GLOBAL MH MATRIX OF THE WATER MODEL.
const vector< Intersection > & intersections_
void create_linear_system(Input::AbstractRecord rec)
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:444
const vector< Intersection > & intersections_
std::vector< char > bc_switch_dirichlet
Idicator of dirichlet or neumann type of switch boundary conditions.
std::vector< AssemblyBase * > assembly_
Field< 3, FieldValue< 3 >::Scalar > conductivity
double delta_0
measure of master element, should be sum of intersection measures
FEValues< dim, 3 > velocity_interpolation_fv_
Distribution * el_ds
virtual void postprocess()
postprocess velocity field (add sources)
boost::shared_ptr< LocalToGlobalMap > global_row_4_sub_row
Necessary only for BDDC solver.
boost::shared_ptr< Balance > balance_
object for calculation and writing the water balance to file.
EqData()
Creation of all fields.
void assembly_steady_mh_matrix()
Vector classes to support both Iterator, index and Id access and creating co-located vectors...
static const Input::Type::Selection & get_mh_mortar_selection()
Selection for enum MortarMethod.
Abstract linear system class.
Mixed-hybrid model of linear Darcy flow, possibly unsteady.
Calculates finite element data on the actual cell.
Definition: fe_values.hh:415
void set_mesh_data_for_bddc(LinSys_BDDC *bddc_ls)
virtual void setup_time_term()
const MH_DofHandler & get_mh_dofhandler()
Record type proxy class.
Definition: type_record.hh:171
void update_solution() override
virtual void output_data() override
Write computed fields.
Distribution * side_ds
Distribution * edge_ds
void set_solution(double time, double *solution, double precision)
QGauss< dim > velocity_interpolation_quad_
DarcyFlowMHOutput * output_object
DECLARE_EXCEPTION(ExcSolverDiverge,<< "Diverged nonlinear solver. Reason: "<< EI_Reason::val)
Field< 3, FieldValue< 3 >::Scalar > storativity
BCField< 3, FieldValue< 3 >::Scalar > bc_flux
BCField< 3, FieldValue< 3 >::Scalar > bc_switch_pressure
Template for classes storing finite set of named values.
Solver based on Multilevel BDDC - using corresponding class of OpenFTL package.
TimeGovernor * time_
Definition: equation.hh:222
Field< 3, FieldValue< 3 >::Scalar > init_pressure
const Element * master_
Calculates finite element data on a side.
Definition: fe_values.hh:460
void get_solution_vector(double *&vec, unsigned int &vec_size) override