46 #include <boost/core/ignore_unused.hpp>
52 namespace LibUtilities
66 this, y_0, time, deltaT);
83 int nvar = y_0.size();
84 int npoints = y_0[0].size();
86 for (i = 0; i < nvar; i++)
94 for (i = 0; i < nvar; i++)
98 y_out->SetDerivative(0, f_y_0, deltaT);
112 int nvar = solvector->GetFirstDim();
113 int npoints = solvector->GetSecondDim();
115 if (solvector->GetIntegrationSchemeData() !=
this)
148 unsigned int nCurSchemeVals =
151 unsigned int nCurSchemeImpDers =
154 unsigned int nCurSchemeDers =
157 unsigned int nCurSchemeSteps =
160 unsigned int nMasterSchemeVals =
161 solvector->GetNvalues();
162 unsigned int nMasterSchemeImpDers =
163 solvector->GetNimplicitderivs();
165 unsigned int nMasterSchemeDers =
166 solvector->GetNderivs();
173 solvector->GetTimeLevelOffset();
182 for (
int n = 0; n < nCurSchemeVals; n++)
188 y_n = solvector->GetValue(curTimeLevels[n]);
189 t_n = solvector->GetValueTime(curTimeLevels[n]);
193 solvector_in->SetValue(curTimeLevels[n], y_n, t_n);
196 for (
int n = nCurSchemeVals; n < nCurSchemeVals + nCurSchemeImpDers;
203 dtFy_n = solvector->GetImplicitDerivative(curTimeLevels[n]);
207 solvector_in->SetImplicitDerivative(curTimeLevels[n], dtFy_n,
211 for (
int n = nCurSchemeVals + nCurSchemeImpDers; n < nCurSchemeSteps;
218 dtFy_n = solvector->GetDerivative(curTimeLevels[n]);
222 solvector_in->SetDerivative(curTimeLevels[n], dtFy_n, deltaT);
234 solvector_in->GetTimeVector(),
235 solvector_out->UpdateSolutionVector(),
236 solvector_out->UpdateTimeVector(), op);
248 bool CalcNewImpDeriv =
false;
253 bool CalcNewDeriv =
false;
259 if (nMasterSchemeImpDers > 0)
261 if (nCurSchemeImpDers == 0)
263 CalcNewImpDeriv =
true;
267 if (masterTimeLevels[nMasterSchemeVals] <
268 curTimeLevels[nCurSchemeVals])
270 CalcNewImpDeriv =
true;
275 if (nMasterSchemeDers > 0)
277 if (nCurSchemeDers == 0)
283 if (masterTimeLevels[nMasterSchemeVals + nMasterSchemeImpDers] <
284 curTimeLevels[nCurSchemeVals + nCurSchemeImpDers])
292 int newImpDerivTimeLevel = (masterTimeLevels.size() > nMasterSchemeVals)
293 ? masterTimeLevels[nMasterSchemeVals]
303 if (newImpDerivTimeLevel == 0 || newImpDerivTimeLevel == 1)
305 y_n = solvector->GetValue(newImpDerivTimeLevel);
306 t_n = solvector->GetValueTime(newImpDerivTimeLevel);
310 ASSERTL1(
false,
"Problems with initialising scheme");
313 for (
int j = 0; j < nvar; j++)
322 for (
int j = 0; j < nvar; j++)
329 int newDerivTimeLevel =
330 (masterTimeLevels.size() > nMasterSchemeVals)
331 ? masterTimeLevels[nMasterSchemeVals + nMasterSchemeImpDers]
346 if (newDerivTimeLevel == 0)
348 y_n = solvector_out->GetValue(0);
349 t_n = solvector_out->GetValueTime(0);
354 else if (newDerivTimeLevel == 1)
356 y_n = solvector->GetValue(0);
357 t_n = solvector->GetValueTime(0);
361 ASSERTL1(
false,
"Problems with initialising scheme");
364 for (
int j = 0; j < nvar; j++)
374 for (
int j = 0; j < nvar; j++)
376 Vmath::Smul(npoints, deltaT, f_n[j], 1, f_n[j], 1);
382 solvector->RotateSolutionVector();
387 y_n = solvector_out->GetValue(0);
388 t_n = solvector_out->GetValueTime(0);
390 solvector->SetValue(0, y_n, t_n);
396 solvector->SetImplicitDerivative(newImpDerivTimeLevel, f_impn,
399 else if (nCurSchemeImpDers > 0 && nMasterSchemeImpDers > 0)
403 dtFy_n = solvector_out->GetImplicitDerivative(newImpDerivTimeLevel);
407 solvector->SetImplicitDerivative(newImpDerivTimeLevel, dtFy_n,
415 solvector->SetDerivative(newDerivTimeLevel, f_n, deltaT);
417 else if (nCurSchemeDers > 0 && nMasterSchemeDers > 0)
421 dtFy_n = solvector_out->GetDerivative(newDerivTimeLevel);
425 solvector->SetDerivative(newDerivTimeLevel, dtFy_n, deltaT);
432 this, nvar, npoints);
435 solvector->GetTimeVector(),
436 solvector_new->UpdateSolutionVector(),
437 solvector_new->UpdateTimeVector(), op);
439 solvector = solvector_new;
442 return solvector->GetSolution();
454 "Arguments not well defined");
463 for (
int j = 0; j <
m_nvars; j++)
486 for (
int j = 0; j <
m_nvars; j++)
500 for (
int j = 0; j <
m_nvars; j++)
512 for (
int j = 0; j <
m_nvars; j++)
524 for (
int j = 0; j <
m_nvars; j++)
543 ->InitializeSecondaryData(
this, deltaT);
555 for (
int k = 0; k <
m_nvars; k++)
568 for (
int k = 0; k <
m_nvars; k++)
582 m_T =
A(stage, 0) * deltaT;
584 for (
int j = 1; j < stage; j++)
586 for (
int k = 0; k <
m_nvars; k++)
599 m_T +=
A(stage, j) * deltaT;
605 for (
int k = 0; k <
m_nvars; k++)
611 m_T +=
U(stage, j) * t_old[j];
629 m_T = t_old[0] + deltaT;
634 for (
int j = 0; j <= stage; ++j)
636 m_T +=
A(stage, j) * deltaT;
642 for (
int k = 0; k <
m_nvars; ++k)
647 m_F[stage][k], 1,
m_F[stage][k], 1);
651 else if (type ==
eIMEX)
655 m_T = t_old[0] + deltaT;
660 for (
int j = 0; j <= stage; ++j)
662 m_T +=
A(stage, j) * deltaT;
670 for (
int k = 0; k <
m_nvars; k++)
675 m_F[stage][k], 1,
m_F[stage][k], 1);
708 for (
int k = 0; k <
m_nvars; k++)
715 t_new[0] = t_old[0] + deltaT;
719 t_new[0] =
B(0, 0) * deltaT;
723 t_new[0] +=
B(0, j) * deltaT;
728 t_new[0] +=
V(0, j) * t_old[j];
740 for (
int k = 0; k <
m_nvars; k++)
748 1, y_new[i][k], 1, y_new[i][k], 1);
754 t_new[i] =
B(i, 0) * deltaT;
759 for (
int k = 0; k <
m_nvars; k++)
762 y_new[i][k], 1, y_new[i][k], 1);
767 m_F_IMEX[j][k], 1, y_new[i][k], 1, y_new[i][k],
774 t_new[i] +=
B(i, j) * deltaT;
782 for (
int k = 0; k <
m_nvars; k++)
790 t_new[i] +=
V(i, j) * t_old[j];
811 for (
int m = 0; m <
m_A.size(); m++)
851 for (
int m = 0; m <
m_A.size(); m++)
881 int IMEXdim =
m_A.size();
882 int dim =
m_A[0].GetRows();
889 for (
int m = 0; m < IMEXdim; m++)
891 for (
int i = 0; i < dim; i++)
899 for (
int i = 0; i < dim; i++)
901 for (
int j = i + 1; j < dim; j++)
906 ASSERTL1(
false,
"Fully Implicit schemes cannnot be handled "
907 "by the TimeIntegrationScheme class");
916 "Coefficient Matrix B should have an "
917 "implicit and explicit part for IMEX schemes");
925 ASSERTL1(
false,
"This is not a proper IMEX scheme");
930 "Time integration scheme coefficients do not match its type");
939 boost::ignore_unused(op);
941 boost::ignore_unused(y_old, t_old, y_new, t_new, op);
949 ASSERTL1(y_old[0].size() == y_new[0].size(),
950 "Non-matching number of variables.");
951 ASSERTL1(y_old[0][0].size() == y_new[0][0].size(),
952 "Non-matching number of coefficients.");
979 <<
"Time Integration Phase : " << rhs.
m_name <<
"\n"
980 <<
"- number of steps: " << r <<
"\n"
981 <<
"- number of stages: " << s <<
"\n"
982 <<
"General linear method tableau:\n";
984 for (
int i = 0; i < s; i++)
986 for (
int j = 0; j < s; j++)
989 os.precision(osprecision);
990 os << std::right << rhs.
A(i, j) <<
" ";
995 for (
int j = 0; j < s; j++)
998 os.precision(osprecision);
999 os << std::right << rhs.
A_IMEX(i, j) <<
" ";
1005 for (
int j = 0; j < r; j++)
1008 os.precision(osprecision);
1009 os << std::right << rhs.
U(i, j);
1014 int imexflag = (type ==
eIMEX) ? 2 : 1;
1015 for (
int i = 0; i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1;
1022 for (
int i = 0; i < r; i++)
1024 for (
int j = 0; j < s; j++)
1027 os.precision(osprecision);
1028 os << std::right << rhs.
B(i, j) <<
" ";
1033 for (
int j = 0; j < s; j++)
1036 os.precision(osprecision);
1037 os << std::right << rhs.
B_IMEX(i, j) <<
" ";
1043 for (
int j = 0; j < r; j++)
1046 os.precision(osprecision);
1047 os << std::right << rhs.
V(i, j);
1053 os.precision(osprecision);
1058 os << std::right <<
" value";
1062 os << std::right <<
" derivative";
1070 for (
int k = 0; k < rhs.
m_nvars; k++)
1073 <<
"General linear method exponential tableau for variable " << k
1076 for (
int i = 0; i < s; i++)
1078 for (
int j = 0; j < s; j++)
1081 os.precision(osprecision);
1082 os << std::right << rhs.
A(k, i, j) <<
" ";
1087 for (
int j = 0; j < r; j++)
1090 os.precision(osprecision);
1091 os << std::right << rhs.
B(k, i, j);
1096 int imexflag = (type ==
eIMEX) ? 2 : 1;
1098 i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1; i++)
1104 for (
int i = 0; i < r; i++)
1106 for (
int j = 0; j < s; j++)
1109 os.precision(osprecision);
1110 os << std::right << rhs.
B(k, i, j) <<
" ";
1115 for (
int j = 0; j < r; j++)
1118 os.precision(osprecision);
1119 os << std::right << rhs.
V(k, i, j);
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
void CheckIfLastStageEqualsNewSolution()
TimeIntegrationSchemeType m_schemeType
Array< TwoD, NekDouble > m_U
int GetFirstDim(ConstTripleArray &y) const
void VerifyIntegrationSchemeType()
int GetSecondDim(ConstTripleArray &y) const
NekDouble A(const unsigned int i, const unsigned int j) const
unsigned int m_numMultiStepValues
Array< TwoD, NekDouble > m_V
NekDouble m_lastNVars
Last delta T.
TripleArray m_F
Explicit RHS of each stage equation.
bool CheckTimeIntegrateArguments(ConstTripleArray &y_old, ConstSingleArray &t_old, TripleArray &y_new, SingleArray &t_new, const TimeIntegrationSchemeOperators &op) const
void CheckIfFirstStageEqualsOldSolution()
unsigned int GetNsteps(void) const
int m_npoints
The size of inner data which is stored for reuse.
DoubleArray m_tmp
Array containing the stage values.
NekDouble B_IMEX(const unsigned int i, const unsigned int j) const
NekDouble V(const unsigned int i, const unsigned int j) const
Array< OneD, Array< TwoD, NekDouble > > m_B
bool m_lastStageEqualsNewSolution
const TimeIntegrationScheme * m_parent
Parent scheme object.
Array< OneD, Array< TwoD, NekDouble > > m_A
unsigned int GetNmultiStepValues() const
NekDouble m_T
Used to store the Explicit stage derivative of IMEX schemes.
const Array< OneD, const unsigned int > & GetTimeLevelOffset() const
bool m_firstStageEqualsOldSolution
Time at the different stages.
unsigned int GetNmultiStepDerivs() const
NekDouble A_IMEX(const unsigned int i, const unsigned int j) const
unsigned int GetNmultiStepImplicitDerivs() const
NekDouble B(const unsigned int i, const unsigned int j) const
LUE ConstDoubleArray & TimeIntegrate(const NekDouble deltaT, TimeIntegrationSolutionGLMSharedPtr &y, const TimeIntegrationSchemeOperators &op)
Explicit integration of an ODE.
LUE TimeIntegrationSolutionGLMSharedPtr InitializeData(const NekDouble deltaT, ConstDoubleArray &y_0, const NekDouble time, const TimeIntegrationSchemeOperators &op)
This function initialises the time integration scheme.
int m_nvars
Last number of vars.
NekDouble m_lastDeltaT
bool to identify array initialization
NekDouble U(const unsigned int i, const unsigned int j) const
TripleArray m_F_IMEX
Array corresponding to the stage Derivatives.
Array< OneD, unsigned int > m_timeLevelOffset
Base class for GLM time integration schemes.
LUE std::string GetFullName() const
Binds a set of functions for use by time integration schemes.
void DoImplicitSolve(InArrayType &inarray, OutArrayType &outarray, const NekDouble time, const NekDouble lambda) const
void DoProjection(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
void DoOdeRhs(InArrayType &inarray, OutArrayType &outarray, const NekDouble time) const
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
static void Dscal(const int &n, const double &alpha, double *x, const int &incx)
BLAS level 1: x = alpha x.
AT< AT< NekDouble > > DoubleArray
std::shared_ptr< TimeIntegrationAlgorithmGLM > TimeIntegrationAlgorithmGLMSharedPtr
TimeIntegrationSchemeType
@ eImplicit
Fully implicit scheme.
@ eExplicit
Formally explicit scheme.
@ eExponential
Exponential scheme.
@ eDiagonallyImplicit
Diagonally implicit scheme (e.g. the DIRK schemes)
@ eIMEX
Implicit Explicit General Linear Method.
std::shared_ptr< TimeIntegrationSolutionGLM > TimeIntegrationSolutionGLMSharedPtr
AT< AT< AT< NekDouble > > > TripleArray
std::ostream & operator<<(std::ostream &os, const BasisKey &rhs)
static const NekDouble kNekZeroTol
The above copyright notice and this permission notice shall be included.
void Svtvp(int n, const T alpha, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
svtvp (scalar times vector plus vector): z = alpha*x + y
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
void Zero(int n, T *x, const int incx)
Zero vector.
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.