36 #ifndef NEKTAR_LIB_UTILITIES_FOUNDATIONS_TIMEINTEGRATIONSCHEME_H
37 #define NEKTAR_LIB_UTILITIES_FOUNDATIONS_TIMEINTEGRATIONSCHEME_H
47 namespace LibUtilities
50 class TimeIntegrationScheme;
101 "NoTimeIntegrationMethod",
102 "AdamsBashforthOrder1",
103 "AdamsBashforthOrder2",
104 "AdamsBashforthOrder3",
105 "AdamsMoultonOrder1",
106 "AdamsMoultonOrder2",
109 "ClassicalRungeKutta4",
110 "RungeKutta2_ModifiedEuler",
111 "RungeKutta2_ImprovedEuler",
144 "NoTimeIntegrationSchemeType",
146 "DiagonallyImplicit",
162 typedef boost::function< void (InArrayType&, OutArrayType&, const NekDouble) >
FunctorType1;
163 typedef boost::function< void (InArrayType&, OutArrayType&, const NekDouble, const NekDouble) >
FunctorType2;
177 template<
typename FuncPo
interT,
typename ObjectPo
interT>
180 m_functors1[0] = boost::bind(func, obj, _1, _2, _3);
183 template<
typename FuncPo
interT,
typename ObjectPo
interT>
186 m_functors1[1] = boost::bind(func, obj, _1, _2, _3);
189 template<
typename FuncPo
interT,
typename ObjectPo
interT>
192 m_functors1[2] = boost::bind(func, obj, _1, _2, _3);
195 template<
typename FuncPo
interT,
typename ObjectPo
interT>
198 m_functors1[3] = boost::bind(func, obj, _1, _2, _3);
201 template<
typename FuncPo
interT,
typename ObjectPo
interT>
204 m_functors2[0] = boost::bind(func, obj, _1, _2, _3, _4);
209 OutArrayType &outarray,
212 ASSERTL1(!(
m_functors1[0].empty()),
"OdeRhs should be defined for this time integration scheme");
217 OutArrayType &outarray,
220 ASSERTL1(!(
m_functors1[1].empty()),
"OdeExplicitRhs should be defined for this time integration scheme");
225 OutArrayType &outarray,
228 ASSERTL1(!(
m_functors1[2].empty()),
"OdeImplictRhs should be defined for this time integration scheme");
233 OutArrayType &outarray,
236 ASSERTL1(!(
m_functors1[3].empty()),
"Projection operation should be defined for this time integration scheme");
241 OutArrayType &outarray,
245 ASSERTL1(!(
m_functors2[0].empty()),
"ImplicitSolve should be defined for this time integration scheme");
303 return (*
this == *y);
308 return (!(*
this == y));
313 return (!(*
this == *y));
346 typedef NekManager<TimeIntegrationSchemeKey,
347 TimeIntegrationScheme,
355 class TimeIntegrationScheme
365 typedef boost::function< void (ConstDoubleArray&, DoubleArray&, const NekDouble) >
FunctorType1;
366 typedef boost::function< void (ConstDoubleArray&, DoubleArray&, const NekDouble, const NekDouble) >
FunctorType2;
389 inline NekDouble A(
const unsigned int i,
const unsigned int j)
const
394 inline NekDouble B(
const unsigned int i,
const unsigned int j)
const
399 inline NekDouble U(
const unsigned int i,
const unsigned int j)
const
404 inline NekDouble V(
const unsigned int i,
const unsigned int j)
const
473 ConstDoubleArray &y_0 ,
496 TimeIntegrationSolutionSharedPtr &y ,
571 ConstTripleArray &y_old ,
572 ConstSingleArray &t_old ,
580 return y[0].num_elements();
585 return y[0][0].num_elements();
589 ConstTripleArray &y_old ,
590 ConstSingleArray &t_old ,
621 const DoubleArray& y,
626 const TripleArray& y,
630 unsigned int npoints);
640 return m_scheme->GetIntegrationSchemeKey();
645 return m_scheme->GetIntegrationMethod();
702 return m_scheme->GetNmultiStepValues();
709 return m_scheme->GetNmultiStepDerivs();
716 return m_scheme->GetTimeLevelOffset();
721 inline DoubleArray&
GetValue(
const unsigned int timeLevelOffset)
723 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
726 for(
int i = 0; i < nMultiStepVals; i++)
728 if( timeLevelOffset == offsetvec[i] )
733 ASSERTL1(
false,
"The solution vector of this scheme does not contain a value at the requested time-level");
741 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
745 for(
int i = nMultiStepVals; i < size; i++)
747 if( timeLevelOffset == offsetvec[i] )
752 ASSERTL1(
false,
"The solution vector of this scheme does not contain a derivative at the requested time-level");
760 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
763 for(
int i = 0; i < nMultiStepVals; i++)
765 if( timeLevelOffset == offsetvec[i] )
770 ASSERTL1(
false,
"The solution vector of this scheme does not contain a value at the requested time-level");
777 inline void SetValue(
const unsigned int timeLevelOffset,
const DoubleArray& y,
const NekDouble t)
779 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
782 for(
int i = 0; i < nMultiStepVals; i++)
784 if( timeLevelOffset == offsetvec[i] )
798 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
802 for(
int i = nMultiStepVals; i < size; i++)
804 if( timeLevelOffset == offsetvec[i] )
824 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
826 for(i = (nMultiStepVals-1); i > 0; i--)
831 for(i = (size-1); i > nMultiStepVals; i--)
854 #endif //NEKTAR_LIB_UTILITIES_FOUNDATIONS_TIMEINTEGRATIONSCHEME_H
NekDouble GetValueTime(const unsigned int timeLevelOffset)
TimeIntegrationSchemeKey(const TimeIntegrationMethod &method)
unsigned int GetNmultiStepValues(void) const
std::vector< TimeIntegrationSchemeSharedPtr > TimeIntegrationSchemeVector
boost::function< void(ConstDoubleArray &, DoubleArray &, const NekDouble, const NekDouble) > FunctorType2
NekDouble B_IMEX(const unsigned int i, const unsigned int j) const
unsigned int GetNmultiStepDerivs(void) const
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
NekDouble U(const unsigned int i, const unsigned int j) const
NekDouble B(const unsigned int i, const unsigned int j) const
bool m_firstStageEqualsOldSolution
TimeIntegrationSchemeKey & operator=(const TimeIntegrationSchemeKey &key)
BDF multi-step scheme of order 1 (implicit)
Array< OneD, unsigned int > m_timeLevelOffset
Adams-Bashforth Forward multi-step scheme of order 2.
Array< OneD, Array< TwoD, NekDouble > > m_B
static const TimeIntegrationSchemeKey NullTimeIntegrationSchemeKey(eNoTimeIntegrationMethod)
int m_nvar
bool to identify if array has been initialised
void DefineImplicitSolve(FuncPointerT func, ObjectPointerT obj)
Runge-Kutta multi-stage scheme 4th order explicit.
Implicit-Explicit Midpoint IMEX DIRK(1,2,2)
NekDouble GetTime() const
void DoImplicitSolve(InArrayType &inarray, OutArrayType &outarray, const NekDouble time, const NekDouble lambda) const
Array< OneD, NekDouble > & UpdateTimeVector()
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
const char *const TimeIntegrationSchemeTypeMap[]
DoubleArray m_tmp
Array containing the stage values.
TimeIntegrationMethod GetIntegrationMethod() const
Array< OneD, FunctorType1 > FunctorType1Array
Array< OneD, NekDouble > SingleArray
void DefineOdeExplicitRhs(FuncPointerT func, ObjectPointerT obj)
NekDouble V(const unsigned int i, const unsigned int j) const
const DoubleArray & GetSolution() const
Formally explicit scheme.
TimeIntegrationSolutionSharedPtr InitializeScheme(const NekDouble timestep, ConstDoubleArray &y_0, const NekDouble time, const TimeIntegrationSchemeOperators &op)
This function initialises the time integration scheme.
L-stable, four stage, third order IMEX DIRK(4,4,3)
Forward-Backward Euler IMEX DIRK(1,2,1)
TimeIntegrationSchemeOperators(void)
void DefineOdeImplicitRhs(FuncPointerT func, ObjectPointerT obj)
bool operator==(const TimeIntegrationSchemeKey &key)
Implicit Explicit General Linear Method.
boost::function< void(InArrayType &, OutArrayType &, const NekDouble, const NekDouble) > FunctorType2
const char *const TimeIntegrationMethodMap[]
TimeIntegrationSchemeKey m_schemeKey
void DoOdeRhs(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
NekManager< TimeIntegrationSchemeKey, TimeIntegrationScheme, TimeIntegrationSchemeKey::opLess > TimeIntegrationSchemeManagerT
const TimeIntegrationSchemeSharedPtr & GetIntegrationScheme() const
bool operator!=(const TimeIntegrationSchemeKey &y)
bool operator()(const TimeIntegrationSchemeKey &lhs, const TimeIntegrationSchemeKey &rhs) const
std::vector< TimeIntegrationSolutionSharedPtr >::iterator TimeIntegrationSolutionVectorIter
DoubleArray m_Y
The size of inner data which is stored for reuse.
TimeIntegrationSchemeManagerT & TimeIntegrationSchemeManager(void)
Adams-Moulton Forward multi-step scheme of order 2.
std::vector< TimeIntegrationSchemeSharedPtr >::iterator TimeIntegrationSchemeVectorIter
Adams-Bashforth Forward multi-step scheme of order 3.
bool operator==(const BasisKey &x, const BasisKey &y)
unsigned int GetNstages(void) const
void SetValue(const unsigned int timeLevelOffset, const DoubleArray &y, const NekDouble t)
Crank-Nicolson/Adams-Bashforth Order 2 (CNAB)
int GetSecondDim(ConstTripleArray &y) const
const Array< OneD, const Array< OneD, Array< OneD, NekDouble > > > ConstTripleArray
DoubleArray & GetDerivative(const unsigned int timeLevelOffset)
TimeIntegrationSchemeSharedPtr m_scheme
const TripleArray & GetSolutionVector() const
const FunctorType1 & ConstFunctorType1Ref
boost::function< void(InArrayType &, OutArrayType &, const NekDouble) > FunctorType1
IMEX 2nd order scheme using Backward Different Formula & Extrapolation.
std::ostream & operator<<(std::ostream &os, const BasisKey &rhs)
const FunctorType2 & ConstFunctorType2Ref
TripleArray m_F
explicit right hand side of each stage equation
Diagonally implicit scheme (e.g. the DIRK schemes)
void DefineProjection(FuncPointerT func, ObjectPointerT obj)
TimeIntegrationSchemeType m_schemeType
bool CheckIfFirstStageEqualsOldSolution(const Array< OneD, const Array< TwoD, NekDouble > > &A, const Array< OneD, const Array< TwoD, NekDouble > > &B, const Array< TwoD, const NekDouble > &U, const Array< TwoD, const NekDouble > &V) const
const Array< OneD, const Array< OneD, NekDouble > > InArrayType
FunctorType2Array m_functors2
Adams-Moulton Forward multi-step scheme of order 1.
NekDouble A_IMEX(const unsigned int i, const unsigned int j) const
void SetDerivative(const unsigned int timeLevelOffset, const DoubleArray &y, const NekDouble timestep)
void DefineOdeRhs(FuncPointerT func, ObjectPointerT obj)
Adams-Bashforth Forward multi-step scheme of order 1.
TimeIntegrationSolution(const TimeIntegrationSchemeKey &key, const DoubleArray &y, const NekDouble time, const NekDouble timestep)
const TimeIntegrationSchemeKey & GetIntegrationSchemeKey() const
int GetFirstDim(ConstTripleArray &y) const
virtual ~TimeIntegrationSchemeKey()
#define LIB_UTILITIES_EXPORT
Array< OneD, Array< OneD, NekDouble > > DoubleArray
L-stable, three stage, third order IMEX DIRK(3,4,3)
friend TimeIntegrationSchemeManagerT & TimeIntegrationSchemeManager(void)
TimeIntegrationSchemeKey(const TimeIntegrationSchemeKey &key)
int m_npoints
The number of variables in integration scheme.
ConstDoubleArray & TimeIntegrate(const NekDouble timestep, TimeIntegrationSolutionSharedPtr &y, const TimeIntegrationSchemeOperators &op)
Explicit integration of an ODE.
bool CheckTimeIntegrateArguments(const NekDouble timestep, ConstTripleArray &y_old, ConstSingleArray &t_old, TripleArray &y_new, SingleArray &t_new, const TimeIntegrationSchemeOperators &op) const
Runge-Kutta multi-stage scheme 2nd order explicit.
Forward-Backward Euler IMEX DIRK(1,1,1)
DoubleArray & UpdateSolution()
Array< OneD, Array< OneD, NekDouble > > DoubleArray
TimeIntegrationSchemeKey()
NekDouble A(const unsigned int i, const unsigned int j) const
DoubleArray & GetValue(const unsigned int timeLevelOffset)
void SetSolVector(const int Offset, const DoubleArray &y)
TimeIntegrationMethod GetIntegrationMethod() const
void RotateSolutionVector()
void DoOdeImplicitRhs(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
TripleArray & UpdateSolutionVector()
unsigned int GetNvalues(void) const
void DoProjection(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
bool operator<(const BasisKey &lhs, const BasisKey &rhs)
TimeIntegrationSchemeType GetIntegrationSchemeType() const
boost::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
unsigned int m_numMultiStepDerivs
FunctorType1Array m_functors1
static boost::shared_ptr< TimeIntegrationScheme > Create(const TimeIntegrationSchemeKey &key)
unsigned int m_numMultiStepValues
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > TripleArray
Array< OneD, NekDouble > m_t
TimeIntegrationScheme(const TimeIntegrationScheme &in)
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
BDF multi-step scheme of order 2 (implicit)
L-stable, two stage, second order IMEX DIRK(2,2,2)
TimeIntegrationMethod m_method
integration method
Runge-Kutta multi-stage scheme 2nd order explicit.
void DoOdeExplicitRhs(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
bool VerifyIntegrationSchemeType(TimeIntegrationSchemeType type, const Array< OneD, const Array< TwoD, NekDouble > > &A, const Array< OneD, const Array< TwoD, NekDouble > > &B, const Array< TwoD, const NekDouble > &U, const Array< TwoD, const NekDouble > &V) const
Array< OneD, Array< OneD, NekDouble > > OutArrayType
Diagonally Implicit Runge Kutta scheme of order 3.
IMEX 3rd order scheme using Backward Different Formula & Extrapolation.
const Array< OneD, const NekDouble > ConstSingleArray
L-stable, three stage, third order IMEX DIRK(3,4,3)
Diagonally Implicit Runge Kutta scheme of order 3.
boost::shared_ptr< TimeIntegrationSolution > TimeIntegrationSolutionSharedPtr
std::vector< TimeIntegrationSolutionSharedPtr > TimeIntegrationSolutionVector
const Array< OneD, const unsigned int > & GetTimeLevelOffset()
L-stable, two stage, third order IMEX DIRK(2,3,3)
unsigned int GetNsteps(void) const
bool m_lastStageEqualsNewSolution
bool CheckIfLastStageEqualsNewSolution(const Array< OneD, const Array< TwoD, NekDouble > > &A, const Array< OneD, const Array< TwoD, NekDouble > > &B, const Array< TwoD, const NekDouble > &U, const Array< TwoD, const NekDouble > &V) const
unsigned int GetNderivs(void) const
boost::function< void(ConstDoubleArray &, DoubleArray &, const NekDouble) > FunctorType1
TimeIntegrationMethod GetIntegrationMethod() const
Array< OneD, Array< TwoD, NekDouble > > m_A
const Array< OneD, const NekDouble > & GetTimeVector() const
Modified Crank-Nicolson/Adams-Bashforth Order 2 (MCNAB)
virtual ~TimeIntegrationScheme()
IMEX 1st order scheme using Euler Backwards/Euler Forwards.
const Array< OneD, const unsigned int > & GetTimeLevelOffset()
NekDouble m_T
Used to store the Explicit stage derivative of IMEX schemes.
Array< OneD, Array< OneD, Array< OneD, NekDouble > > > TripleArray
Array< TwoD, NekDouble > m_U
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
const TimeIntegrationSchemeKey & GetIntegrationSchemeKey() const
TripleArray m_F_IMEX
Array corresponding to the stage Derivatives.
Array< OneD, FunctorType2 > FunctorType2Array
const Array< OneD, const Array< OneD, NekDouble > > ConstDoubleArray
friend bool operator<(const TimeIntegrationSchemeKey &lhs, const TimeIntegrationSchemeKey &rhs)
TimeIntegrationSchemeType
Array< TwoD, NekDouble > m_V