LifeV
TimeAdvanceBDF.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 LifeV.
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 License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file
29  @brief File containing a class to deal the time advancing scheme.
30  A class for an easy handling of different order time
31  discretizations/extrapolations BDF based for first and second order problem
32 
33  @date 09-2010
34 
35  @author Simone Deparis <simone.deparis@epfl.ch>
36  @author Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
37 
38  @contributor Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
39  @maintainer Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
40  */
41 
42 
43 #ifndef TIMEADVANCEBDF_H
44 #define TIMEADVANCEBDF_H 1
45 
46 
47 
48 
49 #include <lifev/core/fem/TimeAdvance.hpp>
50 
51 namespace LifeV
52 {
53 const UInt BDF_MAX_ORDER = 5;
54 
55 //!class TimeAdvanceBDF - Backward differencing formula time discretization for the first and the second order problem in time.
56 /*!
57  @author Simone Deparis <simone.deparis@epfl.ch>
58  @author Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
59 
60 <ol>
61 <li> First order problem
62 
63 A differential equation of the form
64 
65 \f[ M \dot{u} + A u = f \f]
66 
67 is discretizated in time as
68 
69 \f[ M V_{k+1} + A U_{k+1} = f_{k+1} \f]
70 
71 where V denotes the polynomial of order n in t that interpolates
72 \f$(t_i,u_i)\f$ for \f$i = k-n+1,...,k+1\f$.
73 
74 The approximative time derivative \f$ V \f$ is a linear
75 combination of state vectors \f$u_i\f$:
76 
77 \f[ V_{k+1} = \frac{1}{\Delta t} (\alpha_0 U_{k+1} - \sum_{i=0}^n \alpha_i U_{k+1-i} )\f]
78 
79 Thus we have
80 
81 \f[ \frac{\alpha_0}{\Delta t} M U_{k+1} = A U_{k+1} + f + M f_V \f]
82 
83 with
84 
85 \f[ f_V= \frac{1}{\Delta t} \sum_{i=1}^n \alpha_i U_{k+1-i} \f]
86 
87 This class stores the n last state vectors in order to be able to
88 calculate \f$ f_V \f$. It also provides \f$\alpha_i\f$
89 and can extrapolate the the new state from the \f$n\f$ last states with a
90 polynomial of order \f$n-1\f$:
91 
92 \f[ U_{k+1} \approx \sum_{i=0}^{n-1} \beta_i U_{k-i} \f]
93 </li>
94 <li> Second order problem
95 
96 A differential equation of the form
97 
98 \f[ M \ddot{u}= D( u, \dot{u}) + A(u) + f \f]
99 
100 is discretized in time as
101 
102 \f[ M W_{k+1} = A(U^*) U_{k+1} +D(U^*, V^*) V_{k+1} + f_{k+1} \f]
103 
104 where \f$W\f$ and \f$V\f$ denotes the polynomial of order \f$n+1\f$ and order \f$ n\f$,
105 while \f$U^*\f$ and \f$V^*\f$ are suitable extrapolations.
106 
107 The velocity vector, as for first order problem, is:
108 
109 \f[ V_{k+1} = \frac{1}{\Delta t} (\alpha_0 U_{k+1} - \sum_{i=0}^n \alpha_i U_{k+1-i} )\f]
110 
111 while the acceleration vector \f$W^{n+1}\f$ is:
112 
113 \f[ W_{k+1} = \frac{1}{\Delta t^2} (\xi_0 U_{k+1} - \sum_{i=0}^{n+1} \xi_i U_{k+1-i} )\f]
114 
115 Thus we have
116 
117 \f[ \frac{\xi_0}{\Delta t^2} M U_{k+1} + \frac{\alpha_0}{\Delta t } D U_{k+1} + A U_{k+1} + f + M f_W + D f_V \f]
118 
119 with
120 
121 \f[ f_V= \frac{1}{\Delta t} \sum_{i=1}^n \alpha_i U_{k+1-i} \f]
122 
123 and
124 
125 \f[ f_W =\frac{1}{\Delta t^2} \sum_{i=1}^{n+1} \xi_i U_{ k+1 - i} \f]
126 
127 It also provides \f$\alpha_i\f$ and can extrapolate the the new state from the \f$n\f$ last states with a
128 polynomial of order \f$n-1\f$:
129 
130 \f[ U_{k+1} \approx U^*= \sum_{i=0}^{n-1} \beta_i U_{k-i} \f]
131 
132 and \f$V^*\f$ in following way:
133 
134 \f[ V_{k+1} \approx V^*=\sum_{i=0}^p \frac{\beta_i^V}{\Delta t} U^{n-i} = W^{n+1}+O(\Delta t^p), \f]
135 </li>
136 </ol>
137 */
138 
139 template<typename feVectorType = VectorEpetra >
141  public TimeAdvance < feVectorType >
142 {
143 public:
144 
145  //!@name Public Types
146  //@{
147 
148  //! class super
149  typedef TimeAdvance< feVectorType > super;
150  //! type of template
151  typedef typename super::feVector_Type feVector_Type;
152 
153  //! container of feVector
155 
156  //! container of pointer of feVector;
158 
159  //! iterator;
161 
162  //! container of pointer of feVector;
164 
165  //@}
166 
167  //! @name Constructor & Destructor
168  //@{
169 
170  //! Empty Constructor
171 
172  TimeAdvanceBDF();
173 
174  //! Destructor
175  virtual ~TimeAdvanceBDF() {}
176 
177  //@}
178 
179  //! @name Methods
180  //@{
181 
182  //!Update the state vector
183  /*! Update the vectors of the previous time steps by shifting on the right the old values.
184  @param solution current (new) value of the state vector
185  */
186  void shiftRight (const feVector_Type& solution );
187 
188 
189  //! Update the right hand side \f$ f_V \f$ of the time derivative formula
190  /*!
191  Return the right hand side \f$ f_V \f$ of the time derivative formula
192  @param timeStep defined the time step need to compute the
193  @returns rhsV
194  */
195  void RHSFirstDerivative (const Real& timeStep, feVectorType& rhsContribution ) const;
196 
197  //! Update the right hand side \f$ f_W \f$ of the time derivative formula
198  /*!
199  Sets and Returns the right hand side \f$ f_W \f$ of the time derivative formula
200  @param timeStep defined the time step need to compute the \f$ f_W \f$
201  @returns rhsW
202  */
203  void updateRHSSecondDerivative (const Real& timeStep = 1 );
204 
205  //!Show the properties of temporal scheme
206  void showMe (std::ostream& output = std::cout ) const;
207  //@}
208 
209  //!@name Set Methods
210  //@{
211 
212  //! Initialize the parameters of time advance scheme
213  /*!
214  Initialize parameters of time advance scheme;
215  @param order define the order of BDF;
216  @param orderDerivative define the order of derivate;
217  */
218  void setup ( const UInt& order, const UInt& orderDerivative = 1 );
219 
220  //! Initialize the parameters of time advance scheme used in TimeAdvanceNewmark
221  /*!
222  @note: this setup does not run for BDF class;
223  */
224  void setup ( const std::vector<Real>& /*coefficients*/, const UInt& /*orderDerivative*/)
225  {
226  ERROR_MSG ("use setup for TimeAdvanceNewmark but the time advance scheme is BDF");
227  }
228 
229  //! Initialize the StateVector
230  /*!
231  Initialize all the entries of the unknown vector to be derived with the vector x0 (duplicated).
232  this class is virtual because used in BDF;
233  @param x0 is the initial unk;
234  */
235  void setInitialCondition ( const feVector_Type& x0);
236 
237  //! Initialize the StateVector used in TimeAdvanceNewmark
238  void setInitialCondition (const feVector_Type& /* x0*/, const feVector_Type& /*v0*/ )
239  {
240  ERROR_MSG ( "this method is not yet implemented" );
241  }
242 
243  //! Initialize the StateVector used in TimeAdvanceNewmark
244  void setInitialCondition (const feVector_Type& /*x0*/, const feVector_Type& /*v0*/, const feVector_Type& /* w0*/ )
245  {
246  ERROR_MSG ( "this method is not yet implemented" );
247  }
248 
249  //! Initialize all the entries of the unknown vector to be derived with a
250  /*! set of vectors x0
251  @note: this is taken as a copy (not a reference), since x0 is resized inside the method.
252  */
254 
255  //@}
256 
257  //!@name Get Methods
258  //@{
259 
260  //!Return the \f$i\f$-th coefficient of the unk's extrapolation
261  /*!
262  @param \f$i\f$ index of extrapolation coefficient
263  @returns beta
264  */
265  inline Real coefficientExtrapolation (const UInt& i ) const;
266 
267  //! Return the \f$i\f$-th coefficient of the velocity's extrapolation
268  /*!
269  @param \f$i\f$ index of velocity's extrapolation coefficient
270  @returns betaFirstDerivative
271  */
272  inline Real coefficientExtrapolationFirstDerivative (const UInt& i ) const;
273 
274  //! Compute the polynomial extrapolation of solution
275  /*!
276  Compute the polynomial extrapolation approximation of order \f$n-1\f$ of
277  \f$u^{n+1}\f$ defined by the n stored state vectors
278  */
279 
280  void extrapolation (feVector_Type& extrapolation) const;
281 
282  //! Compute the polynomial extrapolation of velocity
283  /*!
284  Compute the polynomial extrapolation approximation of order \f$n-1\f$ of
285  \f$u^{n+1}\f$ defined by the n stored state vectors
286  */
287  void extrapolationFirstDerivative (feVector_Type& extrapolation) const;
288 
289  //! Return the current velocity
290  feVectorType firstDerivative() const;
291 
292  //!Return the current acceleration
293  feVectorType secondDerivative() const;
294 
295  //@}
296 
297 };
298 
299 // ===================================================
300 // Constructors & Destructor
301 // ===================================================
302 
303 template<typename feVectorType>
304 TimeAdvanceBDF <feVectorType> :: TimeAdvanceBDF() :
305  super()
306 {
307 }
308 
309 // ===================================================
310 // Methods
311 // ===================================================
312 template<typename feVectorType>
313 void
314 TimeAdvanceBDF<feVectorType>::shiftRight (feVector_Type const& solution )
315 {
316  ASSERT ( this->M_unknowns.size() == this->M_size,
317  "M_unknowns.size() and M_size must be equal" );
318 
319  feVectorContainerPtrIterate_Type it = this->M_unknowns.end() - 1;
320  feVectorContainerPtrIterate_Type itm1 = this->M_unknowns.end() - 1;
321  feVectorContainerPtrIterate_Type itb = this->M_unknowns.begin();
322 
323  delete *itm1;
324 
325  for ( ; it != itb; --it )
326  {
327  itm1--;
328  *it = *itm1;
329  }
330 
331  *itb = new feVector_Type (solution);
332 
333 }
334 
335 template<typename feVectorType>
336 void
337 TimeAdvanceBDF<feVectorType>::RHSFirstDerivative (const Real& timeStep, feVectorType& rhsContribution ) const
338 {
339 
340  rhsContribution *= (this->M_alpha[ 1 ] / timeStep);
341 
342  for ( UInt i = 1; i < this->M_order; ++i )
343  {
344  rhsContribution += (this->M_alpha[ i + 1 ] / timeStep) * *this->M_unknowns[ i ];
345  }
346 }
347 
348 
349 template<typename feVectorType>
350 void
351 TimeAdvanceBDF<feVectorType>::updateRHSSecondDerivative (const Real& timeStep )
352 {
353  ASSERT ( this->M_orderDerivative == 2 ,
354  " M_orderDerivative must be equal two" );
355 
356  feVectorContainerPtrIterate_Type it = this->M_rhsContribution.end() - 1;
357 
358  *it = new feVector_Type (*this->M_unknowns[ 0 ]);
359 
360  ** it *= this->M_xi[ 1 ] / (timeStep * timeStep);
361 
362  for ( UInt i = 1; i < this->M_order + 1; ++i )
363  {
364  **it += ( this->M_xi[ i + 1 ] / (timeStep * timeStep) ) * *this->M_unknowns[ i ];
365  }
366 }
367 
368 template<typename feVectorType>
369 void
370 TimeAdvanceBDF<feVectorType>::showMe (std::ostream& output) const
371 {
372  output << "*** BDF Time discretization of order " << this->M_order << " maximum order of derivate " << this->M_orderDerivative << " ***"
373  << std::endl;
374  output << " Coefficients: " << std::endl;
375  for ( UInt i = 0; i < this->M_order + 1; ++i )
376  output << " alpha(" << i << ") = " << this->M_alpha[ i ]
377  << std::endl;
378  for ( UInt i = 0; i < this->M_order; ++i )
379  output << " beta (" << i << ") = " << this->M_beta[ i ]
380  << std::endl;
381  if (this->M_orderDerivative == 2)
382  {
383  for ( UInt i = 0; i < this->M_order + this->M_orderDerivative; ++i )
384  {
385  output << " xi(" << i << ") = " << this->M_xi[ i ] << std::endl;
386  }
387  for ( UInt i = 0; i < this->M_order + 1; ++i )
388  output << " beta of the extrapolation of the first derivative ("
389  << i << ") = " << this->M_betaFirstDerivative[ i ]
390  << std::endl;
391  }
392  output << "Delta Time : " << this->M_timeStep << "\n";
393  output << "*************************************\n";
394  return ;
395 }
396 
397 // ===================================================
398 // Set Methods
399 // ==================================================
400 
401 template<typename feVectorType>
402 void
403 TimeAdvanceBDF<feVectorType>::setup ( const UInt& order, const UInt& orderDerivative)
404 {
405  if ( order <= 0 || order > BDF_MAX_ORDER )
406  {
407  std::ostringstream __ex;
408  __ex << "Error: wrong BDF order\n"
409  << " you want to use BDF order " << order << "\n"
410  << " we support BDF order from 1 to " << BDF_MAX_ORDER << "\n";
411  throw std::invalid_argument ( __ex.str() );
412  }
413 
414  this->M_order = order ;
415  this->M_orderDerivative = orderDerivative ;
416  this->M_size = order ;
417  this->M_alpha.resize ( order + 1 );
418  this->M_xi.resize ( order + 2 );
419  this->M_beta.resize ( order );
420  this->M_betaFirstDerivative.resize ( order + 1 );
421  this->M_coefficientsSize = order + orderDerivative;
422 
423  switch ( order )
424  {
425  case 1:
426  this->M_alpha[ 0 ] = 1.; // Backward Euler
427  this->M_alpha[ 1 ] = 1.;
428  this->M_beta[ 0 ] = 1.; // u^{n+1} \approx u^n
429  this->M_xi[ 0 ] = 1.;
430  this->M_xi[ 1 ] = 2.;
431  this->M_xi[ 2 ] = -1.;
432  this->M_betaFirstDerivative[0] = 2.;
433  this->M_betaFirstDerivative[0] = -1.;
434  break;
435  case 2:
436  this->M_alpha[ 0 ] = 3. / 2.;
437  this->M_alpha[ 1 ] = 2.;
438  this->M_alpha[ 2 ] = -1. / 2.;
439  this->M_beta[ 0 ] = 2.;
440  this->M_beta[ 1 ] = -1.;
441  this->M_xi[ 0 ] = 2.;
442  this->M_xi[ 1 ] = 5.;
443  this->M_xi[ 2 ] = -4.;
444  this->M_xi[ 3 ] = 1.;
445  this->M_betaFirstDerivative[0] = 3.;
446  this->M_betaFirstDerivative[1] = -3.;
447  this->M_betaFirstDerivative[2] = 1.;
448  break;
449  case 3:
450  this->M_alpha[ 0 ] = 11. / 6.;
451  this->M_alpha[ 1 ] = 3.;
452  this->M_alpha[ 2 ] = -3. / 2.;
453  this->M_alpha[ 3 ] = 1. / 3.;
454  this->M_beta[ 0 ] = 3.;
455  this->M_beta[ 1 ] = -3.;
456  this->M_beta[ 2 ] = 1.;
457  this->M_xi[ 0 ] = 35. / 12.;
458  this->M_xi[ 1 ] = 26. / 3.;
459  this->M_xi[ 2 ] = -19. / 2;
460  this->M_xi[ 3 ] = 14. / 3.;
461  this->M_xi[ 4 ] = -11. / 12.;
462  this->M_betaFirstDerivative[0] = 4.;
463  this->M_betaFirstDerivative[ 1 ] = -6.;
464  this->M_betaFirstDerivative[ 2 ] = 4.;
465  this->M_betaFirstDerivative[ 3 ] = -1.;
466  break;
467  case 4:
468  this->M_alpha[ 0 ] = 25. / 12.;
469  this->M_alpha[ 1 ] = 4.;
470  this->M_alpha[ 2 ] = -3. ;
471  this->M_alpha[ 3 ] = 4. / 3.;
472  this->M_alpha[ 4 ] = - 1 / 4.;
473  this->M_beta[ 0 ] = 4.;
474  this->M_beta[ 1 ] = -6.;
475  this->M_beta[ 2 ] = 4.;
476  this->M_beta[ 3 ] = -1;
477  this->M_xi[ 0 ] = 15. / 4.;
478  this->M_xi[ 1 ] = 77. / 6.;
479  this->M_xi[ 2 ] = -107. / 6.;
480  this->M_xi[ 3 ] = 13.;
481  this->M_xi[ 4 ] = -61. / 12.;
482  this->M_xi[ 5 ] = 5. / 6.;
483  this->M_betaFirstDerivative[ 0 ] = 5.;
484  this->M_betaFirstDerivative[ 1 ] = -10.;
485  this->M_betaFirstDerivative[ 2 ] = 10.;
486  this->M_betaFirstDerivative[ 3 ] = -5.;
487  this->M_betaFirstDerivative[ 4 ] = 1.;
488  break;
489  case 5:
490  this->M_alpha[ 0 ] = 137. / 60.;
491  this->M_alpha[ 1 ] = 5.;
492  this->M_alpha[ 2 ] = -5. ;
493  this->M_alpha[ 3 ] = 10. / 3.;
494  this->M_alpha[ 4 ] = -5. / 4.;
495  this->M_alpha[ 5 ] = 1. / 5.;
496  this->M_beta[ 0 ] = 5.;
497  this->M_beta[ 1 ] = -10.;
498  this->M_beta[ 2 ] = 10.;
499  this->M_beta[ 3 ] = -5.;
500  this->M_beta[ 4 ] = 1.;
501  this->M_xi[ 0 ] = 203. / 45.;
502  this->M_xi[ 1 ] = 87. / 5.;
503  this->M_xi[ 2 ] = -117. / 4.;
504  this->M_xi[ 3 ] = 254. / 9.;
505  this->M_xi[ 4 ] = -33. / 2.;
506  this->M_xi[ 5 ] = 27. / 5.;
507  this->M_xi[ 6 ] = -137. / 180.;
508  this->M_betaFirstDerivative[ 0 ] = 6.;
509  this->M_betaFirstDerivative[ 1 ] = -15. / 2.;
510  this->M_betaFirstDerivative[ 2 ] = 20. / 3.;
511  this->M_betaFirstDerivative[ 3 ] = -15. / 4.;
512  this->M_betaFirstDerivative[ 4 ] = 6. / 5.;
513  this->M_betaFirstDerivative[ 5 ] = -1.;
514  break;
515  }
516 
517  if ( this->M_orderDerivative == 2 )
518  {
519  this->M_size++;
520  }
521  this->M_unknowns.reserve ( this->M_size);
522  this->M_rhsContribution.reserve (2);
523 }
524 
525 template<typename feVectorType>
526 void TimeAdvanceBDF<feVectorType>::setInitialCondition ( const feVector_Type& x0)
527 {
528  feVectorContainerPtrIterate_Type iter = this->M_unknowns.begin();
529  feVectorContainerPtrIterate_Type iter_end = this->M_unknowns.end();
530 
531  for ( ; iter != iter_end; iter++ )
532  {
533  delete *iter;
534  *iter = new feVector_Type (x0);
535  }
536 
537  for ( UInt i (this->M_unknowns.size() ) ; i < this->M_order; i++ )
538  {
539  this->M_unknowns.push_back (new feVector_Type (x0) );
540  }
541 
542  feVector_Type zero (x0);
543  zero *= 0;
544  this->setInitialRHS (zero);
545 
546  ASSERT ( this->M_unknowns.size() == this->M_order,
547  "M_unknowns.size() and M_order must be equal" );
548 }
549 
550 template<typename feVectorType>
552 {
553  UInt n0 = x0.size();
554 
555  ASSERT ( n0 != 0, "Initial data are not enough for the selected BDF" );
556 
557  feVectorContainerPtrIterate_Type iter = this->M_unknowns.begin();
558  feVectorContainerPtrIterate_Type iter_end = this->M_unknowns.end();
559 
560  UInt i (0);
561 
562  for ( ; iter != iter_end && i < n0 ; ++iter, ++i )
563  {
564  delete *iter;
565  *iter = new feVector_Type (*x0[i]);
566  }
567 
568  for ( i = this->M_unknowns.size() ; i < this->M_order && i < n0; ++i )
569  {
570  this->M_unknowns.push_back (new feVector_Type (*x0[i]) );
571  }
572 
573  if (this->M_orderDerivative == 1)
574  {
575  for ( i = this->M_unknowns.size() ; i < this->M_order; ++i )
576  {
577  this->M_unknowns.push_back (new feVector_Type (*x0[n0 - 1]) );
578  }
579 
580  ASSERT ( this->M_unknowns.size() == this->M_order,
581  "M_unknowns.size() and M_order must be equal" );
582  }
583  if (this->M_orderDerivative == 2)
584  {
585  for ( i = this->M_unknowns.size() ; i < this->M_order + 1; ++i )
586  {
587  this->M_unknowns.push_back (new feVector_Type (*x0[n0 - 1]) );
588  }
589 
590  ASSERT ( this->M_unknowns.size() == this->M_order + 1,
591  "M_unknowns.size() and M_order must be equal" );
592  }
593 
594  //!initialize zero
595  feVector_Type zero (*x0[0]);
596  zero *= 0;
597  this->setInitialRHS (zero);
598 }
599 
600 // ===================================================
601 // Get Methods
602 // ===================================================
603 
604 template<typename feVectorType>
605 inline Real
606 TimeAdvanceBDF<feVectorType>::coefficientExtrapolation (const UInt& i ) const
607 {
608  // Pay attention: i is c-based indexed
609  ASSERT ( i < this->M_order,
610  "Error in specification of the time derivative coefficient for the BDF formula (out of range error)" );
611  return this->M_beta[ i ];
612 }
613 
614 template<typename feVectorType>
615 inline double
617 {
618  // Pay attention: i is c-based indexed
619  ASSERT ( i < this->M_order,
620  "Error in specification of the time derivative coefficient for the BDF formula (out of range error)" );
621  return this->M_betaFirstDerivative[ i ];
622 }
623 
624 template<typename feVectorType>
625 void
626 TimeAdvanceBDF<feVectorType>::extrapolation (feVector_Type& extrapolation) const
627 {
628  extrapolation = this->M_beta[ 0 ] * (*this->M_unknowns[ 0 ]);
629 
630  for ( UInt i = 1; i < this->M_order; ++i )
631  {
632  extrapolation += this->M_beta[ i ] * (*this->M_unknowns[ i ]);
633  }
634 }
635 
636 template<typename feVectorType>
637 void
638 TimeAdvanceBDF<feVectorType>::extrapolationFirstDerivative (feVector_Type& extrapolation) const
639 {
640  ASSERT ( this->M_orderDerivative == 2,
641  "extrapolationFirstDerivative: this method must be used with the second order problem." )
642 
643  extrapolation = this->M_betaFirstDerivative[ 0 ] * (*this->M_unknowns[ 0 ]);
644 
645  for ( UInt i = 1; i < this->M_order; ++i )
646  {
647  extrapolation += this->M_betaFirstDerivative[ i ] * (*this->M_unknowns[ i ]);
648  }
649 }
650 
651 template<typename feVectorType>
652 feVectorType
653 TimeAdvanceBDF<feVectorType>::firstDerivative() const
654 {
655  // Note by Cristiano Malossi - 13/02/2013
656  //
657  // This method is valid only if
658  //
659  // 1) shiftRight has been called
660  // 2) updateRHSFirstDerivative has NOT been called
661  //
662  // TODO In case both shiftRight and updateRHSFirstDerivative have been called
663  // a possible implementation is the one commented below.
664  //
665  // feVector_Type derivative( *this->M_unknowns[ 0 ] * this->M_alpha[ 0 ] );
666  // for ( UInt i = 1; i <= this->M_order; ++i )
667  // {
668  // derivative -= *this->M_unknowns[ i ] * this->M_alpha[ i ];
669  // }
670  //
671  // return derivative / this->M_timeStep;
672  //
673  // Before going in this direction the design of the TimeAdvance needs to be discussed.
674  // The same consideration is valid for the second derivative.
675  return *this->M_unknowns[0] * this->M_alpha[ 0 ] / this->M_timeStep
676  - ( *this->M_rhsContribution[0] );
677 }
678 
679 template<typename feVectorType>
680 feVectorType
681 TimeAdvanceBDF<feVectorType>::secondDerivative() const
682 {
683  return (*this->M_unknowns[0]) * this->M_xi[ 0 ] / (this->M_timeStep * this->M_timeStep) - ( *this->M_rhsContribution[1] );
684 }
685 
686 
687 // ===================================================
688 // Macros
689 // ===================================================
690 
691 //! define the BDF factory; this class runs only the default template parameter.
692 inline
693 TimeAdvance<VectorEpetra>* createBDF()
694 {
695  return new TimeAdvanceBDF<VectorEpetra>();
696 }
697 
698 namespace
699 {
701 }
702 
703 } //Namespace LifeV
704 
705 #endif /*TIMEADVANCEBDF */
feVectorType firstDerivative() const
Return the current velocity.
void extrapolationFirstDerivative(feVector_Type &extrapolation) const
Compute the polynomial extrapolation of velocity.
void updateRHSSecondDerivative(const Real &timeStep=1)
Update the right hand side of the time derivative formula.
const UInt BDF_MAX_ORDER
super::feVectorContainerPtr_Type feVectorContainerPtr_Type
container of pointer of feVector;
void setInitialCondition(const feVectorSharedPtrContainer_Type &x0)
Initialize all the entries of the unknown vector to be derived with a.
super::feVectorContainer_Type feVectorContainer_Type
container of feVector
void setInitialCondition(const feVector_Type &x0)
Initialize the StateVector.
TimeAdvance< feVectorType > super
class super
feVectorContainerPtr_Type::iterator feVectorContainerPtrIterate_Type
iterator;
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
Real coefficientExtrapolationFirstDerivative(const UInt &i) const
Return the -th coefficient of the velocity&#39;s extrapolation.
class TimeAdvanceBDF - Backward differencing formula time discretization for the first and the second...
void extrapolation(feVector_Type &extrapolation) const
Compute the polynomial extrapolation of solution.
Real coefficientExtrapolation(const UInt &i) const
Return the -th coefficient of the unk&#39;s extrapolation.
void setInitialCondition(const feVector_Type &, const feVector_Type &, const feVector_Type &)
Initialize the StateVector used in TimeAdvanceNewmark.
void showMe(std::ostream &output=std::cout) const
Show the properties of temporal scheme.
void setup(const UInt &order, const UInt &orderDerivative=1)
Initialize the parameters of time advance scheme.
super::feVectorSharedPtrContainer_Type feVectorSharedPtrContainer_Type
container of pointer of feVector;
double Real
Generic real data.
Definition: LifeV.hpp:175
void RHSFirstDerivative(const Real &timeStep, feVectorType &rhsContribution) const
Update the right hand side of the time derivative formula.
TimeAdvanceBDF()
Empty Constructor.
void shiftRight(const feVector_Type &solution)
Update the state vector.
virtual ~TimeAdvanceBDF()
Destructor.
feVectorType secondDerivative() const
Return the current acceleration.
super::feVector_Type feVector_Type
type of template
TimeAdvance< VectorEpetra > * createBDF()
define the BDF factory; this class runs only the default template parameter.
void setup(const std::vector< Real > &, const UInt &)
Initialize the parameters of time advance scheme used in TimeAdvanceNewmark.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
void setInitialCondition(const feVector_Type &, const feVector_Type &)
Initialize the StateVector used in TimeAdvanceNewmark.