46 #include <boost/core/ignore_unused.hpp>
52 namespace LibUtilities
84 int nvar = y_0.size();
85 int npoints = y_0[0].size();
87 for (i = 0; i < nvar; i++)
95 for (i = 0; i < nvar; i++)
99 y_out->SetDerivative(0, f_y_0, deltaT);
114 int nvar = solvector->GetFirstDim();
115 int npoints = solvector->GetSecondDim();
117 if (solvector->GetIntegrationSchemeData() !=
152 unsigned int nCurSchemeVals =
155 unsigned int nCurSchemeDers =
158 unsigned int nCurSchemeSteps =
163 unsigned int nMasterSchemeVals =
164 solvector->GetNvalues();
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 < nCurSchemeSteps; n++)
202 dtFy_n = solvector->GetDerivative(curTimeLevels[n]);
206 solvector_in->SetDerivative(curTimeLevels[n], dtFy_n, deltaT);
218 solvector_in->GetSolutionVector(),
219 solvector_in->GetTimeVector(),
220 solvector_out->UpdateSolutionVector(),
221 solvector_out->UpdateTimeVector(), op);
233 bool CalcNewDeriv =
false;
239 if (nMasterSchemeDers > 0)
241 if (nCurSchemeDers == 0)
247 if (masterTimeLevels[nMasterSchemeVals] <
248 curTimeLevels[nCurSchemeVals])
257 int newDerivTimeLevel =
258 masterTimeLevels[nMasterSchemeVals];
270 if (newDerivTimeLevel == 0)
272 y_n = solvector_out->GetValue(0);
273 t_n = solvector_out->GetValueTime(0);
278 else if (newDerivTimeLevel == 1)
280 y_n = solvector->GetValue(0);
281 t_n = solvector->GetValueTime(0);
285 ASSERTL1(
false,
"Problems with initialising scheme");
289 for (
int j = 0; j < nvar; j++)
299 for (
int j = 0; j < nvar; j++)
301 Vmath::Smul(npoints, deltaT, f_n[j], 1, f_n[j], 1);
306 solvector->RotateSolutionVector();
310 solvector->SetDerivative(newDerivTimeLevel, f_n, deltaT);
316 solvector->RotateSolutionVector();
322 for (
int n = 0; n < nCurSchemeVals; n++)
330 y_n = solvector_out->GetValue(curTimeLevels[n]);
331 t_n = solvector_out->GetValueTime(curTimeLevels[n]);
334 solvector->SetValue(curTimeLevels[n], y_n, t_n);
337 for (
int n = nCurSchemeVals; n < nCurSchemeSteps; n++)
343 dtFy_n = solvector_out->GetDerivative(curTimeLevels[n]);
347 solvector->SetDerivative(curTimeLevels[n], dtFy_n, deltaT);
354 this, nvar, npoints);
357 solvector->GetSolutionVector(),
358 solvector->GetTimeVector(),
359 solvector_new->UpdateSolutionVector(),
360 solvector_new->UpdateTimeVector(), op);
362 solvector = solvector_new;
365 return solvector->GetSolution();
381 "Arguments not well defined");
390 for (
int j = 0; j <
m_nvars; j++)
413 for (
int j = 0; j <
m_nvars; j++)
427 for (
int j = 0; j <
m_nvars; j++)
439 for (
int j = 0; j <
m_nvars; j++)
451 for (
int j = 0; j <
m_nvars; j++)
470 InitializeSecondaryData(
this, deltaT );
482 for (
int k = 0; k <
m_nvars; k++)
495 for (
int k = 0; k <
m_nvars; k++)
517 m_T =
A(stage, 0) * deltaT;
519 for (
int j = 1; j < stage; j++)
521 for (
int k = 0; k <
m_nvars; k++)
542 m_T +=
A(stage, j) * deltaT;
548 for (
int k = 0; k <
m_nvars; k++)
562 m_T +=
U(stage, j) * t_old[j];
577 m_T = t_old[0] + deltaT;
582 for (
int j = 0; j <= stage; ++j)
584 m_T +=
A(stage, j) * deltaT;
590 for (
int k = 0; k <
m_nvars; ++k)
595 m_F[stage][k], 1,
m_F[stage][k], 1);
599 else if (type ==
eIMEX)
603 m_T = t_old[0] + deltaT;
608 for (
int j = 0; j <= stage; ++j)
610 m_T +=
A(stage, j) * deltaT;
618 for (
int k = 0; k <
m_nvars; k++)
623 m_F[stage][k], 1,
m_F[stage][k], 1);
656 for (
int k = 0; k <
m_nvars; k++)
663 t_new[0] = t_old[0] + deltaT;
667 t_new[0] =
B(0, 0) * deltaT;
671 t_new[0] +=
B(0, j) * deltaT;
676 t_new[0] +=
V(0, j) * t_old[j];
688 for (
int k = 0; k <
m_nvars; k++)
693 m_F[0][k], 1, y_new[i][k], 1);
698 m_F[0][k], 1, y_new[i][k], 1);
704 m_F_IMEX[0][k], 1, y_new[i][k], 1, y_new[i][k], 1);
710 t_new[i] =
B(i, 0) * deltaT;
715 for (
int k = 0; k <
m_nvars; k++)
720 m_F[j][k], 1, y_new[i][k], 1, y_new[i][k], 1);
725 m_F[j][k], 1, y_new[i][k], 1, y_new[i][k], 1);
738 t_new[i] +=
B(i, j) * deltaT;
746 for (
int k = 0; k <
m_nvars; k++)
751 y_new[i][k], 1, y_new[i][k], 1);
756 y_new[i][k], 1, y_new[i][k], 1);
762 t_new[i] +=
V(i, j) * t_old[j];
782 for (
int m = 0; m <
m_A.size(); m++)
822 for (
int m = 0; m <
m_A.size(); m++)
851 int IMEXdim =
m_A.size();
852 int dim =
m_A[0].GetRows();
859 for (
int m = 0; m < IMEXdim; m++)
861 for (
int i = 0; i < dim; i++)
869 for (
int i = 0; i < dim; i++)
871 for (
int j = i + 1; j < dim; j++)
876 ASSERTL1(
false,
"Fully Implicit schemes cannnot be handled "
877 "by the TimeIntegrationScheme class");
885 ASSERTL1(
m_B.size() == 2,
"Coefficient Matrix B should have an "
886 "implicit and explicit part for IMEX schemes");
894 ASSERTL1(
false,
"This is not a proper IMEX scheme");
899 "Time integration scheme coefficients do not match its type");
911 boost::ignore_unused(op);
913 boost::ignore_unused(y_old, t_old, y_new, t_new, op);
919 "Non-matching number of steps.");
921 "Non-matching number of steps.");
923 ASSERTL1(y_old[0].size() == y_new[0].size(),
924 "Non-matching number of variables.");
925 ASSERTL1(y_old[0][0].size() == y_new[0][0].size(),
926 "Non-matching number of coefficients.");
929 "Non-matching number of steps.");
931 "Non-matching number of steps.");
953 os <<
"Time Integration Scheme (Master): "
955 <<
"Time Integration Phase : " << rhs.
m_name <<
"\n"
956 <<
"- number of steps: " << r <<
"\n"
957 <<
"- number of stages: " << s <<
"\n"
958 <<
"General linear method tableau:\n";
960 for (
int i = 0; i < s; i++)
962 for (
int j = 0; j < s; j++)
965 os.precision(osprecision);
966 os << std::right << rhs.
A(i, j) <<
" ";
971 for (
int j = 0; j < s; j++)
974 os.precision(osprecision);
975 os << std::right << rhs.
A_IMEX(i, j) <<
" ";
981 for (
int j = 0; j < r; j++)
984 os.precision(osprecision);
985 os << std::right << rhs.
U(i, j);
990 int imexflag = (type ==
eIMEX) ? 2 : 1;
991 for (
int i = 0; i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1;
998 for (
int i = 0; i < r; i++)
1000 for (
int j = 0; j < s; j++)
1003 os.precision(osprecision);
1004 os << std::right << rhs.
B(i, j) <<
" ";
1009 for (
int j = 0; j < s; j++)
1012 os.precision(osprecision);
1013 os << std::right << rhs.
B_IMEX(i, j) <<
" ";
1019 for (
int j = 0; j < r; j++)
1022 os.precision(osprecision);
1023 os << std::right << rhs.
V(i, j);
1029 os.precision(osprecision);
1034 os << std::right <<
" value";
1038 os << std::right <<
" derivative";
1046 for (
int k = 0; k < rhs.
m_nvars; k++)
1049 <<
"General linear method exponential tableau for variable "
1052 for (
int i = 0; i < s; i++)
1054 for (
int j = 0; j < s; j++)
1057 os.precision(osprecision);
1058 os << std::right << rhs.
m_A_phi[k][i][j] <<
" ";
1063 for (
int j = 0; j < r; j++)
1066 os.precision(osprecision);
1067 os << std::right << rhs.
m_U_phi[k][i][j];
1072 int imexflag = (type ==
eIMEX) ? 2 : 1;
1073 for (
int i = 0; i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1;
1080 for (
int i = 0; i < r; i++)
1082 for (
int j = 0; j < s; j++)
1085 os.precision(osprecision);
1086 os << std::right << rhs.
m_B_phi[k][i][j] <<
" ";
1091 for (
int j = 0; j < r; j++)
1094 os.precision(osprecision);
1095 os << std::right << rhs.
m_V_phi[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
Array< OneD, Array< TwoD, NekDouble > > m_A_phi
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
Array< OneD, Array< TwoD, NekDouble > > m_B_phi
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
Array< OneD, Array< TwoD, NekDouble > > m_V_phi
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
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
Array< OneD, Array< TwoD, NekDouble > > m_U_phi
Base class for GLM time integration schemes.
virtual 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.