LifeV
DarcySolverTransient.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory UNiversity
7 
8  This file is part of the LifeV library
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public
21  License along with this library; if not, see <http://www.gnu.org/licenses/>
22 
23 
24 *******************************************************************************
25 */
26 //@HEADER
27 
28 /*!
29  * @file
30  @brief This file contains a time dependent Darcy equation solver class
31 
32  @date 05/2010
33  @author A. Fumagalli <alessio.fumagalli@mail.polimi.it>
34 
35  @contributor M. Kern <michel.kern@inria.fr>
36  @maintainer M. Kern <michel.kern@inria.fr>
37  */
38 
39 
40 #ifndef _DARCYSOLVERTRANSIENT_H_
41 #define _DARCYSOLVERTRANSIENT_H_ 1
42 
43 #include <lifev/core/fem/TimeAdvanceBDF.hpp>
44 
45 #include <lifev/darcy/solver/DarcySolverLinear.hpp>
46 
47 // LifeV namespace.
48 namespace LifeV
49 {
50 //! @class DarcySolverTransient This class implements a mixed-hybrid FE Darcy solver for transient problems
51 
52 /*!
53  @author A. Fumagalli <alessio.fumagalli@mail.polimi.it>
54 
55  This class implements a transient Darcy solver in the finite time interval \f$ [0, T] \f$.
56  <br>
57  The classical time dependent Darcy formulation is a couple of differential equations of first order with
58  the unknowns \f$ p \in C^1(0, T; C^1 (\Omega )) \f$, being the pressure or the primal unknown,
59  and \f$ \sigma \in C^0(0, T; (C^1( \Omega ) )^n) \f$, being the Darcy velocity or the flux or the dual unknown,
60  such that
61  \f[
62  \left\{
63  \begin{array}{l l l}
64  \Lambda^{-1}(t) \sigma + \nabla p = f_v(t) & \mathrm{in} & \Omega \times [0, T]\,, \vspace{0.2cm} \\
65  \displaystyle \phi \frac{\partial p}{\partial t} + \nabla \cdot \sigma + \pi(t) p - f(t) = 0 & \mathrm{in} & \Omega \times [0, T]\,, \vspace{0.2cm} \\
66  p = g_D(t) & \mathrm{on} & \Gamma_D \times [0, T]\,, \vspace{0.2cm} \\
67  \sigma \cdot n + h(t) p = g_R(t) & \mathrm{on} & \Gamma_R \times [0, T]\,. \vspace{0.2cm} \\
68  p(0) = p_0 & \mathrm{in} & \Omega
69  \end{array}
70  \right.
71  \f]
72  The data in the system are:
73  <ul>
74  <li> \f$ p_0 \f$ the primal variable at initial time; </li>
75  <li> \f$ \phi \f$ the mass term, which does not depend on time; </li>
76  <li> \f$ \Lambda(t) \f$ the permeability tensor; </li>
77  <li> \f$ f(t) \f$ the scalar source term; </li>
78  <li> \f$ f_v(t) \f$ the vector source term; </li>
79  <li> \f$ \pi(t) \f$ the reaction coefficient; </li>
80  <li> \f$ \Gamma_D \f$ the subset of the boundary of \f$ \Omega \f$ with Dirichlet boundary conditions; </li>
81  <li> \f$ g_D(t) \f$ Dirichlet boundary condition data; </li>
82  <li> \f$ \Gamma_R \f$ that is the part of the boundary of \f$ \Omega \f$ with Robin, or Neumann, boundary conditions; </li>
83  <li> \f$ h(t) \f$ and \f$ g_R(t) \f$ Robin boundary condition data; </li>
84  </ul>
85  We suppose that \f$ \partial \Omega = \Gamma_D \cup \Gamma_R \f$ and \f$ \Gamma_D \cap \Gamma_R = \emptyset \f$.
86  <br>
87  Using the hybridization procedure, and introducing a new variable, we may split the problem from
88  the entire domain to problems in each elements of the triangulation \f$ \mathcal{T}_h \f$, then we may write
89  the weak formulation for the dual problem.
90  The new variable is the hybrid unknown \f$ \lambda \f$, e.g. "the trace" of pressure of the primal unknown,
91  it is the Lagrange multipliers forcing the continuity of the flux across each faces or edges in the triangulation.
92  We introduce the following functional spaces, the first is the space of the primal variable, the third for
93  the dual variable, the fourth for the hybrid variable.
94  \f[
95  \begin{array}{l}
96  V = L^2 (\Omega ) \,,\vspace{0.2cm} \\
97  H(div, K) = \displaystyle \left\{ \tau \in ( L^2(K))^n : \nabla \cdot \tau \in L^2(K)\right\}\,, \vspace{0.2cm}\\
98  Z = \displaystyle \left\{ \tau \in L^2(\Omega) : \tau\vert_K \in H(div, K) \, \forall K \in \mathcal{T}_h \right\}\,, \vspace{0.2cm}\\
99  \Lambda = \displaystyle \left\{ \lambda \in \prod_{K \in \mathcal{T}_h} H^{1/2} (\partial K): \lambda_K = \lambda_{K'} \,\, \mathrm{on} \,\, e_{K-K'} \, \forall K \in \mathcal{T}_h,\, \lambda = g_D \,\, \mathrm{on} \,\, \Gamma_D \right\}\,.
100  \end{array}
101  \f]
102  Introducing the following bilinear forms and functionals at fixed time \f$ t \in [0, T] \f$
103  \f[
104  \begin{array}{l l}
105  a(\sigma(t), \tau) = \displaystyle \sum_{K \in \mathcal{T}_h}\int_K \Lambda^{-1}(t) \sigma(t) \cdot \tau \,, &
106  b(p(t), \tau) = \displaystyle -\sum_{K \in \mathcal{T}_h} \int_K p(t) \nabla \cdot \tau\,, \vspace{0.2cm}\\
107  c(\lambda(t), \tau) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_{\partial K} \lambda(t) \tau \cdot n\,,&
108  d(p(t), v) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_{\partial K} \pi(t) p(t) v \,,\vspace{0.2cm}\\
109  h(\lambda(t), \mu) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_{\partial K \cap \Gamma_R} h(t) \mu \lambda(t) \,,&
110  m(p(t), v) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_K \phi p(t) v \,,\vspace{0.2cm}\\
111  F(v) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_K f(t) v\,,&
112  F_v(\tau) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_K f_v(t) \tau \,, \vspace{0.2cm}\\
113  G(\mu) = \displaystyle \sum_{K \in \mathcal{T}_h} \int_{\partial K \cap \Gamma_R} g(t) \mu\,,
114  \end{array}
115  \f]
116  we obtain the Darcy problem in the weak form: find \f$ (\sigma(t), \, p(t), \, \lambda(t)) \in Z \times V \times \Lambda \f$ such that
117  \f[
118  \left\{
119  \begin{array}{l l}
120  a(\sigma(t), \tau) + b(p(t), \tau) + c(\lambda(t), \tau) = F_v(\tau) \,, & \forall \tau \in Z \,,\vspace{0.2cm}\\
121  \displaystyle -\frac{\partial }{\partial t} m(p(t), v) + b(v, \sigma(t)) - d(p(t), v) = -F(v)\,, & \forall v \in V \,,\vspace{0.2cm}\\
122  c(\mu, \sigma(t)) + h(\lambda(t), \mu) = G(\mu) \,, & \forall \mu \in \Lambda\,.
123  \end{array}
124  \right.
125  \f]
126  At semi-discrete level. i.e. only space discretization is performed,
127  we introduce the polynomial space, of degree \f$ r \f$, that approximate the finite dimensional
128  spaces introduced above \f$ V_h \subset V \f$, \f$ Z_h \subset Z \f$ and \f$\Lambda_h \subset \Lambda \f$
129  \f[
130  \begin{array}{l}
131  V_h = \displaystyle \left\{ v_h \in V: v_h|_K \in P_r (K)\, \forall K \in \mathcal{T}_h \right\}\,, \vspace{0.2cm}\\
132  Z_h = \displaystyle \left\{ \tau_h \in Z: \tau_h|_K \in RT_r(K) \, \forall K \in \mathcal{T}_h \right\} \,, \vspace{0.2cm} \\
133  \Lambda_h = \displaystyle \left\{ \lambda_h \in \Lambda: \lambda_h|_{\partial K} \in R_r( \partial K ) \, \forall K \in \mathcal{T}_h\right\}\,,
134  \end{array}
135  \f]
136  where \f$ P_r(K) \f$ is the space of polynomial of degree \f$ r \f$ in the element \f$ K \f$, \f$ RT_r(K) \f$ is the space of
137  polynomial of Raviart-Thomas of degrees \f$ r \f$ in the element \f$ K \f$ and \f$ R_r(\partial K) \f$ is the space of polynomial of
138  degree \f$ r \f$ definite on each of the boundary of the element \f$ K \f$ and discontinuous from one edge to the other.
139  <br>
140  The finite dimensional problem is: find \f$ (\sigma_h(t),\, p_h(t), \, \lambda_h(t)) \in Z_h \times V_h \times \Lambda_h \f$ such that
141  \f[
142  \left\{
143  \begin{array}{l l}
144  a(\sigma_h(t), \tau_h) + b(p_h(t), \tau_h) + c(\lambda_h(t), \tau_h) = F_v(\tau_h) \,, & \forall \tau_h \in Z_h \,,\vspace{0.2cm}\\
145  \displaystyle -\frac{\partial }{\partial t} m(p_h(t),v_h) + b(v_h, \sigma_h(t)) - d(p_h(t), v_h) = -F(v_h)\,, & \forall v_h \in V_h \,,\vspace{0.2cm}\\
146  c(\mu_h, \sigma_h(t)) + h(\lambda_h(t), \mu_h) = G(\mu_h) \,, & \forall \mu_h \in \Lambda_h\,.
147  \end{array}
148  \right.
149  \f]
150  To obatin a fully discrete problem we discretize the time derivative via BDF (backward differentiation formulae) schemes of order \f$ m \f$,
151  with \f$ \Delta t \f$ as time step. Choosing
152  \f[
153  p_h^0 = \prod_{V_h} p_0
154  \f]
155  we obtain the following system for each \f$ n = 0, \ldots, N \f$, with \f$ N = \frac{T}{\Delta t} \f$
156  \f[
157  \left\{
158  \begin{array}{l l}
159  a(\sigma_h^{n+1}, \tau_h) + b(p_h^{n+1}, \tau_h) + c(\lambda_h^{n+1}, \tau_h) = F_v(\tau_h)\,, & \forall \tau_h \in Z_h \,,\vspace{0.2cm}\\
160  \displaystyle -\frac{\alpha_0}{\Delta t} m(p_h^{n+1},v_h) + b(v_h, \sigma_h^{n+1}) - d(p_h^{n+1}, v_h)= -F(v_h)
161  - \frac{1}{\Delta t} m\left( \sum_{i=1}^m \alpha_i p_h^{n+1-i}, v_h \right) \,, & \forall v_h \in V_h \,,\vspace{0.2cm}\\
162  c(\mu_h, \sigma_h^{n+1}) + h(\lambda_h^{n+1}, \mu_h) = G(\mu_h) \,, & \forall \mu_h \in \Lambda_h\,.
163  \end{array}
164  \right.
165  \f]
166  To solve the problem we use the static condensation procedure, i.e. the unknowns in the discrete
167  weak system are not independent and \f$ p_K \f$, \f$\sigma_K \f$ may be written in function of
168  \f$ \lambda_K \f$ alone. We introduce the following local matrices
169  \f[
170  \begin{array}{l l l}
171  \left[ A \right]_{ij} = \displaystyle \int_K \Lambda^{-1}( (n+1) \Delta t) \psi_j \cdot \psi_i \,, &
172  \left[ B \right]_{ij} = \displaystyle - \int_K \phi_j \nabla \cdot \psi_i \,, &
173  \left[ C \right]_{ij} = \displaystyle \int_{\partial K} \xi_i \psi_j \cdot n \,, \vspace{0.2cm} \\
174  \left[ D \right]_{ij} = \displaystyle \int_K \pi(t) \phi_j \phi_i\,, &
175  \left[ H \right]_{ij} = \displaystyle \int_{\partial K \cap \Gamma_R} h( (n+1) \Delta t) \xi_i \xi_j\,, &
176  \left[ M \right]_{ij} = \displaystyle \int_{K} \phi \phi_j \phi_i \,, \vspace{0.2cm} \\
177  \left[ F \right]_{j} = \displaystyle \int_K f( (n+1) \Delta t) \phi_j\,,&
178  \left[ F_v \right]_{j}= \displaystyle \int_K f_v( (n+1) \Delta t) \cdot \psi_j\,, &
179  \left[ G \right]_{j} = \displaystyle \int_{\partial K \cap \Gamma_R } g( (n+1) \Delta t) \xi_j\,,
180  \end{array}
181  \f]
182  where we avoid to write the dependence on the triangle \f$ K \f$ and on the current time step \f$ n+1 \f$ in all the matrices and vectors.
183  <br>
184  bre local matrix formulation of the finite dimensional problem is
185  \f[
186  \left\{
187  \begin{array}{l}
188  A \sigma_K^{n+1} + B p_K^{n+1} + C \lambda_K^{n+1} = F_v\,, \vspace{0.2cm} \\
189  \displaystyle -\frac{\alpha_0}{\Delta t} M p_K^{n+1} + B^T \sigma_K^{n+1} - D p_K^{n+1} = -F
190  - \frac{1}{\Delta t} M \sum_{i=1}^m \alpha_i p_K^{n+1-i} \,,\vspace{0.2cm}\\
191  C^T \sigma_K^{n+1} + H \lambda_K^{n+1} = G\,.
192  \end{array}
193  \right.
194  \f]
195  Or alternatively
196  \f[
197  \begin{array}{l l l}
198  \left[
199  \begin{array}{c c c}
200  A & B & C \vspace{0.2cm} \\
201  B^T & \displaystyle -\frac{\alpha_0}{\Delta t} M - D & 0 \vspace{0.2cm} \\
202  C^T & 0 & H
203  \end{array}
204  \right] \, \cdot &
205  \left[
206  \begin{array}{c}
207  \sigma_K^{n+1} \vspace{0.2cm}\\
208  p_K^{n+1} \vspace{0.2cm}\\
209  \lambda_K^{n+1}
210  \end{array}
211  \right] \, &
212  =
213  \left[
214  \begin{array}{c}
215  F_v \vspace{0.2cm}\\
216  \displaystyle - F - \frac{1}{\Delta t} M \sum_{i=1}^m \alpha_i p_K^{n+1-i} \vspace{0.2cm}\\
217  G
218  \end{array}
219  \right]\,.
220  \end{array}
221  \f]
222  Introducing the local hybrid matrix and local hybrid right hand side
223  \f[
224  \begin{array}{l}
225  \displaystyle L_K = -C^T A^{-1} C + C^T A^{-1} B \left( \frac{\alpha_0}{\Delta t} M + B^T A^{-1} B + D \right)^{-1} B^T A^{-1} C + H \,, \vspace{0.2cm} \\
226  \displaystyle r_K = G + C^T A^{-1} B \left( \frac{\alpha_0}{\Delta t} M + B^T A^{-1} B + D \right)^{-1}
227  \left( F + \frac{1}{\Delta t} M \sum_{i=1}^m \alpha_i p_K^{n+1-i} \right)
228  + C^T A^{-1} B \left( \frac{\alpha_0}{\Delta t}M + B^T A^{-1} B + D \right)^{-1} B^T A^{-1} F_v - C^T A^{-1} F_v \,,
229  \end{array}
230  \f]
231  Imposing that at each edge or face the hybrid unknown is single value we obtain a linear system for the hybrid unknown
232  \f[
233  L \lambda^{n+1} = r \,.
234  \f]
235  We recover the primal and dual variable as a post-process from the hybrid variable at element level, so we have
236  \f[
237  \begin{array}{l}
238  \displaystyle p_K^{n+1} = \left( \frac{\alpha_0}{\Delta t} M + B^T A^{-1} B + D\right)^{-1} \left( F + \frac{1}{\Delta t} M \sum_{i=1}^m \alpha_i p_K^{n+1-i}
239  - B^T A^{-1} C \lambda_K^{n+1} \right)\,, \vspace{0.2cm} \\
240  \sigma_K^{n+1} = -A^{-1} \left( B p_K^{n+1} + C \lambda_K^{n+1} \right) \,.
241  \end{array}
242  \f]
243  @note In the code we do not use the matrix \f$ H \f$ and the vector \f$ G \f$,
244  because all the boundary conditions are imposed via BCHandler class.
245  @note The initial time is not fixed at zero.
246  @note Example of usage can be found in darcy_nonlinear and darcy_linear.
247  Coupled with an hyperbolic solver in impes.
248  @todo Insert any scientific publications that use this solver.
249 */
250 template < typename MeshType >
252  virtual public DarcySolverLinear < MeshType >
253 {
254 
255 public:
256 
257  //! @name Public Types
258  //@{
259 
260  //! Typedef for mesh template.
261  typedef MeshType mesh_Type;
262 
263  //! Self typedef.
265 
266  //! Darcy solver class.
268 
269  //! Typedef for the data type.
271 
272  //! Shared pointer for the data type.
274 
275  //! Shared pointer to a scalar value function.
277 
278  //! Shared pointer to a distributed vector.
280 
281  //! Distributed vector.
283 
284  //! Shared pointer to a scalar field.
286 
287  //! Scalar field.
289 
290  //! Container of matrix elemental.
292 
293  //! Time advance scheme.
295 
296  //! Shared pointer to a time advance scheme.
298 
299  //@}
300 
301  //! @name Constructors & destructor
302  //@{
303 
304  //! Constructor for the class.
306 
307  //! Virtual destructor.
308  virtual ~DarcySolverTransient () {};
309 
310  //@}
311 
312  // Methods
313  //! @name methods
314  //@{
315 
316  //! Set up the linear solver and the preconditioner for the linear system.
317  virtual void setup ();
318 
319  //! Solve the problem.
320  virtual void solve ();
321 
322  //@}
323 
324  // Update and set Methods.
325  //! @name Update and set methods
326  //@{
327 
328  //! Initialize primal solution
329  /*!
330  Set the initial value function for the primal variable and compute the primal
331  variable at step zero.
332  @param primalInitial The primal initial function.
333  */
334  void setInitialPrimal ( const scalarFctPtr_Type& primalInitialFct );
335 
336  //! Set mass matrix
337  /*!
338  Set the mass term, the default source term is the function one.
339  By defaul it does not depend on time.
340  @param mass Mass term for the problem.
341  */
342  void setMass ( const scalarFctPtr_Type& massFct );
343 
344  //@}
345 
346 protected:
347 
348  // Methods
349  //! @name Protected methods
350  //@{
351 
352  //! Compute element matrices
353  /*!
354  Call the Darcy solver localMatrixComputation method and
355  compute the mass matrix for the time dependent term.
356  @param iElem Id of the current geometrical element.
357  @param elmatMix The local matrix in mixed form.
358  @param elmatReactionTerm The local matrix for the reaction term.
359  */
360  virtual void localMatrixComputation ( const UInt& iElem,
361  MatrixElemental& elmatMix,
362  MatrixElemental& elmatReactionTerm );
363 
364  //! Computes local vectors
365  /*!
366  Call the Darc_y solver localVectorComputation method and
367  compute the additional scalar vector for the time dependent term.
368  @param iElem Id of the current geometrical element.
369  @param elvecMix The local vector in mixed form.
370  */
371  virtual void localVectorComputation ( const UInt& iElem,
372  VectorElemental& elvecMix );
373 
374  //! Do some computation after the calculation of the primal and dual variable.
375  /*!
376  Save into the time advance scheme the computed primal solution.
377  */
378  virtual void postComputePrimalAndDual ()
379  {
380  // Update the solution in the time advance.
381  M_timeAdvance->shiftRight ( this->M_primalField->getVector() );
382  }
383 
384  //! Setup the time data.
385  void setupTime ();
386 
387  //@}
388 
389  // Time advance stuff
390  //! @name Time advance stuff
391  //@{
392 
393  //! Time advance.
395 
396  //! Right hand side coming from the time advance scheme.
398 
399  //@}
400 
401 private:
402 
403  // Private Constructors
404  //! @name Private Constructors
405  //@{
406 
407  //! Inhibited copy constructor.
409 
410  //@}
411 
412  // Private Operators
413  //! @name Private Operators
414  //@{
415 
416  //! Inhibited assign operator.
418 
419  //@}
420 
421  // Data of the problem.
422  //! @name Data of the problem
423  //@{
424 
425  //! Initial time primal variable.
427 
428  //! Mass function, it does not depend on time.
430 
431  //@}
432 
433  // Time advance stuff
434  //! @name Time advance stuff
435  //@{
436 
437  //! Local mass matrices.
439 
440  //@}
441 
442  // Algebraic stuff
443  //! @name Algebraic stuff
444  //@{
445 
446  //! Boolean that indicates if the preconditioner is re-used or not.
448 
449  //! Boolean that indicates if the matrix is updated for the current iteration.
450  bool M_updated;
451 
452  //! Interger storing the max number of solver iteration with preconditioner recomputing.
454 
455  //! Boolean that indicates if the matrix is recomputed for the current iteration.
457 
458  //@}
459 
460 }; // class DarcySolverTransient
461 
462 // IMPLEMENTATION
463 
464 // Complete constructor.
465 template < typename MeshType >
466 DarcySolverTransient < MeshType >::
468  // Standard Darcy solver constructor.
470  // Time advance data.
472  // Linear solver.
473  M_reusePrec ( false ),
474  M_updated ( false ),
475  M_maxIterSolver ( static_cast<UInt> (0) ),
476  M_recomputeMatrix ( false )
477 {
478 } // Constructor
479 
480 // ===========================================================================================
481 // Public methods
482 // ==========================================================================================
483 
484 // Set up the linear solver and the preconditioner.
485 template < typename MeshType >
486 void
487 DarcySolverTransient < MeshType >::
489 {
490 
491  // Call the DarcySolverLinear setup method for setting up the linear solver.
492  darcySolverLinear_Type::setup ();
493 
494  // Setup the time data
495  setupTime ();
496 
497 } // setup
498 
499 // Set up the linear solver and the preconditioner.
500 template < typename MeshType >
501 void
502 DarcySolverTransient < MeshType >::
504 {
505 
506  const typename darcySolverLinear_Type::data_Type::data_Type& dataFile = * ( this->M_data->dataFilePtr() );
507 
508  // Set if the preconditioner is re-used.
509  M_reusePrec = dataFile ( ( this->M_data->section() + "/solver/reuse" ).data(), false );
510 
511  // Set if the preconditioner is reused or not.
512  this->M_linearSolver.setReusePreconditioner ( M_reusePrec );
513 
514  // Set the max number of iteration to mantein the same preconditioner.
515  M_maxIterSolver = dataFile ( ( this->M_data->section() + "/solver/max_iter_reuse" ).data(), static_cast<Int> (0) );
516 
517  // Set up the time advance.
518  M_timeAdvance->setup ( this->M_data->dataTimeAdvancePtr()->orderBDF(), 1 );
519 
520 } // setupTime
521 
522 // Set the inital value
523 template < typename MeshType >
524 void
525 DarcySolverTransient < MeshType >::
526 setInitialPrimal ( const scalarFctPtr_Type& primalInitialFct )
527 {
528  // Set the initial value function.
529  M_primalFieldInitialFct = primalInitialFct;
530 
531  // Create the interpolated initial condition for the primal variable.
532  scalarField_Type primalInitialField ( this->M_primalField->getFESpacePtr(),
533  this->M_primalField->getVector().mapType() );
534 
535  // Interpolate the primal initial value.
536  M_primalFieldInitialFct->interpolate ( primalInitialField,
537  this->M_data->dataTimePtr()->initialTime() );
538 
539  // Set the initial condition for the time advance method.
540  M_timeAdvance->setInitialCondition ( primalInitialField.getVector() );
541 
542 } // setInitialPrimal
543 
544 // ===========================================================================================
545 // Protected methods
546 // ==========================================================================================
547 
548 // Perform all the operations before doing the loop on volume elements.
549 template < typename MeshType >
550 void
551 DarcySolverTransient < MeshType >::
553 {
554  // Reset the right hand side coming from the time advance scheme.
555  M_rhsTimeAdvance.reset ( new vector_Type ( this->M_primalField->getFESpace().map() ) );
556 
557  // Update the RHS
558  M_timeAdvance->updateRHSFirstDerivative ();
559 
560  // Put in M_rhsTimeAdvance the contribution for the right hand side coming
561  // from the time scheme, without the time step.
562  *M_rhsTimeAdvance = M_timeAdvance->rhsContributionFirstDerivative ();
563 
564  // Solve the problem
565  darcySolverLinear_Type::solve ();
566 
567 } // solve
568 
569 // Set and compute the mass matrix.
570 template < typename MeshType >
571 void
572 DarcySolverTransient < MeshType >::
573 setMass ( const scalarFctPtr_Type& massFct )
574 {
575  // Save the mass function.
576  M_massFct = massFct;
577 
578  // The total number of elements in the mesh.
579  const UInt meshNumberOfElements = this->M_primalField->getFESpace().mesh()->numElements();
580 
581  // Element of current id.
582  typename mesh_Type::element_Type element;
583 
584  // Reseve the memory for the mass matrices.
585  M_localMassMatrix.reserve ( meshNumberOfElements );
586 
587  // Elemental matrix to store the current local mass matrix.
588  MatrixElemental localMassMatrix ( this->M_primalField->getFESpace().refFE().nbDof(), 1, 1 );
589 
590  // The coordinate of the barycenter of local element.
591  Vector3D barycenter;
592 
593  //! Loop on all the volume elements.
594  for ( UInt iElem (0); iElem < meshNumberOfElements; ++iElem )
595  {
596  // Element of current ID.
597  element = this->M_primalField->getFESpace().mesh()->element ( iElem );
598 
599  // Update the current element of ID iElem for the primal variable.
600  this->M_primalField->getFESpace().fe().update ( element, UPDATE_QUAD_NODES | UPDATE_WDET );
601 
602  // Clean the local mass matrix before the computation.
603  localMassMatrix.zero ();
604 
605  // Get the coordinates of the barycenter of the current element of ID iElem.
606  this->M_primalField->getFESpace().fe().barycenter ( barycenter[0], barycenter[1], barycenter[2] );
607 
608  // Computes the value for the mass term.
609  const Real massValue = M_massFct->eval ( iElem, barycenter );
610 
611  // Compute the mass matrix for the primal variable.
612  AssemblyElemental::mass ( massValue, localMassMatrix, this->M_primalField->getFESpace().fe(), 0, 0);
613 
614  // Save the computed mass matrix.
615  M_localMassMatrix.push_back ( localMassMatrix );
616  }
617 
618 } // setMass
619 
620 // Call the Darcy solver localMatrixComputation method and compute the mass matrix for the time dependent term.
621 template < typename MeshType >
622 void
623 DarcySolverTransient < MeshType >::
624 localMatrixComputation ( const UInt& iElem, MatrixElemental& elmatMix,
625  MatrixElemental& elmatReactionTerm )
626 {
627  // Call the Darcy solver local matrix computation.
628  darcySolverLinear_Type::localMatrixComputation ( iElem, elmatMix, elmatReactionTerm );
629 
630  // Check if the mass function is set or not.
631  ASSERT ( M_massFct.get(), "DarcySolverTransient : mass function not set." );
632 
633  // Elemental matrix to store the current local mass matrix.
634  MatrixElemental localMassMatrix = M_localMassMatrix [ iElem ];
635 
636  // Multiply the mass matrix by the time step and the time scheme coefficient.
637  localMassMatrix *= M_timeAdvance->coefficientFirstDerivative ( 0 ) /
638  this->M_data->dataTimePtr()->timeStep();
639 
640  /* Store in the reaction matrix the mass matrix,
641  divided by the time step and multiplied by the time scheme coefficient. */
642  elmatReactionTerm.mat() += localMassMatrix.mat();
643 
644 } // localMatrixComputation
645 
646 // Update the primal and dual variable at the current element and compute the element Hdiv mass matrix.
647 template < typename MeshType >
648 void
649 DarcySolverTransient < MeshType >::
650 localVectorComputation ( const UInt& iElem, VectorElemental& elvecMix )
651 {
652  /* Call the Darcy solver localVectorComputation to update the finite elements
653  spaces and to compute the scalar and vector source term. */
654  darcySolverLinear_Type::localVectorComputation ( iElem, elvecMix );
655 
656  // Create the local contribution of the time advance right hand side.
657  VectorElemental localRhsTimeAdvance ( this->M_primalField->getFESpace().refFE().nbDof(), 1 );
658 
659  // Clean the local contribution before the computations.
660  localRhsTimeAdvance.zero ();
661 
662  // Extract from the time advance right hand side the current contribution.
663  extract_vec ( *M_rhsTimeAdvance,
664  localRhsTimeAdvance,
665  this->M_primalField->getFESpace().refFE(),
666  this->M_primalField->getFESpace().dof(),
667  this->M_primalField->getFESpace().fe().currentLocalId(), 0 );
668 
669  // Check if the mass function is setted or not.
670  ASSERT ( M_massFct.get(), "DarcySolverTransient : mass function not setted." );
671 
672  // Extract the current mass matrix.
673  MatrixElemental::matrix_type localMassMatrix ( M_localMassMatrix [ iElem ].mat() );
674 
675  // Divide the mass matrix by the time step.
676  localMassMatrix /= this->M_data->dataTimePtr()->timeStep();
677 
678  // Add to the local scalar source term the time advance term.
679  elvecMix.block ( 1 ) += localMassMatrix * localRhsTimeAdvance.vec();
680 
681 } // localVectorComputation
682 
683 } // namespace LifeV
684 
685 #endif // _DARCYSOLVERTRANSIENT_H_
686 
687 // -*- mode: c++ -*-
darcySolverLinear_Type::vector_Type vector_Type
Distributed vector.
DarcySolverLinear< mesh_Type > darcySolverLinear_Type
Darcy solver class.
matrixElementalContainer_Type M_localMassMatrix
Local mass matrices.
virtual void localMatrixComputation(const UInt &iElem, MatrixElemental &elmatMix, MatrixElemental &elmatReactionTerm)
Compute element matrices.
void setupTime()
Setup the time data.
vectorPtr_Type M_rhsTimeAdvance
Right hand side coming from the time advance scheme.
virtual ~DarcySolverTransient()
Virtual destructor.
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
virtual void postComputePrimalAndDual()
Do some computation after the calculation of the primal and dual variable.
scalarFctPtr_Type M_massFct
Mass function, it does not depend on time.
const flag_Type UPDATE_WDET(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_DPHI_GEO_MAP|UPDATE_ONLY_JACOBIAN|UPDATE_ONLY_DET_JACOBIAN|UPDATE_ONLY_W_DET_JACOBIAN)
implements a mixed-hybrid FE Darcy solver for transient problems
bool M_recomputeMatrix
Boolean that indicates if the matrix is recomputed for the current iteration.
timeAdvancePtr_Type M_timeAdvance
Time advance.
UInt M_maxIterSolver
Interger storing the max number of solver iteration with preconditioner recomputing.
darcySolverLinear_Type::dataPtr_Type dataPtr_Type
Shared pointer for the data type.
virtual void setup()
Set up the linear solver and the preconditioner for the linear system.
DarcySolverTransient(const darcySolverTransient_Type &)
Inhibited copy constructor.
Real & operator[](UInt const &i)
Operator [].
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
MeshType mesh_Type
Typedef for mesh template.
TimeAdvanceBDF< vector_Type > timeAdvance_Type
Time advance scheme.
darcySolverLinear_Type::scalarField_Type scalarField_Type
Scalar field.
std::vector< MatrixElemental > matrixElementalContainer_Type
Container of matrix elemental.
class TimeAdvanceBDF - Backward differencing formula time discretization for the first and the second...
bool M_updated
Boolean that indicates if the matrix is updated for the current iteration.
bool M_reusePrec
Boolean that indicates if the preconditioner is re-used or not.
std::shared_ptr< timeAdvance_Type > timeAdvancePtr_Type
Shared pointer to a time advance scheme.
virtual void solve()
Solve the problem.
double Real
Generic real data.
Definition: LifeV.hpp:175
implements a mixed-hybrid FE Darcy solver.
scalarFctPtr_Type M_primalFieldInitialFct
Initial time primal variable.
virtual void localVectorComputation(const UInt &iElem, VectorElemental &elvecMix)
Computes local vectors.
darcySolverLinear_Type::vectorPtr_Type vectorPtr_Type
Shared pointer to a distributed vector.
const flag_Type UPDATE_QUAD_NODES(UPDATE_ONLY_CELL_NODES|UPDATE_ONLY_QUAD_NODES)
DarcySolverTransient()
Constructor for the class.
void setMass(const scalarFctPtr_Type &massFct)
Set mass matrix.
VectorSmall< 3 > Vector3D
darcySolverTransient_Type & operator=(const darcySolverTransient_Type &)
Inhibited assign operator.
DarcySolverTransient< mesh_Type > darcySolverTransient_Type
Self typedef.
void setInitialPrimal(const scalarFctPtr_Type &primalInitialFct)
Initialize primal solution.
darcySolverLinear_Type::data_Type data_Type
Typedef for the data type.
darcySolverLinear_Type::scalarFieldPtr_Type scalarFieldPtr_Type
Shared pointer to a scalar field.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
darcySolverLinear_Type::scalarFctPtr_Type scalarFctPtr_Type
Shared pointer to a scalar value function.