40 #ifndef TimeAdvanceNewmark_H 41 #define TimeAdvanceNewmark_H 1
51 #include <lifev/core/fem/TimeAdvance.hpp> 52 #include <lifev/core/array/VectorEpetra.hpp> 120 template<
typename feVectorType = VectorEpetra >
121 class TimeAdvanceNewmark:
122 public TimeAdvance < feVectorType >
130 typedef TimeAdvance< feVectorType > super;
132 typedef typename super::feVector_Type feVector_Type;
134 typedef typename super::feVectorContainer_Type feVectorContainer_Type;
137 typedef typename super::feVectorContainerPtr_Type feVectorContainerPtr_Type;
140 typedef typename feVectorContainerPtr_Type::iterator feVectorContainerPtrIterate_Type;
143 typedef typename super::feVectorSharedPtrContainer_Type feVectorSharedPtrContainer_Type;
151 TimeAdvanceNewmark();
154 virtual ~TimeAdvanceNewmark() {}
165 void shiftRight (
const feVector_Type& solution);
173 void RHSFirstDerivative (
const Real& timeStep, feVectorType& rhsContribution)
const;
180 void updateRHSSecondDerivative (
const Real& timeStep = 1 );
183 void showMe (std::ostream& output = std::cout)
const;
197 ERROR_MSG (
"use setup for TimeAdvanceBDF but the time advance scheme is Newmark");
205 void setup (
const std::vector<Real>& coefficients,
const UInt& orderDerivative);
213 void setInitialCondition (
const feVector_Type& x0);
222 void setInitialCondition (
const feVector_Type& x0,
const feVector_Type& v0 );
232 void setInitialCondition (
const feVector_Type& x0,
const feVector_Type& v0,
const feVector_Type& w0 );
239 void setInitialCondition (
const feVectorSharedPtrContainer_Type& x0);
251 Real coefficientExtrapolation (
const UInt& i )
const;
258 Real coefficientExtrapolationFirstDerivative (
const UInt& i )
const;
266 void extrapolation (feVector_Type& extrapolation)
const;
273 void extrapolationFirstDerivative (feVector_Type& extrapolation)
const;
276 feVector_Type firstDerivative()
const 278 return ( *
this->M_unknowns[1]);
282 feVector_Type secondDerivative()
const 284 return *
this->M_unknowns[2];
302 template<
typename feVectorType>
303 TimeAdvanceNewmark <feVectorType> ::TimeAdvanceNewmark() : super()
310 template<
typename feVectorType>
311 void TimeAdvanceNewmark <feVectorType>::shiftRight (
const feVector_Type& solution)
313 ASSERT (
this->M_timeStep != 0 ,
"M_timeStep must be different to 0");
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();
319 for ( ; itb1 != it; ++itb1, ++itb)
324 itb =
this->M_unknowns.begin();
327 *itb =
new feVector_Type ( solution );
332 feVector_Type velocityTemp (solution);
333 velocityTemp *=
this->M_alpha[0] /
this->M_timeStep;
334 velocityTemp -= *
this->M_rhsContribution[0];
337 *itb =
new feVector_Type (velocityTemp);
339 if (
this->M_orderDerivative == 2 )
344 feVector_Type accelerationTemp ( solution );
345 accelerationTemp *=
this->M_xi[ 0 ] / (
this->M_timeStep *
this->M_timeStep);
346 accelerationTemp -= *
this->M_rhsContribution[ 1 ];
348 *itb =
new feVector_Type ( accelerationTemp );
353 template<
typename feVectorType>
355 TimeAdvanceNewmark<feVectorType>::RHSFirstDerivative (
const Real& timeStep, feVectorType& rhsContribution )
const 357 rhsContribution *= (
this->M_alpha[ 1 ] / timeStep) ;
359 Real timeStepPower (1.);
361 for (
UInt i = 1; i <
this->M_firstOrderDerivativeSize; ++i )
363 rhsContribution += (
this->M_alpha[ i + 1 ] * timeStepPower ) * (*
this->M_unknowns[ i ]);
364 timeStepPower *= timeStep;
368 template<
typename feVectorType>
370 TimeAdvanceNewmark<feVectorType>::updateRHSSecondDerivative (
const Real& timeStep )
372 feVectorContainerPtrIterate_Type it =
this->M_rhsContribution.end() - 1;
374 *it =
new feVector_Type (*
this->M_unknowns[0]);
376 ** it *=
this->M_xi[ 1 ] / (timeStep * timeStep) ;
378 for (
UInt i = 1; i <
this->M_secondOrderDerivativeSize; ++i )
380 **it += (
this->M_xi[ i + 1 ] * std::pow (timeStep,
static_cast<Real> (i - 2) ) ) * ( *
this->M_unknowns[ i ]);
384 template<
typename feVectorType>
386 TimeAdvanceNewmark<feVectorType>::showMe (std::ostream& output )
const 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";
395 for (
UInt i = 0; i <
this->M_alpha.size(); ++i )
397 output <<
" alpha(" << i <<
") = " <<
this->M_alpha[ i ] << std::endl;
400 if (
this->M_orderDerivative == 2)
402 for (
UInt i = 0; i <
this->M_xi.size(); ++i )
404 output <<
" xi(" << i <<
") = " <<
this->M_xi[ i ] << std::endl;
408 output <<
"Delta Time : " <<
this->M_timeStep <<
"\n";
409 output <<
"*************************************\n";
416 template<
typename feVectorType>
418 TimeAdvanceNewmark<feVectorType>::setup (
const std::vector<Real>& coefficients,
const UInt& orderDerivative)
421 M_theta = coefficients[0];
424 M_gamma = coefficients[1];
427 this->M_orderDerivative = orderDerivative;
432 ASSERT (
this->M_orderDerivative == 2,
"theta is 0 must be different from 0 in TimeAdvanceNewmark");
434 this->M_alpha[ 0 ] = 1;
435 this->M_alpha[ 1 ] = 1;
436 this->M_alpha[ 2 ] = 1;
441 if (
this->M_orderDerivative == 1 )
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;
454 this->M_beta[2] = 0.5;
458 this->M_coefficientsSize = 3;
464 this->M_alpha.resize (4);
465 this->M_xi.resize (4);
466 this->M_beta.resize (3);
467 this->M_betaFirstDerivative.resize (3);
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;
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;
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;
489 this->M_coefficientsSize = 4;
491 this->M_unknowns.reserve (
this->M_size);
492 this-> M_rhsContribution.reserve (2);
494 if (
this->M_alpha[0] == 0.5)
503 this->M_firstOrderDerivativeSize =
static_cast<
Real> (
this->M_size) / 2.0;
504 this->M_secondOrderDerivativeSize =
static_cast<
Real> (
this->M_size) / 2.0;
508 template<
typename feVectorType>
509 void TimeAdvanceNewmark<feVectorType>::setInitialCondition (
const feVector_Type& x0)
511 feVectorContainerPtrIterate_Type iter =
this->M_unknowns.begin();
512 feVectorContainerPtrIterate_Type iter_end =
this->M_unknowns.end();
514 feVector_Type zero (x0);
517 for ( ; iter != iter_end; ++iter )
520 *iter =
new feVector_Type (zero,
Unique);
523 for (
UInt i (
this->M_unknowns.size() ) ; i <
this->M_size; ++i )
525 this->M_unknowns.push_back (
new feVector_Type (x0) );
528 feVectorContainerPtrIterate_Type iterRhs =
this->M_rhsContribution.begin();
529 feVectorContainerPtrIterate_Type iterRhs_end =
this->M_rhsContribution.end();
531 for ( ; iterRhs != iterRhs_end ; ++iterRhs)
534 *iterRhs =
new feVector_Type (zero,
Unique);
538 template<
typename feVectorType>
539 void TimeAdvanceNewmark<feVectorType>::setInitialCondition (
const feVector_Type& x0,
const feVector_Type& v0)
541 feVectorContainerPtrIterate_Type iter =
this->M_unknowns.begin();
542 feVectorContainerPtrIterate_Type iter_end =
this->M_unknowns.end();
545 feVector_Type zero (x0);
548 for ( ; iter != iter_end; ++iter )
551 *iter =
new feVector_Type (zero,
Unique);
554 this->M_unknowns.push_back (
new feVector_Type (x0) );
555 this->M_unknowns.push_back (
new feVector_Type (v0) );
557 for (
UInt i = 0; i < 4; ++i )
559 this->M_unknowns.push_back (
new feVector_Type (zero,
Unique) );
560 *
this->M_unknowns[i + 2] *= 0;
562 this->setInitialRHS (zero);
565 template<
typename feVectorType>
566 void TimeAdvanceNewmark<feVectorType>::setInitialCondition (
const feVector_Type& x0,
const feVector_Type& v0,
const feVector_Type& w0)
568 feVectorContainerPtrIterate_Type iter =
this->M_unknowns.begin();
569 feVectorContainerPtrIterate_Type iter_end =
this->M_unknowns.end();
572 feVector_Type zero (x0);
575 for ( ; iter != iter_end; ++iter )
578 *iter =
new feVector_Type (zero,
Unique);
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) );
585 for (
UInt i = 0; i < 3; ++i )
587 this->M_unknowns.push_back (
new feVector_Type (zero,
Unique) );
588 *
this->M_unknowns[i + 3] *= 0;
590 this->setInitialRHS (zero);
593 template<
typename feVectorType>
594 void TimeAdvanceNewmark<feVectorType>::setInitialCondition (
const feVectorSharedPtrContainer_Type& x0)
596 const UInt n0 = x0.size();
598 ASSERT ( n0 != 0,
"vector null " );
600 feVectorContainerPtrIterate_Type iter =
this->M_unknowns.begin();
601 feVectorContainerPtrIterate_Type iter_end =
this->M_unknowns.end();
606 feVector_Type zero (*x0[0]);
609 for ( ; iter != iter_end && i < n0 ; ++iter, ++i )
612 *iter =
new feVector_Type (*x0[i]);
615 for ( i =
this->M_unknowns.size() ; i <
this->M_size && i < n0; ++i )
617 this->M_unknowns.push_back (
new feVector_Type (*x0[i]) );
620 for ( i =
this->M_unknowns.size() ; i <
this->M_size; i++ )
622 this->M_unknowns.push_back (
new feVector_Type ( *x0[ n0 - 1 ] ) );
625 this->setInitialRHS (zero);
632 template<
typename feVectorType>
634 TimeAdvanceNewmark<feVectorType>::coefficientExtrapolation (
const UInt& i)
const 636 ASSERT ( i < 3 ,
"coeff_der i must equal 0 or 1 because U^*= U^n + timeStep*V^n + timeStep^2 / 2 W^n");
641 return this->M_beta (i);
643 return this->M_beta (i) *
this->M_timeStep;
645 return this->M_beta (i) *
this->M_timeStep *
this->M_timeStep;
647 ERROR_MSG (
"coeff_der i must equal 0 or 1 because U^*= U^n + timeStep*V^n + timeStep^2 / 2 W^n");
652 template<
typename feVectorType>
654 TimeAdvanceNewmark<feVectorType>::coefficientExtrapolationFirstDerivative (
const UInt& i )
const 659 return this->M_betaFirstDerivative (i);
661 return this->M_betaFirstDerivative (i) *
this->M_timeStep;
663 return this->M_betaFirstDerivative (i) *
this->M_timeStep *
this->M_timeStep;
665 ERROR_MSG (
"coeff_der i must equal 0 or 1 because U^*= U^n + timeStep*V^n + timeStep^2 / 2 W^n");
670 template<
typename feVectorType>
672 TimeAdvanceNewmark<feVectorType>::extrapolation (feVector_Type& extrapolation)
const 674 extrapolation +=
this->M_timeStep * ( *
this->M_unknowns[ 1 ]);
676 if (
this->M_orderDerivative == 2 )
678 extrapolation += (
this->M_timeStep *
this->M_timeStep ) / 2.0 * ( *
this->M_unknowns[2]);
683 template<
typename feVectorType>
685 TimeAdvanceNewmark<feVectorType>::extrapolationFirstDerivative (feVector_Type& extrapolation)
const 687 ASSERT (
this->M_orderDerivative == 2,
688 "extrapolationFirstDerivative: this method must be used with the second order problem." )
690 extrapolation = *
this->M_unknowns[1];
691 extrapolation +=
this->M_timeStep * ( *
this->M_unknowns[ 2 ]);
700 TimeAdvance< VectorEpetra >* createTimeAdvanceNewmark()
702 return new TimeAdvanceNewmark< VectorEpetra >();
static const LifeV::UInt elm_nodes_num[]
double Real
Generic real data.
uint32_type UInt
generic unsigned integer (used mainly for addressing)