Flow123d  last_with_con_2.0.0-4-g42e6930
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 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 
149 
150  /// Class with all fields used in the equation DarcyFlow.
151  /// This is common to all implementations since this provides interface
152  /// to this equation for possible coupling.
153  class EqData : public FieldSet {
154  public:
155 
156  /**
157  * For compatibility with old BCD file we have to assign integer codes starting from 1.
158  */
159  enum BC_Type {
160  none=0,
161  dirichlet=1,
162  total_flux=4,
163  seepage=5,
164  river=6
165  };
166 
167  /// Return a Selection corresponding to enum BC_Type.
168  static const Input::Type::Selection & get_bc_type_selection();
169 
170  /// Creation of all fields.
171  EqData();
172 
173 
179 
180  BCField<3, FieldValue<3>::Enum > bc_type; // Discrete need Selection for initialization
185 
188 
189  /**
190  * Gravity vector and constant shift of pressure potential. Used to convert piezometric head
191  * to pressure head and vice versa.
192  */
193  arma::vec4 gravity_;
195 
198 
201  //FieldSet time_term_fields;
202  //FieldSet main_matrix_fields;
203  //FieldSet rhs_fields;
204  };
205 
206  /// Type of experimental Mortar-like method for non-compatible 1d-2d interaction.
208  NoMortar = 0,
209  MortarP0 = 1,
210  MortarP1 = 2
211  };
212  /// Selection for enum MortarMethod.
213  static const Input::Type::Selection & get_mh_mortar_selection();
214 
215 
216 
217 
218 
219  DarcyMH(Mesh &mesh, const Input::Record in_rec);
220 
221  static const Input::Type::Record & type_field_descriptor();
222  static const Input::Type::Record & get_input_type();
223 
225  double *array;
226  unsigned int size;
227  get_solution_vector(array, size);
228 
229  // here assume that velocity field is extended as constant
230  // to the previous time, so here we set left bound of the interval where the velocity
231  // has current value; this may not be good for every transport !!
232  // we can resolve this when we use FieldFE to store computed velocities in few last steps and
233  // let every equation set time according to nature of the time scheme
234 
235  // in particular this setting is necessary to prevent ConvectinTransport to recreate the transport matrix
236  // every timestep ( this may happen for unsteady flow if we would use time->t() here since it returns infinity.
237  mh_dh.set_solution(time_->last_t(), array, solution_precision());
238  return mh_dh;
239  }
240 
241  void init_eq_data();
242  void initialize() override;
243  virtual void initialize_specific();
244  void zero_time_step() override;
245  void update_solution() override;
246 
247  void get_solution_vector(double * &vec, unsigned int &vec_size) override;
248  void get_parallel_solution_vector(Vec &vector) override;
249 
250  /// postprocess velocity field (add sources)
251  virtual void prepare_new_time_step();
252  virtual void postprocess();
253  virtual void output_data() override;
254 
255  ~DarcyMH();
256 
257 
258 protected:
259 
260  virtual bool zero_time_term();
261 
262 
263  /// Solve method common to zero_time_step and update solution.
264  void solve_nonlinear();
265  void make_serial_scatter();
266  void modify_system();
267  virtual void setup_time_term();
268 
269 
270  //void prepare_parallel();
271  //void make_row_numberings();
272  /// Initialize global_row_4_sub_row.
273  //void prepare_parallel_bddc();
274 
275  /**
276  * Create and preallocate MH linear system (including matrix, rhs and solution vectors)
277  */
278  void create_linear_system(Input::AbstractRecord rec);
279 
280  /**
281  * Read initial condition into solution vector.
282  * Must be called after create_linear_system.
283  *
284  * For the LMH scheme we have to be able to save edge pressures in order to
285  * restart simulation or use results of one simulation as initial condition for other one.
286  */
287  virtual void read_initial_condition();
288 
289  /**
290  * Part of per element assembly that is specific for MH and LMH respectively.
291  *
292  * This implemnets MH case:
293  * - compute conductivity scaling
294  * - assembly source term
295  * - no time term, managed by diagonal extraction etc.
296  */
297  //virtual void local_assembly_specific(AssemblyData &local_data);
298 
299  /**
300  * Abstract assembly method used for both assembly and preallocation.
301  * Assembly only steady part of the equation.
302  * TODO:
303  * - use general preallocation methods in DofHandler
304  * - include time term
305  * - add support for Robin type sources
306  * - support for nonlinear solvers - assembly either residual vector, matrix, or both (using FADBAD++)
307  */
308  void assembly_mh_matrix( MultidimAssembler ma);
309 
310 
311  /// Source term is implemented differently in LMH version.
312  virtual void assembly_source_term();
313 
314  /**
315  * Assembly or update whole linear system.
316  */
317  virtual void assembly_linear_system();
318 
319  void set_mesh_data_for_bddc(LinSys_BDDC * bddc_ls);
320  /**
321  * Return a norm of residual vector.
322  * TODO: Introduce Equation::compute_residual() updating
323  * residual field, standard part of EqData.
324  */
325  virtual double solution_precision() const;
326 
328  //Vec velocity_vector;
329  MH_DofHandler mh_dh; // provides access to seq. solution fluxes and pressures on sides
330 
332 
333  std::shared_ptr<Balance> balance_;
334  /// index of water balance within the Balance object.
335  unsigned int water_balance_idx_;
336 
338 
339  int size; // global size of MH matrix
340  int n_schur_compls; // number of shur complements to make
341  double *solution; // sequantial scattered solution vector
342  int is_linear_; // Hack fo BDDC solver.
343 
344  // Propagate test for the time term to the assembly.
345  // This flag is necessary for switching BC to avoid setting zero neumann on the whole boundary in the steady case.
347 
348  // Setting of the nonlinear solver. TODO: Move to the solver class later on.
349  double tolerance_;
350  unsigned int max_n_it_;
351  unsigned int nonlinear_iteration_; //< Actual number of completed nonlinear iterations, need to pass this information into assembly.
352 
353 
354  LinSys *schur0; //< whole MH Linear System
355 
356 
357 
358 
359 
360  /// Idicator of dirichlet or neumann type of switch boundary conditions.
362 
363 
364  // gather of the solution
365  Vec sol_vec; //< vector over solution array
366  VecScatter par_to_all;
367 
372 
373  std::shared_ptr<EqData> data_;
374 
375  friend class DarcyFlowMHOutput;
376  friend class P0_CouplingAssembler;
377  friend class P1_CouplingAssembler;
378 
379 private:
380  /// Registrar of class to factory
381  static const int registrar;
382 };
383 
384 
386 public:
388  : darcy_(darcy),
389  master_list_(darcy.mesh_->master_elements),
390  intersections_(darcy.mesh_->intersections),
391  master_(nullptr),
392  tensor_average(2)
393  {
394  arma::mat master_map(1,2), slave_map(1,3);
395  master_map.fill(1.0 / 2);
396  slave_map.fill(1.0 / 3);
397 
398  tensor_average[0].push_back( trans( master_map ) * master_map );
399  tensor_average[0].push_back( trans( master_map ) * slave_map );
400  tensor_average[1].push_back( trans( slave_map ) * master_map );
401  tensor_average[1].push_back( trans( slave_map ) * slave_map );
402  }
403 
404  void assembly(LinSys &ls);
405  void pressure_diff(int i_ele,
406  vector<int> &dofs,
407  unsigned int &ele_type,
408  double &delta,
409  arma::vec &dirichlet);
410 private:
412 
413  const DarcyMH &darcy_;
414 
417 
419  const Element *master_;
420 
421  /// Row matrices to compute element pressure as average of boundary pressures
423  /// measure of master element, should be sum of intersection measures
424  double delta_0;
425 };
426 
427 
428 
430 public:
432  : darcy_(darcy),
433  intersections_(darcy.mesh_->intersections),
434  rhs(5),
435  dofs(5),
436  dirichlet(5)
437  {
438  rhs.zeros();
439  }
440 
441  void assembly(LinSys &ls);
442  void add_sides(const Element * ele, unsigned int shift, vector<int> &dofs, vector<double> &dirichlet);
443 private:
444 
445  const DarcyMH &darcy_;
447 
448  arma::vec rhs;
451 };
452 
453 
454 
455 void mat_count_off_proc_values(Mat m, Vec v);
456 
457 
458 
459 /**
460  * @brief Mixed-hybrid solution of unsteady Darcy flow.
461  *
462  * Standard discretization with time term and sources picewise constant
463  * on the element. This leads to violation of the discrete maximum principle for
464  * non-acute meshes or to too small timesteps. For simplicial meshes this can be solved by lumping to the edges. See DarcyFlowLMH_Unsteady.
465  */
466 /*
467 class DarcyFlowMH_Unsteady : public DarcyFlowMH_Steady
468 {
469 public:
470 
471  DarcyFlowMH_Unsteady(Mesh &mesh, const Input::Record in_rec);
472  //DarcyFlowMH_Unsteady();
473 
474  static const Input::Type::Record & get_input_type();
475 protected:
476  void read_initial_condition() override;
477  void modify_system() override;
478  void setup_time_term();
479 
480 private:
481  /// Registrar of class to factory
482  static const int registrar;
483 
484 
485 };
486 */
487 
488 #endif //DARCY_FLOW_MH_HH
489 //-----------------------------------------------------------------------------
490 // vim: set cindent:
491 
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
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:95
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_
#define DECLARE_EXCEPTION(ExcName, Format)
Macro for simple definition of exceptions.
Definition: exceptions.hh:150
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 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
const MH_DofHandler & get_mh_dofhandler()
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:277
double * solution
const vector< IsecList > & master_list_
bool use_steady_assembly_
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:444
LinSys * schur0
const vector< Intersection > & intersections_
const DarcyMH & darcy_
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
#define TYPEDEF_ERR_INFO(EI_Type, Type)
Macro to simplify declaration of error_info types.
Definition: exceptions.hh:186
std::vector< std::shared_ptr< AssemblyBase > > MultidimAssembler
Record type proxy class.
Definition: type_record.hh:171
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_
Calculates finite element data on a side.
Definition: fe_values.hh:461
Mixed-hybrid of steady Darcy flow with sources and variable density.