LifeV
impes.cpp
Go to the documentation of this file.
1 /* -*- mode: c++ -*-
2 
3  This file is part of the LifeV Applications.
4 
5  Author(s): A. Fumagalli <alessio.fumagalli@mail.polimi.it>
6  Date: 2010-07-29
7 
8  Copyright (C) 2010 EPFL, Politecnico di Milano
9 
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful, but
16  WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23  USA
24 */
25 /**
26  \file impes.cpp
27  \author A. Fumagalli <alessio.fumagalli@mail.polimi.it>
28  \date 2010-07-29
29  */
30 
31 // ===================================================
32 //! Includes
33 // ===================================================
34 
35 #include "impes.hpp"
36 #include "user_fun.hpp"
37 
38 // ===================================================
39 //! Namespaces & define
40 // ===================================================
41 
42 using namespace LifeV;
43 
44 enum BCNAME
45 {
46 
47  FLUX0 = 0,
51  FLUX1 = 4
52 
53  // BACK = 1,
54  // FRONT = 2,
55  // LEFT = 3,
56  // RIGHT = 4,
57  // BOTTOM = 5,
58  // TOP = 6
59 };
60 
61 namespace dataProblem
62 {
63 
64 // Standard functions
65 Real UOne ( const Real& /* t */,
66  const Real& /* x */,
67  const Real& /* y */,
68  const Real& /* z */,
69  const ID& /* icomp */)
70 {
71  return 1.;
72 }
73 
74 Real UZero ( const Real& /* t */,
75  const Real& /* x */,
76  const Real& /* y */,
77  const Real& /* z */,
78  const ID& /* icomp */)
79 {
80  return 0.;
81 }
82 
83 }
84 // ===================================================
85 //! Private Members
86 // ===================================================
87 
88 struct impes::Private
89 {
90  Private() {}
91 
92  // Policy for scalar functions
93  typedef std::function < Real ( const Real&, const Real&,
94  const Real&, const Real&, const ID& ) >
96 
97  // Policy for vector function
98  typedef std::function < Vector ( const Real&, const Real&,
99  const Real&, const Real&,
100  const std::vector<Real>& ) >
102 
103 
104  // Policy for matrix function
105  typedef std::function < Matrix ( const Real&, const Real&,
106  const Real&, const Real&,
107  const std::vector<Real>& ) >
109 
111 
112  // General section
114 
115  // Section for the Darcy solver
117 
118  // Section for the hyperbolic solver
120 
121  // Section for the non-linear and transient Darcy solver
123 
125 
126  // Function Types
127 
129  {
130  fct_type f;
131  f = std::bind ( &dataProblem::UOne, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
132  return f;
133  }
134 
136  {
137  fct_type f;
138  f = std::bind ( &dataProblem::UZero, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
139  return f;
140  }
141 
143  {
144  fct_type f;
145  f = std::bind ( &dataProblem::pressureSource, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
146  return f;
147  }
148 
150  {
151  Mfct_type m;
152  m = std::bind ( &dataProblem::pressurePermeability, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
153  return m;
154  }
155 
157  {
158  fct_type f;
159  f = std::bind ( &dataProblem::saturationInitialCondition, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
160  return f;
161  }
162 
164  {
165  Vfct_type v;
166  v = std::bind ( &dataProblem::saturationPhysicalFlux, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
167  return v;
168  }
169 
171  {
172  Vfct_type v;
173  v = std::bind ( &dataProblem::saturationFirstDerivativePhysicalFlux, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
174  return v;
175  }
176 
178  {
179  fct_type f;
180  f = std::bind ( &dataProblem::saturationSource, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
181  return f;
182  }
183 
185  {
186  Mfct_type mnl;
187  mnl = std::bind ( &dataProblem::saturationPermeability, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
188  return mnl;
189  }
190 
192  {
193  fct_type f;
194  f = std::bind ( &dataProblem::saturationMass, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5 );
195  return f;
196  }
197 
198 };
199 
200 // ===================================================
201 //! Constructors
202 // ===================================================
203 
204 impes::impes ( int argc,
205  char** argv )
206  : Members ( new Private )
207 {
208  GetPot command_line (argc, argv);
209  const std::string data_file_name = command_line.follow ("data", 2, "-f", "--file");
210  GetPot dataFile ( data_file_name );
211 
212  Members->data_file_name = data_file_name;
213  Members->discretization_section = "impes";
214  Members->discretization_section_darcy = Members->discretization_section + "/darcy";
215  Members->discretization_section_hyperbolic = Members->discretization_section + "/hyperbolic";
216  Members->discretization_section_darcy_nonlin_trans = Members->discretization_section + "/darcy_transient_non_linear";
217 
218 #ifdef EPETRA_MPI
219  std::cout << "Epetra Initialization" << std::endl;
220  Members->comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
221  int ntasks;
222  MPI_Comm_size (MPI_COMM_WORLD, &ntasks);
223 #else
224  Members->comm.reset ( new Epetra_SerialComm() );
225 #endif
226 
227 }
228 
229 // ===================================================
230 //! Methods
231 // ===================================================
232 
233 Real
235 {
236  typedef RegionMesh<LinearTetra> RegionMesh;
237  typedef SolverAztecOO solver_type;
238  typedef DarcySolver< RegionMesh, solver_type > ds;
239  typedef DarcySolverTransientNonLinear< RegionMesh, solver_type > dstnl;
240  typedef HyperbolicSolver< RegionMesh, solver_type > hyper;
241  typedef ds::vector_Type vector_type;
242  typedef std::shared_ptr<vector_type> vector_ptrtype;
243  typedef FESpace< RegionMesh, MapEpetra > feSpace_Type;
244  typedef std::shared_ptr<feSpace_Type> feSpacePtr_Type;
245 
246  LifeChrono chronoTotal;
247  LifeChrono chronoReadAndPartitionMesh;
248  LifeChrono chronoBoundaryCondition;
249  LifeChrono chronoFiniteElementSpace;
250  LifeChrono chronoProblem;
251  LifeChrono chronoProcess;
252  LifeChrono chronoError;
253 
254  // Start chronoTotal for measure the total time for the computation.
255  chronoTotal.start();
256 
257  // Reading from data file.
258  GetPot dataFile ( Members->data_file_name.c_str() );
259 
260  // Create the leader process, i.e. the process with MyPID equal to zero.
261  bool isLeader = ( Members->comm->MyPID() == 0 );
262 
263  //
264  // The IMPES Solver.
265  //
266 
267  if ( isLeader )
268  {
269  std::cout << "The IMPES solver" << std::endl << std::flush;
270  }
271 
272  // Start chronoReadAndPartitionMesh for measure the total time for the creation of the local meshes.
273  chronoReadAndPartitionMesh.start();
274 
275  // Create the data file for the pressure equation.
276  DarcyData<RegionMesh> dataPressure;
277 
278  // Create the data file for the hyperbolic solver in the saturation equation.
279  HyperbolicData<RegionMesh> dataSaturationHyperbolic;
280 
281  // Create the data file for the non-linear and transient Darcy solver in the saturation equation.
282  DarcyData<RegionMesh> dataSaturationDarcyNonLinear;
283 
284  // Set up the data for the pressure equation.
285  dataPressure.setup ( dataFile, Members->discretization_section_darcy );
286 
287  // Set up the data for the hyperbolic solver.
288  dataSaturationHyperbolic.setup ( dataFile, Members->discretization_section_hyperbolic );
289 
290  // Set up the data for the non-linear and transient Darcy solver.
291  dataSaturationDarcyNonLinear.setup ( dataFile, Members->discretization_section_darcy_nonlin_trans );
292 
293  // Create the mesh file handler.
294  MeshData meshData;
295 
296  // Set up the mesh file.
297  meshData.setup ( dataFile, Members->discretization_section + "/space_discretization");
298 
299  // Create the mesh.
300  std::shared_ptr<RegionMesh> fullMeshPtr ( new RegionMesh ( * ( Members->comm ) ) );
301 
302  // Set up the mesh.
303  readMesh ( *fullMeshPtr, meshData );
304 
305  // Partition the mesh using ParMetis.
306  std::shared_ptr<RegionMesh> meshPtr;
307  {
308  MeshPartitioner< RegionMesh > meshPart ( fullMeshPtr, Members->comm );
309  meshPtr = meshPart.meshPartition();
310  }
311 
312  // Stop chronoReadAndPartitionMesh.
313  chronoReadAndPartitionMesh.stop();
314 
315  // The leader process print chronoReadAndPartitionMesh.
316  if ( isLeader )
317  std::cout << "Time for read and partition the mesh " <<
318  chronoReadAndPartitionMesh.diff() << std::endl << std::flush;
319 
320  // Create the boundary conditions.
321 
322  // Start chronoBoundaryCondition for measure the total time for create the boundary conditions.
323  chronoBoundaryCondition.start();
324 
325  BCFunctionBase pressureDirichletBDfun1,
326  pressureDirichletBDfun2,
327  pressureDirichletBDfun3,
328  pressureNeumannBDfun;
329 
330  BCFunctionBase saturationDirichletBDfun1,
331  saturationDirichletBDfun2,
332  saturationDirichletBDfun3,
333  saturationNeumannBDfun;
334 
335  //BCFunctionRobin pressureRobinBDfun, saturationRobinBDfun;
336 
337  // Set pressure bounday data.
338  pressureDirichletBDfun1.setFunction ( dataProblem::pressureDirichlet1 );
339  pressureDirichletBDfun2.setFunction ( dataProblem::pressureDirichlet2 );
340  pressureDirichletBDfun3.setFunction ( dataProblem::pressureDirichlet3 );
341 
342  pressureNeumannBDfun.setFunction ( dataProblem::pressureNeumann );
343 
344  // dp/dn = first_parameter + second_parameter * p.
345  //pressureRobinBDfun.setFunctions_Robin ( dataProblem::pressureRobin,
346  // Members->getUOne() );
347 
348  // Set pressure bounday data.
349  saturationDirichletBDfun1.setFunction ( dataProblem::saturationDirichlet1 );
350  saturationDirichletBDfun2.setFunction ( dataProblem::saturationDirichlet2 );
351  saturationDirichletBDfun3.setFunction ( dataProblem::saturationDirichlet3 );
352 
353  saturationNeumannBDfun.setFunction ( dataProblem::saturationNeumann );
354  // dp/dn = first_parameter + second_parameter * p.
355  //pressureRobinBDfun.setFunctions_Robin ( dataProblem::saturationRobin,
356  // Members->getUOne() );
357 
358  // Boundary condition handler for the pressure equation.
359  BCHandler bcPressure;
360 
361  // Boundary condition handler for the saturation equation.
362  BCHandler bcSaturation;
363 
364  bcPressure.addBC ( "Top", FLUX0, Natural, Full, pressureNeumannBDfun, 0 );
365  bcPressure.addBC ( "Top2", FLUX1, Natural, Full, pressureNeumannBDfun, 0 );
366  bcPressure.addBC ( "InletPressure", INLETPRESSURE1, Essential, Scalar, pressureDirichletBDfun1 );
367  bcPressure.addBC ( "InletPressure1", INLETPRESSURE2, Essential, Scalar, pressureDirichletBDfun3 );
368  bcPressure.addBC ( "OutletPressure", OUTLETPRESSURE, Essential, Scalar, pressureDirichletBDfun2 );
369 
370  bcSaturation.addBC ( "Top", FLUX0, Natural, Full, saturationNeumannBDfun, 0 );
371  bcSaturation.addBC ( "Top2", FLUX1, Natural, Full, saturationNeumannBDfun, 0 );
372  bcSaturation.addBC ( "InletPressure", INLETPRESSURE1, Essential, Scalar, saturationDirichletBDfun1 );
373  bcSaturation.addBC ( "InletPressure1", INLETPRESSURE2, Essential, Scalar, saturationDirichletBDfun3 );
374  bcSaturation.addBC ( "OutletPressure", OUTLETPRESSURE, Essential, Scalar, saturationDirichletBDfun2 );
375 
376  // Setting the boundary condition for the pressure equation.
377  //bcPressure.addBC( "Top", TOP, Essential, Scalar, pressureDirichletBDfun1 );
378  //bcPressure.addBC("Bottom", BOTTOM, Essential, Scalar, pressureDirichletBDfun1 );
379  //bcPressure.addBC( "Left", LEFT, Essential, Scalar, pressureDirichletBDfun1 );
380  //bcPressure.addBC( "Right", RIGHT, Essential, Scalar, pressureDirichletBDfun1 );
381  //bcPressure.addBC( "Front", FRONT, Essential, Scalar, pressureDirichletBDfun1 );
382  //bcPressure.addBC( "Back", BACK, Essential, Scalar, pressureDirichletBDfun1 );
383 
384  // Setting the boundary condition for the saturation equation.
385  //bcSaturation.addBC( "Top", TOP, Essential, Scalar, saturationDirichletBDfun1 );
386  //bcSaturation.addBC("Bottom", BOTTOM, Essential, Scalar, saturationDirichletBDfun1 );
387  //bcSaturation.addBC( "Left", LEFT, Essential, Scalar, saturationDirichletBDfun1 );
388  //bcSaturation.addBC( "Right", RIGHT, Essential, Scalar, saturationDirichletBDfun1 );
389  //bcSaturation.addBC( "Front", FRONT, Essential, Scalar, saturationDirichletBDfun1 );
390  //bcSaturation.addBC( "Back", BACK, Essential, Scalar, saturationDirichletBDfun1 );
391 
392  // Stop chronoBoundaryCondition.
393  chronoBoundaryCondition.stop();
394 
395  // The leader process print chronoBoundaryCondition.
396  if ( isLeader )
397  {
398  std::cout << "Time for create the boundary conditions handler " <<
399  chronoBoundaryCondition.diff() << std::endl << std::flush;
400 
401  }
402 
403  // Create the solution spaces.
404 
405  // Start chronoFiniteElementSpace for measure the total time for create the finite element spaces.
406  chronoFiniteElementSpace.start();
407 
408  // We impose directly the compatibily condition on the FE spaces.
409 
410  // Parameters for the pressure equation.
411  const ReferenceFE* pressure_refFE_primal ( static_cast<ReferenceFE*> (NULL) );
412  const QuadratureRule* pressure_qR_primal ( static_cast<QuadratureRule*> (NULL) );
413  const QuadratureRule* pressure_bdQr_primal ( static_cast<QuadratureRule*> (NULL) );
414 
415  pressure_refFE_primal = &feTetraP0;
416  pressure_qR_primal = &quadRuleTetra15pt;
417  pressure_bdQr_primal = &quadRuleTria4pt;
418 
419  // Dual solution parameters.
420  const ReferenceFE* pressure_refFE_dual ( static_cast<ReferenceFE*> (NULL) );
421  const QuadratureRule* pressure_qR_dual ( static_cast<QuadratureRule*> (NULL) );
422  const QuadratureRule* pressure_bdQr_dual ( static_cast<QuadratureRule*> (NULL) );
423 
424  pressure_refFE_dual = &feTetraRT0;
425  pressure_qR_dual = &quadRuleTetra15pt;
426  pressure_bdQr_dual = &quadRuleTria4pt;
427 
428  // Interpolate of dual solution parameters.
429  const ReferenceFE* pressure_refFE_dualInterpolate ( static_cast<ReferenceFE*> (NULL) );
430  const QuadratureRule* pressure_qR_dualInterpolate ( static_cast<QuadratureRule*> (NULL) );
431  const QuadratureRule* pressure_bdQr_dualInterpolate ( static_cast<QuadratureRule*> (NULL) );
432 
433  pressure_refFE_dualInterpolate = &feTetraP0;
434  pressure_qR_dualInterpolate = &quadRuleTetra15pt;
435  pressure_bdQr_dualInterpolate = &quadRuleTria4pt;
436 
437  // Hybrid solution parameters.
438  // hybrid.
439  const ReferenceFE* pressure_refFE_hybrid ( static_cast<ReferenceFE*> (NULL) );
440  const QuadratureRule* pressure_qR_hybrid ( static_cast<QuadratureRule*> (NULL) );
441  const QuadratureRule* pressure_bdQr_hybrid ( static_cast<QuadratureRule*> (NULL) );
442 
443  pressure_refFE_hybrid = &feTetraRT0Hyb;
444  pressure_qR_hybrid = &quadRuleTetra15pt;
445  pressure_bdQr_hybrid = &quadRuleTria4pt;
446 
447  // dual dot outward unit normal.
448  const ReferenceFE* pressure_refFE_VdotN ( static_cast<ReferenceFE*> (NULL) );
449  const QuadratureRule* pressure_qR_VdotN ( static_cast<QuadratureRule*> (NULL) );
450  const QuadratureRule* pressure_bdQr_VdotN ( static_cast<QuadratureRule*> (NULL) );
451 
452  pressure_refFE_VdotN = &feTetraRT0VdotNHyb;
453  pressure_qR_VdotN = &quadRuleTetra15pt;
454  pressure_bdQr_VdotN = &quadRuleTria4pt;
455 
456 
457  // Finite element space of the primal variable.
458  feSpacePtr_Type pressure_p_FESpacePtr ( new feSpace_Type ( meshPtr, *pressure_refFE_primal, *pressure_qR_primal,
459  *pressure_bdQr_primal, 1, Members->comm ) );
460 
461  // Finite element space of the dual variable.
462  feSpacePtr_Type pressure_u_FESpacePtr ( new feSpace_Type ( meshPtr, *pressure_refFE_dual, *pressure_qR_dual,
463  *pressure_bdQr_dual, 1, Members->comm ) );
464 
465  // Finite element space of the interpolation of dual variable.
466  feSpacePtr_Type pressure_uInterpolate_FESpacePtr ( new feSpace_Type ( meshPtr, *pressure_refFE_dualInterpolate,
467  *pressure_qR_dualInterpolate,
468  *pressure_bdQr_dualInterpolate, 3, Members->comm ) );
469 
470  // Vector for the interpolated dual solution.
471  vector_ptrtype pressure_dualInterpolated ( new vector_type ( pressure_uInterpolate_FESpacePtr->map(), Repeated ) );
472 
473  // Finite element space of the hybrid variable.
474  FESpace< RegionMesh, MapEpetra > pressure_hybrid_FESpace ( meshPtr, *pressure_refFE_hybrid, *pressure_qR_hybrid,
475  *pressure_bdQr_hybrid, 1, Members->comm );
476 
477  // Finite element space of the outward unit normal variable.
478  FESpace< RegionMesh, MapEpetra > pressure_VdotN_FESpace ( meshPtr, *pressure_refFE_VdotN, *pressure_qR_VdotN,
479  *pressure_bdQr_VdotN, 1, Members->comm );
480 
481  // Parameters for the saturation equation.
482 
483  // Hyperbolic parameters.
484  const ReferenceFE* saturation_hyperbolic_refFE ( static_cast<ReferenceFE*> (NULL) );
485  const QuadratureRule* saturation_hyperbolic_qR ( static_cast<QuadratureRule*> (NULL) );
486  const QuadratureRule* saturation_hyperbolic_bdQr ( static_cast<QuadratureRule*> (NULL) );
487 
488  saturation_hyperbolic_refFE = pressure_refFE_primal;
489  saturation_hyperbolic_qR = pressure_qR_primal;
490  saturation_hyperbolic_bdQr = &quadRuleTria1pt;
491 
492  // Finite element space.
493  feSpacePtr_Type saturation_hyperbolic_FESpacePtr ( new feSpace_Type ( meshPtr, *saturation_hyperbolic_refFE,
494  *saturation_hyperbolic_qR,
495  *saturation_hyperbolic_bdQr, 1, Members->comm ) );
496 
497  GhostHandler<RegionMesh> ghost ( fullMeshPtr, meshPart.meshPartition(), saturation_hyperbolic_FESpacePtr->mapPtr(), Members->comm );
498 
499  // Non-linear and transient Darcy parameters.
500 
501  // Primal solution parameters.
502  const ReferenceFE* saturation_darcy_refFE_primal ( static_cast<ReferenceFE*> (NULL) );
503  const QuadratureRule* saturation_darcy_qR_primal ( static_cast<QuadratureRule*> (NULL) );
504  const QuadratureRule* saturation_darcy_bdQr_primal ( static_cast<QuadratureRule*> (NULL) );
505 
506  saturation_darcy_refFE_primal = pressure_refFE_primal;
507  saturation_darcy_qR_primal = pressure_qR_primal;
508  saturation_darcy_bdQr_primal = pressure_bdQr_dual;
509 
510  // Dual solution parameters.
511  const ReferenceFE* saturation_darcy_refFE_dual ( static_cast<ReferenceFE*> (NULL) );
512  const QuadratureRule* saturation_darcy_qR_dual ( static_cast<QuadratureRule*> (NULL) );
513  const QuadratureRule* saturation_darcy_bdQr_dual ( static_cast<QuadratureRule*> (NULL) );
514 
515  saturation_darcy_refFE_dual = pressure_refFE_dual;
516  saturation_darcy_qR_dual = pressure_qR_dual;
517  saturation_darcy_bdQr_dual = pressure_bdQr_dual;
518 
519  // Hybrid solution parameters.
520  // hybrid.
521  const ReferenceFE* saturation_darcy_refFE_hybrid ( static_cast<ReferenceFE*> (NULL) );
522  const QuadratureRule* saturation_darcy_qR_hybrid ( static_cast<QuadratureRule*> (NULL) );
523  const QuadratureRule* saturation_darcy_bdQr_hybrid ( static_cast<QuadratureRule*> (NULL) );
524 
525  saturation_darcy_refFE_hybrid = pressure_refFE_hybrid;
526  saturation_darcy_qR_hybrid = pressure_qR_hybrid;
527  saturation_darcy_bdQr_hybrid = pressure_bdQr_hybrid;
528 
529  // dual dot outward unit normal.
530  const ReferenceFE* saturation_darcy_refFE_VdotN ( static_cast<ReferenceFE*> (NULL) );
531  const QuadratureRule* saturation_darcy_qR_VdotN ( static_cast<QuadratureRule*> (NULL) );
532  const QuadratureRule* saturation_darcy_bdQr_VdotN ( static_cast<QuadratureRule*> (NULL) );
533 
534  saturation_darcy_refFE_VdotN = pressure_refFE_VdotN;
535  saturation_darcy_qR_VdotN = pressure_qR_VdotN;
536  saturation_darcy_bdQr_VdotN = pressure_bdQr_VdotN;
537 
538 
539  // Finite element space of the primal variable.
540  FESpace< RegionMesh, MapEpetra > saturation_darcy_p_FESpace ( meshPtr, *saturation_darcy_refFE_primal,
541  *saturation_darcy_qR_primal,
542  *saturation_darcy_bdQr_primal, 1, Members->comm );
543 
544  // Finite element space of the dual variable.
545  FESpace< RegionMesh, MapEpetra > saturation_darcy_u_FESpace ( meshPtr, *saturation_darcy_refFE_dual,
546  *saturation_darcy_qR_dual,
547  *saturation_darcy_bdQr_dual, 1, Members->comm );
548 
549  // Finite element space of the hybrid variable.
550  FESpace< RegionMesh, MapEpetra > saturation_darcy_hybrid_FESpace ( meshPtr, *saturation_darcy_refFE_hybrid,
551  *saturation_darcy_qR_hybrid,
552  *saturation_darcy_bdQr_hybrid, 1, Members->comm );
553 
554  // Finite element space of the outward unit normal variable.
555  FESpace< RegionMesh, MapEpetra > saturation_darcy_VdotN_FESpace ( meshPtr, *saturation_darcy_refFE_VdotN,
556  *saturation_darcy_qR_VdotN,
557  *saturation_darcy_bdQr_VdotN, 1, Members->comm );
558 
559 
560  // Stop chronoFiniteElementSpace.
561  chronoFiniteElementSpace.stop();
562 
563  // The leader process print chronoFiniteElementSpace.
564  if ( isLeader )
565  std::cout << "Time for create the finite element spaces " <<
566  chronoFiniteElementSpace.diff() << std::endl << std::flush;
567 
568  // Start chronoProblem for measure the total time for create the problem.
569  chronoProblem.start();
570 
571  // Instantiation of the pressure equation solver, i.e. the Darcy solver.
572  ds pressureSolver ( dataPressure, *pressure_p_FESpacePtr, *pressure_u_FESpacePtr,
573  pressure_hybrid_FESpace, pressure_VdotN_FESpace, Members->comm );
574 
575  // Instantiation of the saturation equation solver.
576 
577  // Instantiation of the hyperbolic solver.
578  hyper saturationHyperbolicSolver ( dataSaturationHyperbolic,
579  *saturation_hyperbolic_FESpacePtr,
580  ghost.ghostMapOnElementsP0(),
581  Members->comm );
582 
583  // Instantiation of the non-linear and transient Darcy solver.
584  dstnl saturationDarcySolver ( dataSaturationDarcyNonLinear, saturation_darcy_p_FESpace,
585  saturation_darcy_u_FESpace, saturation_darcy_hybrid_FESpace,
586  saturation_darcy_VdotN_FESpace, Members->comm );
587 
588  // Stop chronoProblem.
589  chronoProblem.stop();
590 
591  // The leader process print chronoProblem.
592  pressureSolver.getDisplayer().leaderPrint ( "Time for create the problem ",
593  chronoProblem.diff(), "\n" );
594 
595  // Process the problem.
596 
597  // Start chronoProcess for measure the total time for the simulation.
598  chronoProcess.start();
599 
600  // Set up for the pressure equation.
601 
602  // Set up phase for the linear solver for the pressure equation.
603  pressureSolver.setup();
604 
605  // Create the inverse permeability.
606  inversePermeability < RegionMesh > invPermPress ( Members->getPressurePermeability(),
607  saturation_darcy_p_FESpace );
608 
609  // Set the saturation dependence for the permeability tensor.
610  invPermPress.setField ( saturationDarcySolver.primalSolution() );
611 
612  // Set the inverse of the permeability in the pressure equation.
613  pressureSolver.setInversePermeability ( invPermPress );
614 
615  // Set the source term in the pressure equation.
616  pressureSolver.setSource ( Members->getPressureSource() );
617 
618  // Set the boudary conditions.
619  pressureSolver.setBC ( bcPressure );
620 
621  // Set up for the saturation equation.
622 
623  // Set up for the hyperbolic solver in the saturation equation.
624  saturationHyperbolicSolver.setup();
625 
626  // Create the numerical flux
627  GodunovNumericalFlux < RegionMesh > numericalFlux ( Members->getSaturationPhysicalFlux(),
628  Members->getSaturationFirstDerivativePhysicalFlux(),
629  *pressure_uInterpolate_FESpacePtr,
630  dataFile,
631  "impes/hyperbolic/numerical_flux/" );
632 
633  // Set the dependence field
634  numericalFlux.setExternalField ( pressure_dualInterpolated );
635 
636  // Set the numerical flux usign the physical flux
637  saturationHyperbolicSolver.setNumericalFlux ( numericalFlux );
638 
639  // Set the porosity
640  saturationHyperbolicSolver.setMassTerm ( Members->getSaturationMass() );
641 
642  // Set the boudary conditions.
643  saturationHyperbolicSolver.setBoundaryCondition ( bcSaturation );
644 
645  // Set up for the non-linear and transient Darcy solver in the saturation equation.
646 
647  // Set up phase for the linear solver.
648  saturationDarcySolver.setup();
649 
650  // Create the inverse permeability.
651  inversePermeability < RegionMesh > invPermSat ( Members->getSaturationPermeability(),
652  saturation_darcy_p_FESpace );
653 
654  // Set the inverse of the permeability.
655  saturationDarcySolver.setInversePermeability ( invPermSat );
656 
657  // Set the initial solution.
658  saturationDarcySolver.setInitialPrimal ( Members->getSaturationInitialCondition() );
659 
660  // Set the source term.
661  saturationDarcySolver.setSource ( Members->getSaturationSource() );
662 
663  // Set the boudary conditions.
664  saturationDarcySolver.setBC ( bcSaturation );
665 
666  // Set the exporter for the solution.
667  std::shared_ptr< Exporter< RegionMesh > > exporter;
668 
669  // Shared pointer used in the exporter for the pressure in the pressure equation.
670  vector_ptrtype pressureExporter;
671 
672  // Shared pointer in the exporter for the saturation in the saturation equation.
673  vector_ptrtype saturationExporter;
674 
675  // Type of the exporter.
676  std::string const exporterType = dataFile ( "exporter/type", "ensight");
677 
678  // Choose the exporter.
679 #ifdef HAVE_HDF5
680  if ( exporterType.compare ("hdf5") == 0 )
681  {
682  exporter.reset ( new ExporterHDF5< RegionMesh > ( dataFile, dataFile ( "exporter/file_name", "PressureSaturation" ) ) );
683 
684  // Set directory where to save the solution.
685  exporter->setPostDir ( dataFile ( "exporter/folder", "./" ) );
686 
687  exporter->setMeshProcId ( meshPtr, Members->comm->MyPID() );
688  }
689  else
690 #endif
691  {
692  if ( exporterType.compare ("none") == 0 )
693  {
694  exporter.reset ( new ExporterEmpty< RegionMesh > ( dataFile, dataFile ( "exporter/file_name", "PressureSaturation" ) ) );
695 
696  // Set directory where to save the solution.
697  exporter->setPostDir ( dataFile ( "exporter/folder", "./" ) );
698 
699  exporter->setMeshProcId ( meshPtr, Members->comm->MyPID() );
700  }
701  else
702  {
703  exporter.reset ( new ExporterEnsight< RegionMesh > ( dataFile, dataFile ( "exporter/file_name", "PressureSaturation" ) ) );
704 
705  // Set directory where to save the solution.
706  exporter->setPostDir ( dataFile ( "exporter/folder", "./" ) );
707 
708  exporter->setMeshProcId ( meshPtr, Members->comm->MyPID() );
709  }
710  }
711 
712  // Set the exporter pressure pointer.
713  pressureExporter.reset ( new vector_type ( *pressureSolver.primalSolution(), exporter->mapType() ) );
714 
715  // Add the pressure variable to the exporter.
716  exporter->addVariable ( ExporterData<RegionMesh>::ScalarField, "Pressure",
717  pressure_p_FESpacePtr, pressureExporter,
718  static_cast<UInt> ( 0 ),
719  ExporterData< RegionMesh >::UnsteadyRegime,
720  ExporterData< RegionMesh >::Cell );
721 
722  // Set the exporter saturation pointer.
723  saturationExporter.reset ( new vector_type ( *saturationHyperbolicSolver.solution(), exporter->mapType() ) );
724 
725  // Add the solution to the exporter.
726  exporter->addVariable ( ExporterData<RegionMesh>::ScalarField, "Saturation",
727  saturation_hyperbolic_FESpacePtr, saturationExporter,
728  static_cast<UInt> ( 0 ),
729  ExporterData< RegionMesh >::UnsteadyRegime,
730  ExporterData< RegionMesh >::Cell );
731 
732  // Display the total number of unknowns.
733  pressureSolver.getDisplayer().leaderPrint ( "Number of unknowns : ",
734  2.*pressure_hybrid_FESpace.map().map (Unique)->NumGlobalElements() +
735  saturation_hyperbolic_FESpacePtr->map().map (Unique)->NumGlobalElements(), "\n" );
736 
737  // Solve the problem.
738 
739  // Save the initial primal.
740 
741  // Copy the saturation initial solution to the exporter.
742  *saturationExporter = *saturationDarcySolver.primalSolution();
743 
744  // Save the initial solution into the exporter.
745  exporter->postProcess ( dataSaturationHyperbolic.dataTime()->initialTime() );
746 
747  // Update the time for the simulation
748  dataSaturationDarcyNonLinear.dataTime()->updateTime();
749 
750  // Outher loop for the simulation, it starts from \Delta t and end in N \Delta t = T.
751  for ( ; dataSaturationDarcyNonLinear.dataTime()->canAdvance(); dataSaturationDarcyNonLinear.dataTime()->updateTime() )
752  {
753 
754  // The leader process prints the temporal data.
755  if ( saturationDarcySolver.getDisplayer().isLeader() )
756  {
757  dataSaturationDarcyNonLinear.dataTime()->showMe();
758  }
759 
760  // Solve the pressure equation.
761 
762  // Build the linear system and the right hand side.
763  pressureSolver.buildSystem();
764 
765  // Solve the linear system.
766  pressureSolver.solve();
767 
768  // Post process of the global pressure and total velocity.
769  pressureSolver.computePrimalAndDual();
770 
771  // Interpolate the Darcy velocity
772  *pressure_dualInterpolated = pressure_uInterpolate_FESpacePtr->feToFEInterpolate ( *pressure_u_FESpacePtr,
773  *pressureSolver.dualSolution() );
774 
775  // Solve the saturation equation.
776 
777  // Solve the hyperbolic part of the saturation equation.
778 
779  // Set the initial condition for the inner loop
780  saturationHyperbolicSolver.setSolution ( saturationDarcySolver.primalSolution() );
781 
782  // Set the time parameters for the hyperbolic part of the saturation equation.
783 
784  // Set the initial time.
785  dataSaturationHyperbolic.dataTime()->setInitialTime ( dataSaturationDarcyNonLinear.dataTime()->time() );
786 
787  // Set the current time as initial time.
788  dataSaturationHyperbolic.dataTime()->setTime ( dataSaturationDarcyNonLinear.dataTime()->time() );
789 
790  // Define the inner time step.
791  Real innerTimeStep ( 0. );
792 
793  // Set the end time.
794  dataSaturationHyperbolic.dataTime()->setEndTime ( dataSaturationDarcyNonLinear.dataTime()->nextTime() );
795 
796  // Define if the current time is the last time step.
797  bool isLastTimeStep ( false );
798 
799  // Inner loop for the simulation, it starts form N \Delta t and end in ( N + 1 ) \Delta t.
800  for ( ; dataSaturationHyperbolic.dataTime()->canAdvance() && !isLastTimeStep; dataSaturationHyperbolic.dataTime()->updateTime() )
801  {
802 
803  // The leader process prints the temporal data for the inner loop.
804  saturationHyperbolicSolver.getDisplayer().leaderPrint ( "Inner loop for sub-temporal iteration for the hyperbolic equation.\n" );
805 
806  // Compute the new time step according to the CFL condition.
807  //innerTimeStep = saturationHyperbolicSolver.CFL();
808 
809  // Check if the time step is consistent, i.e. if innerTimeStep + currentTime < endTime.
810  if ( dataSaturationHyperbolic.dataTime()->isLastTimeStep() )
811  {
812  // Compute the last time step.
813  innerTimeStep = dataSaturationHyperbolic.dataTime()->leftTime();
814 
815  // This is the last time step in the simulation
816  isLastTimeStep = true;
817  }
818 
819  // Set the new time step in the dataHyperbolic.
820  //dataSaturationHyperbolic.dataTime()->setTimeStep( innerTimeStep );
821 
822  // The leader process prints the temporal data for the inner loop.
823  if ( saturationHyperbolicSolver.getDisplayer().isLeader() )
824  {
825  dataSaturationHyperbolic.dataTime()->showMe();
826  }
827 
828  // solve one step of the hyperbolic problem.
829  saturationHyperbolicSolver.solveOneTimeStep();
830 
831  }
832 
833  // Solve the parabolic part of the saturation equation.
834 
835  // Set the new previous time step solution.
836  saturationDarcySolver.setPrimalSolution ( saturationHyperbolicSolver.solution() );
837  saturationDarcySolver.updatePrimalOldSolution();
838 
839  // Start the fixed point simulation.
840  saturationDarcySolver.fixedPointScheme();
841 
842  // Save the solution.
843 
844  // Copy the pressure solution to the exporter.
845  *pressureExporter = *pressureSolver.primalSolution();
846 
847  // Copy the saturation solution to the exporter.
848  *saturationExporter = *saturationDarcySolver.primalSolution();
849 
850  // Save the solution into the exporter.
851  exporter->postProcess ( dataSaturationDarcyNonLinear.dataTime()->time() );
852  }
853 
854 
855  // Stop chronoProcess.
856  chronoProcess.stop();
857 
858  // The leader process print chronoProcess.
859  pressureSolver.getDisplayer().leaderPrint ( "Time for process ",
860  chronoProcess.diff(), "\n" );
861 
862  // Stop chronoTotal.
863  chronoTotal.stop();
864 
865  // The leader process print chronoTotal.
866  pressureSolver.getDisplayer().leaderPrint ( "Total time for the computation ",
867  chronoTotal.diff(), "\n" );
868 
869  return 0.;
870 
871 }
std::shared_ptr< Epetra_Comm > comm
Definition: impes.cpp:124
Real UOne(const Real &, const Real &, const Real &, const Real &, const ID &)
Definition: hyperbolic.cpp:193
Vfct_type getSaturationPhysicalFlux()
Definition: impes.cpp:163
BCNAME
Definition: impes.cpp:44
FESpace - Short description here please!
Definition: FESpace.hpp:78
LifeV::Real run()
Methods.
Definition: impes.cpp:234
const QuadratureRule quadRuleTetra15pt(pt_tetra_15pt, 5, "Quadrature rule 15 points on a tetraedra", TETRA, 15, 5)
Definition: impes.cpp:51
const QuadratureRule quadRuleTria4pt(pt_tria_4pt, 3, "Quadrature rule 4 points on a triangle", TRIANGLE, 4, 3)
Real UZero(const Real &, const Real &, const Real &, const Real &, const ID &)
Definition: hyperbolic.cpp:202
impes(int argc, char **argv)
Constructors.
Definition: impes.cpp:204
Mfct_type getPressurePermeability()
Definition: impes.cpp:149
fct_type getSaturationInitialCondition()
Definition: impes.cpp:156
Vfct_type getSaturationFirstDerivativePhysicalFlux()
Definition: impes.cpp:170
Mfct_type getSaturationPermeability()
Definition: impes.cpp:184
Definition: impes.hpp:61
std::function< Vector(const Real &, const Real &, const Real &, const Real &, const std::vector< Real > &) > Vfct_type
Definition: impes.cpp:101
Definition: impes.cpp:47
std::function< Matrix(const Real &, const Real &, const Real &, const Real &, const std::vector< Real > &) > Mfct_type
Definition: impes.cpp:108
Private Members.
Definition: impes.cpp:88
fct_type getSaturationSource()
Definition: impes.cpp:177
uint32_type ID
IDs.
Definition: LifeV.hpp:194
std::shared_ptr< std::vector< Int > > M_isOnProc
MeshData - class for handling spatial discretization.
Definition: MeshData.hpp:72
HyperbolicSolver Implements an hyperbolic solver.
double Real
Generic real data.
Definition: LifeV.hpp:175
std::function< Real(const Real &, const Real &, const Real &, const Real &, const ID &) > fct_type
Definition: impes.cpp:95
fct_type getUOne()
Definition: impes.cpp:128
The class for a reference Lagrangian finite element.
fct_type getPressureSource()
Definition: impes.cpp:142
fct_type getSaturationMass()
Definition: impes.cpp:191
fct_type getUZero()
Definition: impes.cpp:135
std::string data_file_name
Definition: impes.cpp:110
std::string discretization_section_hyperbolic
Definition: impes.cpp:119
std::string discretization_section_darcy
Definition: impes.cpp:116
contain the basic data for the Darcy solver.
Definition: DarcyData.hpp:61
std::string discretization_section_darcy_nonlin_trans
Definition: impes.cpp:122
QuadratureRule - The basis class for storing and accessing quadrature rules.
const QuadratureRule quadRuleTria1pt(pt_tria_1pt, 1, "Quadrature rule 1 point on a triangle", TRIANGLE, 1, 1)
std::string discretization_section
Definition: impes.cpp:113