Flow123d  jenkins-Flow123d-windows32-release-multijob-51
darcy_flow_mh.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 mixed-hybrid model of linear Darcy flow, possibly unsteady.
27  *
28  * Main object for mixed-hybrid discretization of the linear elliptic PDE (Laplace)
29  * on a multidimensional domain. Discretization of saturated Darcy flow using
30  * RT0 approximation for the velocity
31  *
32  *
33  *
34  * @author Jan Brezina
35  *
36  */
37 
38 /*
39  * list of files dependent on this one:
40  *
41  * posprocess.cc
42  * problem.cc
43  * main.hh
44  * transport.cc
45  */
46 
47 
48 #ifndef DARCY_FLOW_MH_HH
49 #define DARCY_FLOW_MH_HH
50 
51 #include <memory>
52 #include "input/input_type.hh"
53 
54 #include <petscmat.h>
55 #include "system/sys_vector.hh"
56 #include "coupling/equation.hh"
57 #include "flow/mh_dofhandler.hh"
58 #include "input/input_type.hh"
59 #include "la/linsys_BDDC.hh"
60 #include "la/linsys_PETSC.hh"
61 
62 #include "fields/field.hh"
63 #include "fields/field_set.hh"
65 #include "flow/old_bcd.hh"
66 
67 
68 /// external types:
69 class LinSys;
70 struct Solver;
71 class Mesh;
72 class SchurComplement;
73 class Distribution;
74 class SparseGraph;
75 class LocalToGlobalMap;
76 class DarcyFlowMHOutput;
77 
78 
79 /**
80  * @brief Mixed-hybrid model of linear Darcy flow, possibly unsteady.
81  *
82  * Abstract class for various implementations of Darcy flow. In future there should be
83  * one further level of abstraction for general time dependent problem.
84  *
85  * maybe TODO:
86  * split compute_one_step to :
87  * 1) prepare_next_timestep
88  * 2) actualize_solution - this is for iterative nonlinear solvers
89  *
90  */
91 
92 class DarcyFlowMH : public EquationBase {
93 public:
94  enum MortarMethod {
95  NoMortar = 0,
96  MortarP0 = 1,
98  };
99 
100  /** @brief Data for Darcy flow equation.
101  *
102  */
103  class EqData : public FieldSet {
104  public:
105 
106  /**
107  * For compatibility with old BCD file we have to assign integer codes starting from 1.
108  */
109  enum BC_Type {
110  none=0,
113  robin=3,
115  };
117 
118  /// Collect all fields
119  EqData();
120 
121 
122  /**
123  * Hook for processing "bc_piezo_head" key.
124  */
125  inline static std::shared_ptr< FieldAlgorithmBase<3, FieldValue<3>::Scalar> >
127  {
128  auto field_ptr = OldBcdInput::flow_pressure_hook(rec, field);
129  Input::AbstractRecord field_a_rec;
130  if (! field_ptr && rec.opt_val("bc_piezo_head", field_a_rec)) {
131  return std::make_shared< FieldAddPotential<3, FieldValue<3>::Scalar > >( gravity_, field_a_rec);
132  } else {
133  return field_ptr;
134  }
135  }
136 
142 
143  BCField<3, FieldValue<3>::Enum > bc_type; // Discrete need Selection for initialization
147 
148  //TODO: these belong to Unsteady flow classes
149  //as long as Unsteady is descendant from Steady, these cannot be transfered..
152 
153  /**
154  * Gravity vector and constant shift of pressure potential. Used to convert piezometric head
155  * to pressure head and vice versa.
156  *
157  * TODO: static method bc_piezo_head_hook needs static @p gravity_ vector. Other solution is to
158  * introduce some kind of context pointer into @p FieldCommonBase.
159  */
160  static arma::vec4 gravity_;
161 
165  };
166 
167 
168  /**
169  * Model for transition coefficients due to Martin, Jaffre, Roberts (see manual for full reference)
170  *
171  * TODO:
172  * - how we can reuse values computed during assembly
173  * we want to make this class see values in
174  *
175  */
177  : EquationBase(mesh, in_rec)
178  {}
179 
185 
186  void get_velocity_seq_vector(Vec &velocity_vec)
187  { velocity_vec = velocity_vector; }
188 
190  double *array;
191  unsigned int size;
192  get_solution_vector(array, size);
193 
194  // here assume that velocity field is extended as constant
195  // to the previous time, so here we set left bound of the interval where the velocity
196  // has current value; this may not be good for every transport !!
197  // we can resolve this when we use FieldFE to store computed velocities in few last steps and
198  // let every equation set time according to nature of the time scheme
199 
200  // in particular this setting is necessary to prevent ConvectinTransport to recreate the transport matrix
201  // every timestep ( this may happen for unsteady flow if we would use time->t() here since it returns infinity.
203  return mh_dh;
204  }
205 
206  virtual void set_concentration_vector(Vec &vc){};
207 
208 
209 protected:
211  double *velocity_array;
212  unsigned int size;
213 
214  get_solution_vector(velocity_array, size);
215  VecCreateSeqWithArray(PETSC_COMM_SELF, 1, mesh_->n_sides(), velocity_array, &velocity_vector);
216 
217  }
218 
219  virtual double solution_precision() const = 0;
220 
223  MH_DofHandler mh_dh; // provides access to seq. solution fluxes and pressures on sides
224 
226 };
227 
228 
229 /**
230  * @brief Mixed-hybrid of steady Darcy flow with sources and variable density.
231  *
232  * solve equations:
233  * @f[
234  * q= -{\mathbf{K}} \nabla h -{\mathbf{K}} R \nabla z
235  * @f]
236  * @f[
237  * \mathrm{div} q = f
238  * @f]
239  *
240  * where
241  * - @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.
242  * - @f$ \mathbf{K} @f$ is hydraulic tensor ( its orientation for 2d, 1d case is questionable )
243  * - @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.
244  * Assumes gravity force acts counter to the direction of the @f$ z @f$ axis.
245  * - @f$ R @f$ is destity or gravity variability coefficient. For density driven flow it should be
246  * @f[
247  * R = \frac{\rho}{\rho_0} -1 = \rho_0^{-1}\sum_{i=1}^s c_i
248  * @f]
249  * where @f$ c_i @f$ is concentration in @f$ kg m^{-3} @f$.
250  *
251  *
252  * TODO:
253  * - consider create auxiliary classes for creation of inverse of block A
254  */
256 {
257 public:
258 
259  class EqData : public DarcyFlowMH::EqData {
260  public:
261 
263  {}
264  };
265 
266  DarcyFlowMH_Steady(Mesh &mesh, const Input::Record in_rec, bool make_tg=true);
267 
269 
270  virtual void update_solution();
271  virtual void get_solution_vector(double * &vec, unsigned int &vec_size);
272  virtual void get_parallel_solution_vector(Vec &vector);
273 
274  /// postprocess velocity field (add sources)
275  virtual void postprocess();
276  virtual void output_data() override;
277 
279 
280 
281 protected:
282  void make_serial_scatter();
283  virtual void modify_system()
284  { ASSERT(0, "Modify system called for Steady darcy.\n"); };
285  virtual void setup_time_term()
286  { ASSERT(0, "Setup time term called for Steady darcy.\n"); };
287 
288 
289  void prepare_parallel( const Input::AbstractRecord in_rec);
290  void make_row_numberings();
291 
292  /**
293  * Create and preallocate MH linear system (including matrix, rhs and solution vectors)
294  */
295  void create_linear_system();
296 
297  /**
298  * Read initial condition into solution vector.
299  * Must be called after create_linear_system.
300  *
301  */
302  virtual void read_init_condition() {};
303 
304  /**
305  * Abstract assembly method used for both assembly and preallocation.
306  * Assembly only steady part of the equation.
307  * TODO:
308  * - use general preallocation methods in DofHandler
309  * - include alos time term
310  * - add support for Robin type sources
311  * - support for nonlinear solvers - assembly either residual vector, matrix, or both (using FADBAD++)
312  *
313  */
315 
316  /**
317  * Assembly or update whole linear system.
318  */
319  void assembly_linear_system();
320 
321  void set_mesh_data_for_bddc(LinSys_BDDC * bddc_ls);
322  double solution_precision() const;
323 
324 
326 
327  int size; // global size of MH matrix
328  int n_schur_compls; // number of shur complements to make
329  double *solution; // sequantial scattered solution vector
330 
331 
332  LinSys *schur0; //< whole MH Linear System
333 
334  // parallel
335  Distribution *edge_ds; //< optimal distribution of edges
336  Distribution *el_ds; //< optimal distribution of elements
337  Distribution *side_ds; //< optimal distribution of elements
338  boost::shared_ptr<Distribution> rows_ds; //< final distribution of rows of MH matrix
339 
340  int *el_4_loc; //< array of idexes of local elements (in ordering matching the optimal global)
341  int *row_4_el; //< element index to matrix row
342  int *side_id_4_loc; //< array of ids of local sides
343  int *side_row_4_id; //< side id to matrix row
344  int *edge_4_loc; //< array of indexes of local edges
345  int *row_4_edge; //< edge index to matrix row
346 
347  // MATIS related arrays
348  boost::shared_ptr<LocalToGlobalMap> global_row_4_sub_row; //< global dof index for subdomain index
349 
350  // gather of the solution
351  Vec sol_vec; //< vector over solution array
352  VecScatter par_to_all;
353 
355 
356  friend class DarcyFlowMHOutput;
357  friend class P0_CouplingAssembler;
358  friend class P1_CouplingAssembler;
359 };
360 
361 
363 public:
365  : darcy_(darcy),
366  master_list_(darcy.mesh_->master_elements),
367  intersections_(darcy.mesh_->intersections),
368  master_(nullptr),
369  tensor_average(2)
370  {
371  arma::mat master_map(1,2), slave_map(1,3);
372  master_map.fill(1.0 / 2);
373  slave_map.fill(1.0 / 3);
374 
375  tensor_average[0].push_back( trans( master_map ) * master_map );
376  tensor_average[0].push_back( trans( master_map ) * slave_map );
377  tensor_average[1].push_back( trans( slave_map ) * master_map );
378  tensor_average[1].push_back( trans( slave_map ) * slave_map );
379  }
380 
381  void assembly(LinSys &ls);
382  void pressure_diff(int i_ele,
383  vector<int> &dofs,
384  unsigned int &ele_type,
385  double &delta,
386  arma::vec &dirichlet);
387 private:
389 
391 
394 
396  const Element *master_;
397 
398  /// Row matrices to compute element pressure as average of boundary pressures
400  /// measure of master element, should be sum of intersection measures
401  double delta_0;
402 };
403 
404 
405 
407 public:
409  : darcy_(darcy),
410  intersections_(darcy.mesh_->intersections),
411  rhs(5),
412  dofs(5),
413  dirichlet(5)
414  {
415  rhs.zeros();
416  }
417 
418  void assembly(LinSys &ls);
419  void add_sides(const Element * ele, unsigned int shift, vector<int> &dofs, vector<double> &dirichlet);
420 private:
421 
424 
425  arma::vec rhs;
428 };
429 
430 
431 
432 void mat_count_off_proc_values(Mat m, Vec v);
433 
434 
435 
436 /**
437  * @brief Mixed-hybrid solution of unsteady Darcy flow.
438  *
439  * Standard discretization with time term and sources picewise constant
440  * on the element. This leads to violation of the discrete maximum principle for
441  * non-acute meshes or to too small timesteps. For simplicial meshes this can be solved by lumping to the edges. See DarcyFlowLMH_Unsteady.
442  */
443 
445 {
446 public:
447 
450 
452 protected:
453  void read_init_condition() override;
454  void modify_system() override;
455  void setup_time_term();
456 
457 private:
462 
463 };
464 
465 /**
466  * @brief Edge lumped mixed-hybrid solution of unsteady Darcy flow.
467  *
468  * The time term and sources are evenly distributed form an element to its edges.
469  * This applies directly to the second Schur complement. After this system for pressure traces is solved we reconstruct pressures and side flows as follows:
470  *
471  * -# Element pressure is average of edge pressure. This is in fact same as the MH for steady case so we let SchurComplement class do its job.
472  *
473  * -# We let SchurComplement to reconstruct fluxes and then account time term and sources which are evenly distributed from an element to its sides.
474  * It can be proved, that this keeps continuity of the fluxes over the edges.
475  *
476  * This lumping technique preserves discrete maximum principle for any time step provided one use acute mesh. But in practice even worse meshes are tractable.
477  */
479 {
480 public:
481 
484 
486 protected:
487  void read_init_condition() override;
488  void modify_system() override;
489  void setup_time_term();
490  virtual void postprocess();
491 private:
496  //Vec time_term;
497 };
498 
499 #endif //DARCY_FLOW_MH_HH
500 //-----------------------------------------------------------------------------
501 // vim: set cindent:
502 
Abstract base class for equation clasess.
Common abstract parent of all Field<...> classes.
Definition: field_common.hh:45
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:51
virtual void postprocess()
postprocess velocity field (add sources)
virtual void get_solution_vector(double *&vec, unsigned int &vec_size)
virtual void setup_time_term()
P1_CouplingAssembler(const DarcyFlowMH_Steady &darcy)
Solver based on the original PETSc solver using MPIAIJ matrix and succesive Schur complement construc...
vector< vector< arma::mat > > tensor_average
Row matrices to compute element pressure as average of boundary pressures.
MortarMethod mortar_method_
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:48
static Input::Type::Selection mh_mortar_selection
void assembly(LinSys &ls)
bool solution_changed_for_scatter
const DarcyFlowMH_Steady & darcy_
void assembly(LinSys &ls)
Definition: mesh.h:108
static Input::Type::Record input_type
virtual void read_init_condition()
boost::shared_ptr< Distribution > rows_ds
vector< IsecList >::const_iterator ml_it_
BCField< 3, FieldValue< 3 >::Scalar > bc_flux
void pressure_diff(int i_ele, vector< int > &dofs, unsigned int &ele_type, double &delta, arma::vec &dirichlet)
vector< double > dirichlet
const MH_DofHandler & get_mh_dofhandler()
static Input::Type::Record input_type
BCField< 3, FieldValue< 3 >::Enum > bc_type
Field< 3, FieldValue< 3 >::Scalar > storativity
unsigned int n_sides()
Definition: mesh.cc:151
virtual double solution_precision() const =0
void mat_count_off_proc_values(Mat m, Vec v)
class to manage local indices on sub-domain to global indices on domain
static arma::vec4 gravity_
void modify_system() override
vector< unsigned int > IsecList
BCField< 3, FieldValue< 3 >::Scalar > bc_pressure
void setup_velocity_vector()
double last_t() const
const DarcyFlowMH_Steady & darcy_
Data for Darcy flow equation.
virtual void update_solution()
Mixed-hybrid solution of unsteady Darcy flow.
bool opt_val(const string &key, Ret &value) const
static FieldBaseScalar flow_pressure_hook(Input::Record rec, const FieldCommon &field)
Definition: old_bcd.hh:90
FieldCommon * field(const std::string &field_name) const
Definition: field_set.cc:102
virtual void get_parallel_solution_vector(Vec &vector)
virtual void modify_system()
#define ASSERT(...)
Definition: global_defs.h:121
P0_CouplingAssembler(const DarcyFlowMH_Steady &darcy)
Mesh & mesh()
Definition: equation.hh:171
Virtual class for construction and partitioning of a distributed sparse graph.
Definition: sparse_graph.hh:66
Field< 3, FieldValue< 3 >::TensorFixed > anisotropy
void get_velocity_seq_vector(Vec &velocity_vec)
Accessor to the data with type Type::Record.
Definition: accessors.hh:308
void modify_system() override
static std::shared_ptr< FieldAlgorithmBase< 3, FieldValue< 3 >::Scalar > > bc_piezo_head_hook(Input::Record rec, const FieldCommon &field)
Class for declaration of polymorphic Record.
Definition: type_record.hh:463
Mesh * mesh_
Definition: equation.hh:218
void read_init_condition() override
const vector< IsecList > & master_list_
Mixed-hybrid model of linear Darcy flow, possibly unsteady.
double solution_precision() const
const vector< Intersection > & intersections_
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:423
const vector< Intersection > & intersections_
virtual void get_solution_vector(double *&vector, unsigned int &size)
Definition: equation.hh:198
Field< 3, FieldValue< 3 >::Scalar > conductivity
static Input::Type::AbstractRecord input_type
double delta_0
measure of master element, should be sum of intersection measures
Distribution * el_ds
Field< 3, FieldValue< 3 >::Scalar > sigma
virtual void postprocess()
postprocess velocity field (add sources)
MH_DofHandler mh_dh
boost::shared_ptr< LocalToGlobalMap > global_row_4_sub_row
virtual void set_concentration_vector(Vec &vc)
void assembly_steady_mh_matrix()
Vector classes to support both Iterator, index and Id access and creating co-located vectors...
Edge lumped mixed-hybrid solution of unsteady Darcy flow.
static std::vector< Input::Type::Record > bc_input_types
Abstract linear system class.
Mixed-hybrid of steady Darcy flow with sources and variable density.
BCField< 3, FieldValue< 3 >::Scalar > bc_robin_sigma
static Input::Type::Record input_type
void set_mesh_data_for_bddc(LinSys_BDDC *bddc_ls)
void read_init_condition() override
void add_sides(const Element *ele, unsigned int shift, vector< int > &dofs, vector< double > &dirichlet)
Record type proxy class.
Definition: type_record.hh:161
static Input::Type::Record bc_segment_rec
virtual void output_data() override
Write computed fields.
Field< 3, FieldValue< 3 >::Scalar > cross_section
Distribution * side_ds
Distribution * edge_ds
void set_solution(double time, double *solution, double precision)
DarcyFlowMH(Mesh &mesh, const Input::Record in_rec)
static Input::Type::Selection bc_type_selection
Field< 3, FieldValue< 3 >::Scalar > init_pressure
DarcyFlowMHOutput * output_object
DarcyFlowMH_Steady(Mesh &mesh, const Input::Record in_rec, bool make_tg=true)
CREATE AND FILL GLOBAL MH MATRIX OF THE WATER MODEL.
static Input::Type::AbstractRecord bc_input_type
EqData()
Collect all fields.
Template for classes storing finite set of named values.
Field< 3, FieldValue< 3 >::Scalar > water_source_density
void prepare_parallel(const Input::AbstractRecord in_rec)
Solver based on Multilevel BDDC - using corresponding class of OpenFTL package.
TimeGovernor * time_
Definition: equation.hh:219
const Element * master_