62 this, y_0, time, deltaT);
85 size_t nvar = y_0.size();
86 size_t npoints = y_0[0].size();
88 for (
size_t i = 0; i < nvar; i++)
97 for (
size_t i = 0; i < nvar; i++)
99 Vmath::Smul(npoints, deltaT, f_y_0[i], 1, f_y_0[i], 1);
101 y_out->SetExplicitDerivative(0, f_y_0, deltaT);
111 size_t nvar = solvector->GetFirstDim();
112 size_t npoints = solvector->GetSecondDim();
114 if (solvector->GetIntegrationSchemeData() !=
this)
152 size_t nMasterSchemeVals = solvector->GetNvalues();
155 size_t nMasterSchemeImpDers = solvector->GetNimplicitderivs();
158 size_t nMasterSchemeExpDers = solvector->GetNexplicitderivs();
167 solvector->GetTimeLevelOffset();
181 for (
size_t n = 0; n < nCurSchemeVals; n++)
184 y_n = solvector->GetValue(curTimeLevels[n]);
185 t_n = solvector->GetValueTime(curTimeLevels[n]);
189 solvector_in->SetValue(curTimeLevels[n], y_n, t_n);
193 for (
size_t n = nCurSchemeVals; n < nCurSchemeVals + nCurSchemeImpDers;
197 dtFy_n = solvector->GetImplicitDerivative(curTimeLevels[n]);
201 solvector_in->SetImplicitDerivative(curTimeLevels[n], dtFy_n,
206 for (
size_t n = nCurSchemeVals + nCurSchemeImpDers; n < nCurSchemeSteps;
210 dtFy_n = solvector->GetExplicitDerivative(curTimeLevels[n]);
214 solvector_in->SetExplicitDerivative(curTimeLevels[n], dtFy_n,
223 this, nvar, npoints);
227 solvector_in->GetTimeVector(),
228 solvector_out->UpdateSolutionVector(),
229 solvector_out->UpdateTimeVector());
242 bool CalcNewImpDeriv =
false;
244 if (nMasterSchemeImpDers > 0)
246 if (nCurSchemeImpDers == 0 || (masterTimeLevels[nMasterSchemeVals] <
247 curTimeLevels[nCurSchemeVals]))
249 CalcNewImpDeriv =
true;
256 bool CalcNewExpDeriv =
false;
258 if (nMasterSchemeExpDers > 0)
260 if (nCurSchemeExpDers == 0 ||
261 (masterTimeLevels[nMasterSchemeVals + nMasterSchemeImpDers] <
262 curTimeLevels[nCurSchemeVals + nCurSchemeImpDers]))
264 CalcNewExpDeriv =
true;
270 size_t newImpDerivTimeLevel =
271 (masterTimeLevels.size() > nMasterSchemeVals)
272 ? masterTimeLevels[nMasterSchemeVals]
280 if (newImpDerivTimeLevel == 0 || newImpDerivTimeLevel == 1)
282 y_n = solvector->GetValue(newImpDerivTimeLevel);
283 t_n = solvector->GetValueTime(newImpDerivTimeLevel);
287 ASSERTL1(
false,
"Problems with initialising scheme");
290 for (
size_t j = 0; j < nvar; j++)
297 for (
size_t j = 0; j < nvar; j++)
305 size_t newExpDerivTimeLevel =
306 (masterTimeLevels.size() > nMasterSchemeVals + nMasterSchemeImpDers)
307 ? masterTimeLevels[nMasterSchemeVals + nMasterSchemeImpDers]
317 if (newExpDerivTimeLevel == 0)
319 y_n = solvector_out->GetValue(0);
320 t_n = solvector_out->GetValueTime(0);
324 else if (newExpDerivTimeLevel == 1)
326 y_n = solvector->GetValue(0);
327 t_n = solvector->GetValueTime(0);
331 ASSERTL1(
false,
"Problems with initialising scheme");
334 for (
size_t j = 0; j < nvar; j++)
340 if (newExpDerivTimeLevel == 1)
350 for (
size_t j = 0; j < nvar; j++)
352 Vmath::Smul(npoints, deltaT, f_expn[j], 1, f_expn[j], 1);
358 solvector->RotateSolutionVector();
364 y_n = solvector_out->GetValue(0);
365 t_n = solvector_out->GetValueTime(0);
368 if (newExpDerivTimeLevel == 1)
373 solvector->SetValue(0, y_n, t_n);
379 solvector->SetImplicitDerivative(newImpDerivTimeLevel, f_impn,
382 else if (nCurSchemeImpDers > 0 && nMasterSchemeImpDers > 0)
386 dtFy_n = solvector_out->GetImplicitDerivative(newImpDerivTimeLevel);
389 solvector->SetImplicitDerivative(newImpDerivTimeLevel, dtFy_n,
397 solvector->SetExplicitDerivative(newExpDerivTimeLevel, f_expn,
400 else if (nCurSchemeExpDers > 0 && nMasterSchemeExpDers > 0)
404 dtFy_n = solvector_out->GetExplicitDerivative(newExpDerivTimeLevel);
407 solvector->SetExplicitDerivative(newExpDerivTimeLevel, dtFy_n,
415 this, nvar, npoints);
418 solvector->GetTimeVector(),
419 solvector_new->UpdateSolutionVector(),
420 solvector_new->UpdateTimeVector());
422 solvector = solvector_new;
425 return solvector->GetSolution();
437 "Arguments not well defined");
446 for (
size_t j = 0; j <
m_nvars; j++)
468 for (
size_t j = 0; j <
m_nvars; j++)
482 for (
size_t j = 0; j <
m_nvars; j++)
494 for (
size_t j = 0; j <
m_nvars; j++)
506 for (
size_t j = 0; j <
m_nvars; j++)
534 for (
size_t stage = 0; stage <
m_numstages; stage++)
538 for (
size_t k = 0; k <
m_nvars; k++)
549 for (
size_t k = 0; k <
m_nvars; k++)
563 for (
size_t j = 1; j < stage; j++)
565 for (
size_t k = 0; k <
m_nvars; k++)
582 for (
size_t k = 0; k <
m_nvars; k++)
595 m_T = t_old[0] + deltaT;
600 for (
size_t j = 0; j <= stage; ++j)
602 m_T +=
A(stage, j) * deltaT;
617 for (
size_t k = 0; k <
m_nvars; ++k)
622 m_F[stage][k], 1,
m_F[stage][k], 1);
626 else if (type ==
eIMEX)
630 m_T = t_old[0] + deltaT;
635 for (
size_t j = 0; j <= stage; ++j)
637 m_T +=
A(stage, j) * deltaT;
645 for (
size_t k = 0; k <
m_nvars; k++)
650 m_F[stage][k], 1,
m_F[stage][k], 1);
665 for (
size_t j = 0; j < stage; ++j)
667 m_T +=
A(stage, j) * deltaT;
694 for (
size_t k = 0; k <
m_nvars; k++)
699 t_new[0] = t_old[0] + deltaT;
708 for (
size_t k = 0; k <
m_nvars; k++)
716 1, y_new[i][k], 1, y_new[i][k], 1);
722 t_new[i] =
B(i, 0) * deltaT;
727 for (
size_t k = 0; k <
m_nvars; k++)
730 y_new[i][k], 1, y_new[i][k], 1);
735 m_F_IMEX[j][k], 1, y_new[i][k], 1, y_new[i][k],
742 t_new[i] +=
B(i, j) * deltaT;
749 for (
size_t k = 0; k <
m_nvars; k++)
757 t_new[i] +=
V(i, j) * t_old[j];
778 for (
size_t m = 0; m <
m_A.size(); m++)
818 for (
size_t m = 0; m <
m_A.size(); m++)
848 size_t IMEXdim =
m_A.size();
849 size_t dim =
m_A[0].GetRows();
858 for (
size_t m = 0; m < IMEXdim; m++)
860 for (
size_t i = 0; i < dim; i++)
868 for (
size_t i = 0; i < dim; i++)
870 for (
size_t j = i + 1; j < dim; j++)
875 ASSERTL1(
false,
"Fully Implicit schemes cannnot be handled "
876 "by the TimeIntegrationScheme class");
885 "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");
914 ASSERTL1(y_old[0].size() == y_new[0].size(),
915 "Non-matching number of variables.");
916 ASSERTL1(y_old[0][0].size() == y_new[0][0].size(),
917 "Non-matching number of coefficients.");
940 size_t osprecision = 6;
944 <<
"Time Integration Phase : " << rhs.
m_name <<
"\n"
945 <<
"- number of steps: " << r <<
"\n"
946 <<
"- number of stages: " << s <<
"\n"
947 <<
"General linear method tableau:\n";
949 for (
size_t i = 0; i < s; i++)
951 for (
size_t j = 0; j < s; j++)
954 os.precision(osprecision);
955 os << std::right << rhs.
A(i, j) <<
" ";
960 for (
size_t j = 0; j < s; j++)
963 os.precision(osprecision);
964 os << std::right << rhs.
A_IMEX(i, j) <<
" ";
970 for (
size_t j = 0; j < r; j++)
973 os.precision(osprecision);
974 os << std::right << rhs.
U(i, j);
979 size_t imexflag = (type ==
eIMEX) ? 2 : 1;
981 i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1; i++)
987 for (
size_t i = 0; i < r; i++)
989 for (
size_t j = 0; j < s; j++)
992 os.precision(osprecision);
993 os << std::right << rhs.
B(i, j) <<
" ";
998 for (
size_t j = 0; j < s; j++)
1001 os.precision(osprecision);
1002 os << std::right << rhs.
B_IMEX(i, j) <<
" ";
1008 for (
size_t j = 0; j < r; j++)
1011 os.precision(osprecision);
1012 os << std::right << rhs.
V(i, j);
1018 os.precision(osprecision);
1023 os << std::right <<
" value";
1027 os << std::right <<
" derivative";
1035 for (
size_t k = 0; k < rhs.
m_nvars; k++)
1038 <<
"General linear method exponential tableau for variable " << k
1041 for (
size_t i = 0; i < s; i++)
1043 for (
size_t j = 0; j < s; j++)
1046 os.precision(osprecision);
1047 os << std::right << rhs.
A(k, i, j) <<
" ";
1052 for (
size_t j = 0; j < r; j++)
1055 os.precision(osprecision);
1056 os << std::right << rhs.
B(k, i, j);
1062 i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1; i++)
1068 for (
size_t i = 0; i < r; i++)
1070 for (
size_t j = 0; j < s; j++)
1073 os.precision(osprecision);
1074 os << std::right << rhs.
B(k, i, j) <<
" ";
1079 for (
size_t j = 0; j < r; j++)
1082 os.precision(osprecision);
1083 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()
size_t GetFirstDim(ConstTripleArray &y) const
TimeIntegrationSchemeType m_schemeType
Array< TwoD, NekDouble > m_U
size_t GetNsteps(void) const
void VerifyIntegrationSchemeType()
TimeIntegrationSchemeOperators m_op
size_t m_nvars
Last number of vars.
Array< TwoD, NekDouble > m_V
NekDouble V(const size_t i, const size_t j) const
NekDouble m_lastNVars
Last delta T.
const TimeIntegrationSchemeGLM * m_parent
Parent scheme object.
TripleArray m_F
Explicit RHS of each stage equation.
void CheckIfFirstStageEqualsOldSolution()
Optimisation-flag.
DoubleArray m_tmp
Array containing the stage values.
NekDouble A(const size_t i, const size_t j) const
size_t GetSecondDim(ConstTripleArray &y) const
NekDouble B_IMEX(const size_t i, const size_t j) const
size_t GetNmultiStepExplicitDerivs() const
Array< OneD, Array< TwoD, NekDouble > > m_B
size_t m_numMultiStepValues
bool CheckTimeIntegrateArguments(ConstTripleArray &y_old, ConstSingleArray &t_old, TripleArray &y_new, SingleArray &t_new) const
bool m_lastStageEqualsNewSolution
Optimisation-flag.
NekDouble A_IMEX(const size_t i, const size_t j) const
NekDouble B(const size_t i, const size_t j) const
Array< OneD, Array< TwoD, NekDouble > > m_A
size_t GetNmultiStepImplicitDerivs() const
NekDouble U(const size_t i, const size_t j) const
NekDouble m_T
Used to store the Explicit stage derivative of IMEX schemes.
bool m_firstStageEqualsOldSolution
ime at the different stages
size_t GetNmultiStepValues() const
const Array< OneD, const size_t > & GetTimeLevelOffset() const
size_t m_npoints
The number of variables in integration scheme.
void InitializeScheme(const TimeIntegrationSchemeOperators &op)
LUE ConstDoubleArray & TimeIntegrate(const NekDouble deltaT, TimeIntegrationSolutionGLMSharedPtr &y)
Explicit integration of an ODE.
Array< OneD, size_t > m_timeLevelOffset
LUE TimeIntegrationSolutionGLMSharedPtr InitializeData(const NekDouble deltaT, ConstDoubleArray &y_0, const NekDouble time)
This function initialises the time integration scheme.
TripleArray m_F_IMEX
Array corresponding to the stage Derivatives.
LUE void InitializeSecondaryData(TimeIntegrationAlgorithmGLM *phase, NekDouble deltaT) const
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.
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
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.