43#include <boost/core/ignore_unused.hpp>
66 this, y_0, time, deltaT);
82 size_t nvar = y_0.size();
83 size_t npoints = y_0[0].size();
85 for (
size_t i = 0; i < nvar; i++)
94 for (
size_t i = 0; i < nvar; i++)
96 Vmath::Smul(npoints, deltaT, f_y_0[i], 1, f_y_0[i], 1);
98 y_out->SetExplicitDerivative(0, f_y_0, deltaT);
108 size_t nvar = solvector->GetFirstDim();
109 size_t npoints = solvector->GetSecondDim();
111 if (solvector->GetIntegrationSchemeData() !=
this)
149 size_t nMasterSchemeVals = solvector->GetNvalues();
152 size_t nMasterSchemeImpDers = solvector->GetNimplicitderivs();
155 size_t nMasterSchemeExpDers = solvector->GetNexplicitderivs();
164 solvector->GetTimeLevelOffset();
178 for (
size_t n = 0; n < nCurSchemeVals; n++)
181 y_n = solvector->GetValue(curTimeLevels[n]);
182 t_n = solvector->GetValueTime(curTimeLevels[n]);
186 solvector_in->SetValue(curTimeLevels[n], y_n, t_n);
190 for (
size_t n = nCurSchemeVals; n < nCurSchemeVals + nCurSchemeImpDers;
194 dtFy_n = solvector->GetImplicitDerivative(curTimeLevels[n]);
198 solvector_in->SetImplicitDerivative(curTimeLevels[n], dtFy_n,
203 for (
size_t n = nCurSchemeVals + nCurSchemeImpDers; n < nCurSchemeSteps;
207 dtFy_n = solvector->GetExplicitDerivative(curTimeLevels[n]);
211 solvector_in->SetExplicitDerivative(curTimeLevels[n], dtFy_n,
220 this, nvar, npoints);
224 solvector_in->GetTimeVector(),
225 solvector_out->UpdateSolutionVector(),
226 solvector_out->UpdateTimeVector());
239 bool CalcNewImpDeriv =
false;
241 if (nMasterSchemeImpDers > 0)
243 if (nCurSchemeImpDers == 0 || (masterTimeLevels[nMasterSchemeVals] <
244 curTimeLevels[nCurSchemeVals]))
246 CalcNewImpDeriv =
true;
253 bool CalcNewExpDeriv =
false;
255 if (nMasterSchemeExpDers > 0)
257 if (nCurSchemeExpDers == 0 ||
258 (masterTimeLevels[nMasterSchemeVals + nMasterSchemeImpDers] <
259 curTimeLevels[nCurSchemeVals + nCurSchemeImpDers]))
261 CalcNewExpDeriv =
true;
267 size_t newImpDerivTimeLevel =
268 (masterTimeLevels.size() > nMasterSchemeVals)
269 ? masterTimeLevels[nMasterSchemeVals]
277 if (newImpDerivTimeLevel == 0 || newImpDerivTimeLevel == 1)
279 y_n = solvector->GetValue(newImpDerivTimeLevel);
280 t_n = solvector->GetValueTime(newImpDerivTimeLevel);
284 ASSERTL1(
false,
"Problems with initialising scheme");
287 for (
size_t j = 0; j < nvar; j++)
294 for (
size_t j = 0; j < nvar; j++)
302 size_t newExpDerivTimeLevel =
303 (masterTimeLevels.size() > nMasterSchemeVals + nMasterSchemeImpDers)
304 ? masterTimeLevels[nMasterSchemeVals + nMasterSchemeImpDers]
314 if (newExpDerivTimeLevel == 0)
316 y_n = solvector_out->GetValue(0);
317 t_n = solvector_out->GetValueTime(0);
321 else if (newExpDerivTimeLevel == 1)
323 y_n = solvector->GetValue(0);
324 t_n = solvector->GetValueTime(0);
328 ASSERTL1(
false,
"Problems with initialising scheme");
331 for (
size_t j = 0; j < nvar; j++)
337 if (newExpDerivTimeLevel == 1)
347 for (
size_t j = 0; j < nvar; j++)
349 Vmath::Smul(npoints, deltaT, f_expn[j], 1, f_expn[j], 1);
355 solvector->RotateSolutionVector();
361 y_n = solvector_out->GetValue(0);
362 t_n = solvector_out->GetValueTime(0);
365 if (newExpDerivTimeLevel == 1)
370 solvector->SetValue(0, y_n, t_n);
376 solvector->SetImplicitDerivative(newImpDerivTimeLevel, f_impn,
379 else if (nCurSchemeImpDers > 0 && nMasterSchemeImpDers > 0)
383 dtFy_n = solvector_out->GetImplicitDerivative(newImpDerivTimeLevel);
386 solvector->SetImplicitDerivative(newImpDerivTimeLevel, dtFy_n,
394 solvector->SetExplicitDerivative(newExpDerivTimeLevel, f_expn,
397 else if (nCurSchemeExpDers > 0 && nMasterSchemeExpDers > 0)
401 dtFy_n = solvector_out->GetExplicitDerivative(newExpDerivTimeLevel);
404 solvector->SetExplicitDerivative(newExpDerivTimeLevel, dtFy_n,
412 this, nvar, npoints);
415 solvector->GetTimeVector(),
416 solvector_new->UpdateSolutionVector(),
417 solvector_new->UpdateTimeVector());
419 solvector = solvector_new;
422 return solvector->GetSolution();
434 "Arguments not well defined");
443 for (
size_t j = 0; j <
m_nvars; j++)
465 for (
size_t j = 0; j <
m_nvars; j++)
479 for (
size_t j = 0; j <
m_nvars; j++)
491 for (
size_t j = 0; j <
m_nvars; j++)
503 for (
size_t j = 0; j <
m_nvars; j++)
531 for (
size_t stage = 0; stage <
m_numstages; stage++)
535 for (
size_t k = 0; k <
m_nvars; k++)
546 for (
size_t k = 0; k <
m_nvars; k++)
560 for (
size_t j = 1; j < stage; j++)
562 for (
size_t k = 0; k <
m_nvars; k++)
579 for (
size_t k = 0; k <
m_nvars; k++)
592 m_T = t_old[0] + deltaT;
597 for (
size_t j = 0; j <= stage; ++j)
599 m_T +=
A(stage, j) * deltaT;
614 for (
size_t k = 0; k <
m_nvars; ++k)
619 m_F[stage][k], 1,
m_F[stage][k], 1);
623 else if (type ==
eIMEX)
627 m_T = t_old[0] + deltaT;
632 for (
size_t j = 0; j <= stage; ++j)
634 m_T +=
A(stage, j) * deltaT;
642 for (
size_t k = 0; k <
m_nvars; k++)
647 m_F[stage][k], 1,
m_F[stage][k], 1);
662 for (
size_t j = 0; j < stage; ++j)
664 m_T +=
A(stage, j) * deltaT;
691 for (
size_t k = 0; k <
m_nvars; k++)
696 t_new[0] = t_old[0] + deltaT;
705 for (
size_t k = 0; k <
m_nvars; k++)
713 1, y_new[i][k], 1, y_new[i][k], 1);
719 t_new[i] =
B(i, 0) * deltaT;
724 for (
size_t k = 0; k <
m_nvars; k++)
727 y_new[i][k], 1, y_new[i][k], 1);
732 m_F_IMEX[j][k], 1, y_new[i][k], 1, y_new[i][k],
739 t_new[i] +=
B(i, j) * deltaT;
746 for (
size_t k = 0; k <
m_nvars; k++)
754 t_new[i] +=
V(i, j) * t_old[j];
775 for (
size_t m = 0; m <
m_A.size(); m++)
815 for (
size_t m = 0; m <
m_A.size(); m++)
845 size_t IMEXdim =
m_A.size();
846 size_t dim =
m_A[0].GetRows();
855 for (
size_t m = 0; m < IMEXdim; m++)
857 for (
size_t i = 0; i < dim; i++)
865 for (
size_t i = 0; i < dim; i++)
867 for (
size_t j = i + 1; j < dim; j++)
872 ASSERTL1(
false,
"Fully Implicit schemes cannnot be handled "
873 "by the TimeIntegrationScheme class");
882 "Coefficient Matrix B should have an "
883 "implicit and explicit part for IMEX schemes");
891 ASSERTL1(
false,
"This is not a proper IMEX scheme");
896 "Time integration scheme coefficients do not match its type");
905 boost::ignore_unused(y_old, t_old, y_new, t_new);
913 ASSERTL1(y_old[0].size() == y_new[0].size(),
914 "Non-matching number of variables.");
915 ASSERTL1(y_old[0][0].size() == y_new[0][0].size(),
916 "Non-matching number of coefficients.");
939 size_t osprecision = 6;
943 <<
"Time Integration Phase : " << rhs.
m_name <<
"\n"
944 <<
"- number of steps: " << r <<
"\n"
945 <<
"- number of stages: " << s <<
"\n"
946 <<
"General linear method tableau:\n";
948 for (
size_t i = 0; i < s; i++)
950 for (
size_t j = 0; j < s; j++)
953 os.precision(osprecision);
954 os << std::right << rhs.
A(i, j) <<
" ";
959 for (
size_t j = 0; j < s; j++)
962 os.precision(osprecision);
963 os << std::right << rhs.
A_IMEX(i, j) <<
" ";
969 for (
size_t j = 0; j < r; j++)
972 os.precision(osprecision);
973 os << std::right << rhs.
U(i, j);
978 size_t imexflag = (type ==
eIMEX) ? 2 : 1;
980 i < (r + imexflag * s) * (oswidth + 1) + imexflag * 2 - 1; i++)
986 for (
size_t i = 0; i < r; i++)
988 for (
size_t j = 0; j < s; j++)
991 os.precision(osprecision);
992 os << std::right << rhs.
B(i, j) <<
" ";
997 for (
size_t j = 0; j < s; j++)
1000 os.precision(osprecision);
1001 os << std::right << rhs.
B_IMEX(i, j) <<
" ";
1007 for (
size_t j = 0; j < r; j++)
1010 os.precision(osprecision);
1011 os << std::right << rhs.
V(i, j);
1017 os.precision(osprecision);
1022 os << std::right <<
" value";
1026 os << std::right <<
" derivative";
1034 for (
size_t k = 0; k < rhs.
m_nvars; k++)
1037 <<
"General linear method exponential tableau for variable " << k
1040 for (
size_t i = 0; i < s; i++)
1042 for (
size_t j = 0; j < s; j++)
1045 os.precision(osprecision);
1046 os << std::right << rhs.
A(k, i, j) <<
" ";
1051 for (
size_t j = 0; j < r; j++)
1054 os.precision(osprecision);
1055 os << std::right << rhs.
B(k, i, j);
1060 size_t imexflag = (type ==
eIMEX) ? 2 : 1;
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
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.