36 #ifndef NEKTAR_LIB_UTILITIES_FOUNDATIONS_TIMEINTEGRATIONSCHEME_H
37 #define NEKTAR_LIB_UTILITIES_FOUNDATIONS_TIMEINTEGRATIONSCHEME_H
47 namespace LibUtilities
50 class TimeIntegrationScheme;
104 "NoTimeIntegrationMethod",
105 "AdamsBashforthOrder1",
106 "AdamsBashforthOrder2",
107 "AdamsBashforthOrder3",
108 "AdamsMoultonOrder1",
109 "AdamsMoultonOrder2",
112 "ClassicalRungeKutta4",
115 "RungeKutta2_ImprovedEuler",
150 "NoTimeIntegrationSchemeType",
152 "DiagonallyImplicit",
168 typedef boost::function< void (InArrayType&, OutArrayType&, const NekDouble) >
FunctorType1;
169 typedef boost::function< void (InArrayType&, OutArrayType&, const NekDouble, const NekDouble) >
FunctorType2;
183 template<
typename FuncPo
interT,
typename ObjectPo
interT>
186 m_functors1[0] = boost::bind(func, obj, _1, _2, _3);
189 template<
typename FuncPo
interT,
typename ObjectPo
interT>
192 m_functors1[1] = boost::bind(func, obj, _1, _2, _3);
195 template<
typename FuncPo
interT,
typename ObjectPo
interT>
198 m_functors1[2] = boost::bind(func, obj, _1, _2, _3);
201 template<
typename FuncPo
interT,
typename ObjectPo
interT>
204 m_functors1[3] = boost::bind(func, obj, _1, _2, _3);
207 template<
typename FuncPo
interT,
typename ObjectPo
interT>
210 m_functors2[0] = boost::bind(func, obj, _1, _2, _3, _4);
215 OutArrayType &outarray,
218 ASSERTL1(!(
m_functors1[0].empty()),
"OdeRhs should be defined for this time integration scheme");
223 OutArrayType &outarray,
226 ASSERTL1(!(
m_functors1[1].empty()),
"OdeExplicitRhs should be defined for this time integration scheme");
231 OutArrayType &outarray,
234 ASSERTL1(!(
m_functors1[2].empty()),
"OdeImplictRhs should be defined for this time integration scheme");
239 OutArrayType &outarray,
242 ASSERTL1(!(
m_functors1[3].empty()),
"Projection operation should be defined for this time integration scheme");
247 OutArrayType &outarray,
251 ASSERTL1(!(
m_functors2[0].empty()),
"ImplicitSolve should be defined for this time integration scheme");
309 return (*
this == *y);
314 return (!(*
this == y));
319 return (!(*
this == *y));
352 typedef NekManager<TimeIntegrationSchemeKey,
353 TimeIntegrationScheme,
361 class TimeIntegrationScheme
371 typedef boost::function< void (ConstDoubleArray&, DoubleArray&, const NekDouble) >
FunctorType1;
372 typedef boost::function< void (ConstDoubleArray&, DoubleArray&, const NekDouble, const NekDouble) >
FunctorType2;
395 inline NekDouble A(
const unsigned int i,
const unsigned int j)
const
400 inline NekDouble B(
const unsigned int i,
const unsigned int j)
const
405 inline NekDouble U(
const unsigned int i,
const unsigned int j)
const
410 inline NekDouble V(
const unsigned int i,
const unsigned int j)
const
479 ConstDoubleArray &y_0 ,
502 TimeIntegrationSolutionSharedPtr &y ,
577 ConstTripleArray &y_old ,
578 ConstSingleArray &t_old ,
586 return y[0].num_elements();
591 return y[0][0].num_elements();
595 ConstTripleArray &y_old ,
596 ConstSingleArray &t_old ,
627 const DoubleArray& y,
632 const TripleArray& y,
636 unsigned int npoints);
646 return m_scheme->GetIntegrationSchemeKey();
651 return m_scheme->GetIntegrationMethod();
708 return m_scheme->GetNmultiStepValues();
715 return m_scheme->GetNmultiStepDerivs();
722 return m_scheme->GetTimeLevelOffset();
727 inline DoubleArray&
GetValue(
const unsigned int timeLevelOffset)
729 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
732 for(
int i = 0; i < nMultiStepVals; i++)
734 if( timeLevelOffset == offsetvec[i] )
739 ASSERTL1(
false,
"The solution vector of this scheme does not contain a value at the requested time-level");
747 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
751 for(
int i = nMultiStepVals; i < size; i++)
753 if( timeLevelOffset == offsetvec[i] )
758 ASSERTL1(
false,
"The solution vector of this scheme does not contain a derivative at the requested time-level");
766 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
769 for(
int i = 0; i < nMultiStepVals; i++)
771 if( timeLevelOffset == offsetvec[i] )
776 ASSERTL1(
false,
"The solution vector of this scheme does not contain a value at the requested time-level");
783 inline void SetValue(
const unsigned int timeLevelOffset,
const DoubleArray& y,
const NekDouble t)
785 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
788 for(
int i = 0; i < nMultiStepVals; i++)
790 if( timeLevelOffset == offsetvec[i] )
804 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
808 for(
int i = nMultiStepVals; i < size; i++)
810 if( timeLevelOffset == offsetvec[i] )
830 int nMultiStepVals =
m_scheme->GetNmultiStepValues();
832 for(i = (nMultiStepVals-1); i > 0; i--)
837 for(i = (size-1); i > nMultiStepVals; i--)
860 #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 (old name)
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
Classical RungeKutta4 method (new name for eClassicalRungeKutta4)
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)
Nonlinear SSP RungeKutta3 explicit.
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)
Classical RungeKutta2 method (new name for eMidpoint)
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.
Nonlinear SSP RungeKutta2 explicit (surrogate for eRungeKutta2_ImprovedEuler)
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
Improved RungeKutta2 explicit (old name meaning Heun's method)
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
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.
midpoint method (old name)
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