LifeV
TimeAdvanceNewmark.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  This class consider \f$\theta\f$-method for first order problems and
31  TimeAdvanceNewmark scheme for the second order problems.
32 
33  @date 09-2010
34 
35  @author Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
36  @contributor Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
37  @maintainer Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
38 */
39 
40 #ifndef TimeAdvanceNewmark_H
41 #define TimeAdvanceNewmark_H 1
42 
43 
44 #include <string>
45 #include <iostream>
46 #include <stdexcept>
47 #include <sstream>
48 #include <cmath>
49 
50 
51 #include <lifev/core/fem/TimeAdvance.hpp>
52 #include <lifev/core/array/VectorEpetra.hpp>
53 
54 namespace LifeV
55 {
56 //! TimeAdvanceNewmark - Class to deal the \f$theta\f$-method and TimeAdvanceNewmark scheme
57 /*!
58  @author Matteo Pozzoli <matteo1.pozzoli@mail.polimi.it>
59 
60  This class can be used to approximate problems of the first order and the second order in time.
61  In the first case the temporal scheme is a theta-method, while in the second case is a TimeAdvanceNewmark scheme.
62 
63  This class defines the state vector \f$X^{n+1}\f$, a suitable extrapolation of vector \f$X^*\f$ and opportune coefficients used to determinate \f$X^{n+1}\f$ and \f$X^*\f$.
64 <ol>
65 <li> First order problem:
66 
67  \f[ M u' + A(u) = f \f]
68 
69  the state vector is \f[X^{n+1} = (U^{n+1},V^{n+1}, U^{n}, V^{n})\f].
70  where \f$U\f$ is an approximation of \f$u\f$ and \f$V\f$ of \f$\dot{u}\f$.
71 
72  We consider a parameter \f$\theta\f$, and we apply the following theta method:
73 
74  \f[ U^{n+1} = U^{n} + \Delta t \theta V^{n+1} + (1 − \theta) V^n, \f]
75 
76  so the approximation of velocity at timestep \f$n+1\f$ is:
77 
78  \f[ V^{ n+1} = 1/ (\theta * \Delta t) (U^{n+1}-U^n)+( 1 - 1 / \theta) V^n;\f]
79 
80  We can linearize non-linear term \f$A(u)\f$ as \f$A(U^*) U^{n+1}\f$, where the \f$U^*\f$ becomes:
81 
82  \f[ U^∗ = U^n + \Delta t V^n, \f]
83 
84  The coefficients \f$\alpha\f$, \f$beta\f$ depend on \f$theta\f$,
85  and we can use a explicit \f$theta\f$-method.
86  </li>
87  <li> Second order Method:
88 
89  \f[ M \ddot{u} + D(u, \dot{u})+ A(u) = f \f]
90 
91  the state vector is \f[X^{n+1} = (U^{n+1},V^{n+1}, W^{n+1}, U^{n}, V^{n}, W^{n}).\f]
92  where U is an approximation of \f$u\f$ and \f$V\f$ of \f$\dot{u}\f$ and \f$W\f$ of \f$\ddot{u}\f$ .
93 
94  We introduce the parameters (\f$\theta\f$, \f$\gamma\f$) and we apply the following TimeAdvanceNewmark method:
95 
96  \f[ U^{n+1} = U^{n} + \Delta t \theta V^{n+1} + (1 − \theta) V^n, \f]
97 
98  so the approximation of velocity at time step \f$n+1\f$ is
99 
100  \f[ V^{ n+1} = \beta / (\theta * \Delta t) (U^{n+1}-U^n)+( 1 - \gamma/ \theta) V^n+ (1- \gamma /(2\theta)) \Delta t W^n;\f]
101 
102  and we determine \f$W^{n+1}\f$ by
103 
104  \f[ W^{n+1} =1/(\theta \Delta t^2) (U^{n+1}-U^{n}) - 1 / \Delta t V^n + (1-1/(2\theta)) W^n \f].
105 
106  We can linearize non-linear term \f$A(u)\f$ as \f$A(U^*) U^{n+1}\f$ and \f$D(u, \dot{u})\f$ as \f$D(U^*, V^*) V^{n+1}\f$,
107  where \f$U^*\f$ is given by
108 
109  \f[ U^∗ = U^n + \Delta t V^n \f]
110 
111  and \f$V^*\f$ is
112 
113  \f[ V^* =V^n+ \Delta t W^n \f]
114 
115  The coefficients \f$\xi\f$, \f$\alpha\f$, \f$\beta\f$, \f$\beta_V\f$ depend on \f$\theta\f$ and \f$\gamma\f$.
116  </li>
117  </ol>
118 */
119 
120 template<typename feVectorType = VectorEpetra >
121 class TimeAdvanceNewmark:
122  public TimeAdvance < feVectorType >
123 {
124 public:
125 
126  //! @name Public Types
127  //@{
128 
129  // class super;
130  typedef TimeAdvance< feVectorType > super;
131  // type of template
132  typedef typename super::feVector_Type feVector_Type;
133  // container of feVector
134  typedef typename super::feVectorContainer_Type feVectorContainer_Type;
135 
136  // container of pointer of feVector;
137  typedef typename super::feVectorContainerPtr_Type feVectorContainerPtr_Type;
138 
139  // iterator;
140  typedef typename feVectorContainerPtr_Type::iterator feVectorContainerPtrIterate_Type;
141 
142  // container of pointer of feVector;
143  typedef typename super::feVectorSharedPtrContainer_Type feVectorSharedPtrContainer_Type;
144 
145  //@}
146 
147  //! @name Constructor & Destructor
148  //@{
149 
150  //! Empty Constructor
151  TimeAdvanceNewmark();
152 
153  //! Destructor
154  virtual ~TimeAdvanceNewmark() {}
155 
156  //@}
157 
158  //! @name Methods
159  //@{
160 
161  //!Update the state vector
162  /*! Update the vectors of the previous time steps by shifting on the right the old values.
163  @param solution current (new) value of the state vector
164  */
165  void shiftRight (const feVector_Type& solution);
166 
167  //! Update the right hand side \f$ f_V \f$ of the time derivative formula
168  /*!
169  Return the right hand side \f$ f_V \f$ of the time derivative formula
170  @param timeStep defined the time step need to compute the
171  @returns rhsV
172  */
173  void RHSFirstDerivative (const Real& timeStep, feVectorType& rhsContribution) const;
174 
175  //! Update the right hand side \f$ f_W \f$ of the time derivative formula
176  /*!
177  Set and Return the right hand side \f$ f_W \f$ of the time derivative formula
178  @param timeStep defined the time step need to compute the \f$ f_W \f$
179  */
180  void updateRHSSecondDerivative (const Real& timeStep = 1 );
181 
182  //!Show the properties of temporal scheme
183  void showMe (std::ostream& output = std::cout) const;
184 
185  //@}
186 
187  //!@name Set Methods
188  //@{
189 
190  //! Initialize the parameters of time advance scheme
191  /*!
192  @param order define the order of BDF;
193  @param orderDerivatve define the order of derivative;
194  */
195  void setup ( const UInt& /*order*/, const UInt& /*orderDerivative*/ )
196  {
197  ERROR_MSG ("use setup for TimeAdvanceBDF but the time advance scheme is Newmark");
198  }
199 
200  //! Initialize the parameters of time advance scheme
201  /*!
202  @param coefficients define the TimeAdvanceNewmark's coefficients (\theta, \gamma);
203  @param orderDerivative define the order of derivative;
204  */
205  void setup (const std::vector<Real>& coefficients, const UInt& orderDerivative);
206 
207  //! Initialize the StateVector
208  /*!
209  Initialize all the entries of the unknown vector to be derived with the vector x0 (duplicated).
210  this class is virtual because used in bdf;
211  @param x0 is the initial solution;
212  */
213  void setInitialCondition ( const feVector_Type& x0);
214 
215  //! initialize the state vector
216  /*!
217  Initialize all the entries of the unknown vector to be derived with the vector x0, v0 (duplicated).
218  this class is virtual because used in \f$\theta\f$-method scheme;
219  @param x0 is the initial unk;
220  @param v0 is the initial velocity
221  */
222  void setInitialCondition ( const feVector_Type& x0, const feVector_Type& v0 );
223 
224  //! initialize the state vector
225  /*!
226  Initialize all the entries of the unknown vector to be derived with the vector x0, v0,w0 (duplicated).
227  this class is virtual because used in Newamrk scheme;
228  @param x0 is the initial solution;
229  @param v0 is the initial velocity
230  @param w0 is the initial acceleration
231  */
232  void setInitialCondition (const feVector_Type& x0, const feVector_Type& v0, const feVector_Type& w0 );
233 
234  //! Initialize the state vector
235  /*! Initialize all the entries of the unknown vector to be derived with a
236  set of vectors x0
237  note: this is taken as a copy (not a reference), since x0 is resized inside the method.
238  */
239  void setInitialCondition ( const feVectorSharedPtrContainer_Type& x0);
240 
241  //@}
242 
243  //!@name Get Methods
244  //@{
245 
246  //!Return the \f$i\f$-th coefficient of the unk's extrapolation
247  /*!
248  @param i index of extrapolation coefficient
249  @returns beta
250  */
251  Real coefficientExtrapolation (const UInt& i ) const;
252 
253  //! Return the \f$i\f$-th coefficient of the velocity's extrapolation
254  /*!
255  @param \f$i\f$ index of the coefficient of the first derivative
256  @returns beta
257  */
258  Real coefficientExtrapolationFirstDerivative (const UInt& i ) const;
259 
260  //! Compute the polynomial extrapolation of solution
261  /*!
262  Compute the polynomial extrapolation approximation of order \f$n-1\f$ of
263  \f$u^{n+1}\f$ defined by the n stored state vectors
264  */
265  //feVectorType extrapolation() const;
266  void extrapolation (feVector_Type& extrapolation) const;
267 
268  //! Compute the polynomial extrapolation of velocity
269  /*!
270  Compute the polynomial extrapolation approximation of order \f$n-1\f$ of
271  \f$u^{n+1}\f$ defined by the n stored state vectors
272  */
273  void extrapolationFirstDerivative (feVector_Type& extrapolation) const;
274 
275  //! Return the current velocity
276  feVector_Type firstDerivative() const
277  {
278  return ( *this->M_unknowns[1]);
279  }
280 
281  //!Return the current acceleration
282  feVector_Type secondDerivative() const
283  {
284  return *this->M_unknowns[2];
285  }
286 
287  //@}
288 
289 private:
290 
291  //! Coefficient of TimeAdvanceNewmark: \f$theta\f$
292  Real M_theta;
293 
294  //! Coefficient of TimeAdvanceNewmark: \f$\gamma\f$
295  Real M_gamma;
296 
297 };
298 
299 // ==================================================
300 // Constructors & Destructor
301 // ==================================================
302 template<typename feVectorType>
303 TimeAdvanceNewmark <feVectorType> ::TimeAdvanceNewmark() : super()
304 {
305 }
306 
307 // ===================================================
308 // Methods
309 // ===================================================
310 template<typename feVectorType>
311 void TimeAdvanceNewmark <feVectorType>::shiftRight (const feVector_Type& solution)
312 {
313  ASSERT ( this->M_timeStep != 0 , "M_timeStep must be different to 0");
314 
315  feVectorContainerPtrIterate_Type it = this->M_unknowns.end();
316  feVectorContainerPtrIterate_Type itb1 = this->M_unknowns.begin() + this->M_size / 2;
317  feVectorContainerPtrIterate_Type itb = this->M_unknowns.begin();
318 
319  for ( ; itb1 != it; ++itb1, ++itb)
320  {
321  *itb1 = *itb;
322  }
323 
324  itb = this->M_unknowns.begin();
325 
326  // insert unk in unknowns[0];
327  *itb = new feVector_Type ( solution );
328 
329  itb++;
330 
331  //update velocity
332  feVector_Type velocityTemp (solution);
333  velocityTemp *= this->M_alpha[0] / this->M_timeStep;
334  velocityTemp -= *this->M_rhsContribution[0];
335 
336  // update unknows[1] with velocityTemp is current velocity
337  *itb = new feVector_Type (velocityTemp);
338 
339  if ( this->M_orderDerivative == 2 )
340  {
341  itb++;
342 
343  //update acceleration
344  feVector_Type accelerationTemp ( solution );
345  accelerationTemp *= this->M_xi[ 0 ] / ( this->M_timeStep * this->M_timeStep);
346  accelerationTemp -= * this->M_rhsContribution[ 1 ];
347 
348  *itb = new feVector_Type ( accelerationTemp );
349  }
350  return;
351 }
352 
353 template<typename feVectorType>
354 void
355 TimeAdvanceNewmark<feVectorType>::RHSFirstDerivative (const Real& timeStep, feVectorType& rhsContribution ) const
356 {
357  rhsContribution *= (this->M_alpha[ 1 ] / timeStep) ;
358 
359  Real timeStepPower (1.); // was: std::pow( timeStep, static_cast<Real>(i - 1 ) )
360 
361  for (UInt i = 1; i < this->M_firstOrderDerivativeSize; ++i )
362  {
363  rhsContribution += ( this->M_alpha[ i + 1 ] * timeStepPower ) * (* this->M_unknowns[ i ]);
364  timeStepPower *= timeStep;
365  }
366 }
367 
368 template<typename feVectorType>
369 void
370 TimeAdvanceNewmark<feVectorType>::updateRHSSecondDerivative (const Real& timeStep )
371 {
372  feVectorContainerPtrIterate_Type it = this->M_rhsContribution.end() - 1;
373 
374  *it = new feVector_Type (*this->M_unknowns[0]);
375 
376  ** it *= this->M_xi[ 1 ] / (timeStep * timeStep) ;
377 
378  for ( UInt i = 1; i < this->M_secondOrderDerivativeSize; ++i )
379  {
380  **it += ( this->M_xi[ i + 1 ] * std::pow (timeStep, static_cast<Real> (i - 2) ) ) * ( *this->M_unknowns[ i ]);
381  }
382 }
383 
384 template<typename feVectorType>
385 void
386 TimeAdvanceNewmark<feVectorType>::showMe (std::ostream& output ) const
387 {
388  output << "*** TimeAdvanceNewmark discretization maximum order of derivate "
389  << this->M_orderDerivative << " ***" << std::endl;
390  output << " Coefficients : " << std::endl;
391  output << " theta : " << M_theta << "\n"
392  << " gamma : " << M_gamma << "\n"
393  << " size unknowns :" << this->M_size << "\n";
394 
395  for ( UInt i = 0; i < this->M_alpha.size(); ++i )
396  {
397  output << " alpha(" << i << ") = " << this->M_alpha[ i ] << std::endl;
398  }
399 
400  if (this->M_orderDerivative == 2)
401  {
402  for ( UInt i = 0; i < this->M_xi.size(); ++i )
403  {
404  output << " xi(" << i << ") = " << this->M_xi[ i ] << std::endl;
405  }
406  }
407 
408  output << "Delta Time : " << this->M_timeStep << "\n";
409  output << "*************************************\n";
410 }
411 
412 // ===================================================
413 // Set Methods
414 // ===================================================
415 
416 template<typename feVectorType>
417 void
418 TimeAdvanceNewmark<feVectorType>::setup (const std::vector<Real>& coefficients, const UInt& orderDerivative)
419 {
420  //initialize theta
421  M_theta = coefficients[0];
422 
423  //initilialize gamma
424  M_gamma = coefficients[1];
425 
426  //initialize Order Derivative
427  this->M_orderDerivative = orderDerivative;
428 
429  // If theta equal 0, explicit meta method
430  if (M_theta == 0)
431  {
432  ASSERT (this->M_orderDerivative == 2, "theta is 0 must be different from 0 in TimeAdvanceNewmark");
433  this->M_size = 4;
434  this->M_alpha[ 0 ] = 1;
435  this->M_alpha[ 1 ] = 1;
436  this->M_alpha[ 2 ] = 1;
437  this->M_order = 1;
438  }
439  else
440  {
441  if (this->M_orderDerivative == 1 ) // Theta method
442  {
443  this->M_gamma = 1;
444  // unknown vector's dimension;
445  this->M_size = 4;
446  this->M_alpha.resize (3);
447  this->M_xi.resize (3);
448  this->M_beta.resize (3);
449  this->M_alpha[ 0 ] = M_gamma / M_theta;
450  this->M_alpha[ 1 ] = M_gamma / M_theta;
451  this->M_alpha[ 2 ] = M_gamma / M_theta - 1.0;
452  this->M_beta[0] = 1;
453  this->M_beta[1] = 1;
454  this->M_beta[2] = 0.5;
455  this->M_xi[0] = 0;
456  this->M_xi[1] = 0;
457  this->M_xi[2] = 0;
458  this->M_coefficientsSize = 3;
459  }
460  else //TimeAdvanceNewmarkMethod
461  {
462  //unknown vector's dimension
463  this->M_size = 6 ;
464  this->M_alpha.resize (4);
465  this->M_xi.resize (4);
466  this->M_beta.resize (3);
467  this->M_betaFirstDerivative.resize (3);
468  //initialitation alpha coefficients
469  this->M_alpha[ 0 ] = M_gamma / M_theta;
470  this->M_alpha[ 1 ] = M_gamma / M_theta;
471  this->M_alpha[ 2 ] = M_gamma / M_theta - 1.0;
472  this->M_alpha[ 3 ] = M_gamma / (2.0 * M_theta) - 1.0;
473 
474  //initialitation xi coefficients
475  this->M_xi[ 0 ] = 1. / M_theta;
476  this->M_xi[ 1 ] = 1. / M_theta;
477  this->M_xi[ 2 ] = 1. / M_theta;
478  this->M_xi[ 3 ] = 1. / ( 2.0 * M_theta ) - 1.0;
479 
480 
481  //initialitation extrap coefficients
482  this->M_beta[ 0 ] = 1;
483  this->M_beta[ 1 ] = 1;
484  this->M_beta[ 2 ] = 0.5;
485  this->M_betaFirstDerivative[ 0 ] = 0;
486  this->M_betaFirstDerivative[ 1 ] = 1;
487  this->M_betaFirstDerivative[ 2 ] = 1;
488 
489  this->M_coefficientsSize = 4;
490  }
491  this->M_unknowns.reserve (this->M_size);
492  this-> M_rhsContribution.reserve (2);
493  // check order scheme
494  if (this->M_alpha[0] == 0.5)
495  {
496  this->M_order = 2;
497  }
498  else
499  {
500  this->M_order = 1;
501  }
502 
503  this->M_firstOrderDerivativeSize = static_cast<Real> (this->M_size) / 2.0;
504  this->M_secondOrderDerivativeSize = static_cast<Real> (this->M_size) / 2.0;
505  }
506 }
507 
508 template<typename feVectorType>
509 void TimeAdvanceNewmark<feVectorType>::setInitialCondition ( const feVector_Type& x0)
510 {
511  feVectorContainerPtrIterate_Type iter = this->M_unknowns.begin();
512  feVectorContainerPtrIterate_Type iter_end = this->M_unknowns.end();
513 
514  feVector_Type zero (x0);
515  zero *= 0;
516 
517  for ( ; iter != iter_end; ++iter )
518  {
519  delete *iter;
520  *iter = new feVector_Type (zero, Unique);
521  }
522 
523  for ( UInt i (this->M_unknowns.size() ) ; i < this->M_size; ++i )
524  {
525  this->M_unknowns.push_back (new feVector_Type (x0) );
526  }
527 
528  feVectorContainerPtrIterate_Type iterRhs = this->M_rhsContribution.begin();
529  feVectorContainerPtrIterate_Type iterRhs_end = this->M_rhsContribution.end();
530 
531  for ( ; iterRhs != iterRhs_end ; ++iterRhs)
532  {
533  delete *iterRhs;
534  *iterRhs = new feVector_Type (zero, Unique);
535  }
536 }
537 
538 template<typename feVectorType>
539 void TimeAdvanceNewmark<feVectorType>::setInitialCondition ( const feVector_Type& x0, const feVector_Type& v0)
540 {
541  feVectorContainerPtrIterate_Type iter = this->M_unknowns.begin();
542  feVectorContainerPtrIterate_Type iter_end = this->M_unknowns.end();
543 
544  //!initialize zero
545  feVector_Type zero (x0);
546  zero *= 0;
547 
548  for ( ; iter != iter_end; ++iter )
549  {
550  delete *iter;
551  *iter = new feVector_Type (zero, Unique);
552  }
553 
554  this->M_unknowns.push_back (new feVector_Type (x0) );
555  this->M_unknowns.push_back (new feVector_Type (v0) );
556 
557  for (UInt i = 0; i < 4; ++i )
558  {
559  this->M_unknowns.push_back (new feVector_Type (zero, Unique) );
560  *this->M_unknowns[i + 2] *= 0;
561  }
562  this->setInitialRHS (zero);
563 }
564 
565 template<typename feVectorType>
566 void TimeAdvanceNewmark<feVectorType>::setInitialCondition ( const feVector_Type& x0, const feVector_Type& v0, const feVector_Type& w0)
567 {
568  feVectorContainerPtrIterate_Type iter = this->M_unknowns.begin();
569  feVectorContainerPtrIterate_Type iter_end = this->M_unknowns.end();
570 
571  //!initialize zero
572  feVector_Type zero (x0);
573  zero *= 0;
574 
575  for ( ; iter != iter_end; ++iter )
576  {
577  delete *iter;
578  *iter = new feVector_Type (zero, Unique);
579  }
580 
581  this->M_unknowns.push_back (new feVector_Type (x0) );
582  this->M_unknowns.push_back (new feVector_Type (v0) );
583  this->M_unknowns.push_back (new feVector_Type (w0) );
584 
585  for (UInt i = 0; i < 3; ++i )
586  {
587  this->M_unknowns.push_back (new feVector_Type (zero, Unique) );
588  *this->M_unknowns[i + 3] *= 0;
589  }
590  this->setInitialRHS (zero);
591 }
592 
593 template<typename feVectorType>
594 void TimeAdvanceNewmark<feVectorType>::setInitialCondition ( const feVectorSharedPtrContainer_Type& x0)
595 {
596  const UInt n0 = x0.size();
597 
598  ASSERT ( n0 != 0, "vector null " );
599 
600  feVectorContainerPtrIterate_Type iter = this->M_unknowns.begin();
601  feVectorContainerPtrIterate_Type iter_end = this->M_unknowns.end();
602 
603  UInt i (0);
604 
605  //!initialize zero
606  feVector_Type zero (*x0[0]);
607  zero *= 0;
608 
609  for ( ; iter != iter_end && i < n0 ; ++iter, ++i )
610  {
611  delete *iter;
612  *iter = new feVector_Type (*x0[i]);
613  }
614 
615  for ( i = this->M_unknowns.size() ; i < this->M_size && i < n0; ++i )
616  {
617  this->M_unknowns.push_back (new feVector_Type (*x0[i]) );
618  }
619 
620  for ( i = this->M_unknowns.size() ; i < this->M_size; i++ )
621  {
622  this->M_unknowns.push_back (new feVector_Type ( *x0[ n0 - 1 ] ) );
623  }
624 
625  this->setInitialRHS (zero);
626 }
627 
628 // ===================================================
629 // Get Methods
630 // ===================================================
631 
632 template<typename feVectorType>
633 Real
634 TimeAdvanceNewmark<feVectorType>::coefficientExtrapolation (const UInt& i) const
635 {
636  ASSERT ( i < 3 , "coeff_der i must equal 0 or 1 because U^*= U^n + timeStep*V^n + timeStep^2 / 2 W^n");
637 
638  switch (i)
639  {
640  case 0:
641  return this->M_beta (i);
642  case 1:
643  return this->M_beta (i) * this->M_timeStep;
644  case 2:
645  return this->M_beta (i) * this->M_timeStep * this->M_timeStep;
646  default:
647  ERROR_MSG ("coeff_der i must equal 0 or 1 because U^*= U^n + timeStep*V^n + timeStep^2 / 2 W^n");
648  }
649  return 1;
650 }
651 
652 template<typename feVectorType>
653 Real
654 TimeAdvanceNewmark<feVectorType>::coefficientExtrapolationFirstDerivative (const UInt& i ) const
655 {
656  switch (i)
657  {
658  case 0:
659  return this->M_betaFirstDerivative (i);
660  case 1:
661  return this->M_betaFirstDerivative (i) * this->M_timeStep;
662  case 2:
663  return this->M_betaFirstDerivative (i) * this->M_timeStep * this->M_timeStep;
664  default:
665  ERROR_MSG ("coeff_der i must equal 0 or 1 because U^*= U^n + timeStep*V^n + timeStep^2 / 2 W^n");
666  }
667  return 1;
668 }
669 
670 template<typename feVectorType>
671 void
672 TimeAdvanceNewmark<feVectorType>::extrapolation (feVector_Type& extrapolation) const
673 {
674  extrapolation += this->M_timeStep * ( *this->M_unknowns[ 1 ]);
675 
676  if ( this->M_orderDerivative == 2 )
677  {
678  extrapolation += ( this->M_timeStep * this->M_timeStep ) / 2.0 * ( *this->M_unknowns[2]);
679  }
680 }
681 
682 
683 template<typename feVectorType>
684 void
685 TimeAdvanceNewmark<feVectorType>::extrapolationFirstDerivative (feVector_Type& extrapolation) const
686 {
687  ASSERT ( this->M_orderDerivative == 2,
688  "extrapolationFirstDerivative: this method must be used with the second order problem." )
689 
690  extrapolation = *this->M_unknowns[1];
691  extrapolation += this->M_timeStep * ( *this->M_unknowns[ 2 ]);
692 }
693 
694 // ===================================================
695 // Macros
696 // ===================================================
697 
698 //! define the TimeAdvanceNewmark; this class runs only the default template parameter.
699 inline
700 TimeAdvance< VectorEpetra >* createTimeAdvanceNewmark()
701 {
702  return new TimeAdvanceNewmark< VectorEpetra >();
703 }
704 
705 namespace
706 {
707 static bool registerTimeAdvanceNewmark = TimeAdvanceFactory::instance().registerProduct ( "Newmark", &createTimeAdvanceNewmark);
708 }
709 
710 }
711 #endif /*TimeAdvanceNewmark*/
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
double Real
Generic real data.
Definition: LifeV.hpp:175
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191