41#ifndef NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_EULER_EXP_TIME_INTEGRATION_SCHEME
42#define NEKTAR_LIB_UTILITIES_TIME_INTEGRATION_EULER_EXP_TIME_INTEGRATION_SCHEME
44#define LUE LIB_UTILITIES_EXPORT
48#include <NekMesh/Module/ProcessModules/ProcessVarOpti/Evaluator.hxx>
53using namespace NekMesh;
65 std::vector<NekDouble> freeParams)
70 ASSERTL1(variant ==
"Lawson" || variant ==
"Norsett",
71 "EulerExponential Time integration scheme unknown variant: " +
72 variant +
". Must be 'Lawson' or 'Norsett'.");
74 ASSERTL1(((variant ==
"Lawson" && 1 <= order && order <= 1) ||
75 (variant ==
"Norsett" && 1 <= order && order <= 4)),
76 "EulerExponential Time integration scheme bad order, "
77 "Lawson (1) or Norsett (1-4): " +
78 std::to_string(order));
84 for (
size_t n = 0; n < order; ++n)
99 std::string variant,
size_t order, std::vector<NekDouble> freeParams)
111 std::string variant,
size_t order)
114 phase->m_variant = variant;
115 phase->m_order = order;
116 phase->m_name = variant + std::string(
"EulerExponentialOrder") +
117 std::to_string(phase->m_order);
120 phase->m_numstages = 1;
121 phase->m_numsteps = phase->m_order;
139 phase->m_B[0][0][0] = 1.0 / phase->m_order;
142 if (phase->m_order > 1)
144 phase->m_B[0][1][0] = 1.0;
148 phase->m_U[0][0] = 1.0;
151 phase->m_V[0][0] = 1.0;
154 for (
size_t n = 1; n < phase->m_order; ++n)
156 phase->m_V[0][n] = 1.0 / phase->m_order;
160 for (
size_t n = 2; n < phase->m_order; ++n)
162 phase->m_V[n][n - 1] = 1.0;
165 phase->m_numMultiStepValues = 1;
166 phase->m_numMultiStepImplicitDerivs = 0;
167 phase->m_numMultiStepExplicitDerivs = phase->m_order - 1;
169 phase->m_timeLevelOffset[0] = 0;
172 for (
size_t n = 1; n < phase->m_order; ++n)
174 phase->m_timeLevelOffset[n] = n;
177 phase->CheckAndVerify();
181 Array<
OneD, std::complex<NekDouble>> &Lambda)
210 return std::string(
"EulerExponential");
236 "The number of variables does not match "
237 "the number of exponential coefficents.");
246 for (
size_t k = 0; k < phase->
m_nvars; ++k)
259 ASSERTL1(
false,
"Cannot call EulerExponential directly "
260 "use the variant 'Lawson' or 'Norsett'.");
292 phi_func[0] = phi[0];
294 for (
size_t m = 1; m < phase->
m_order; ++m)
303 for (
size_t j = 0; j < phase->
m_order; ++j)
305 for (
size_t i = 0; i < phase->
m_order; ++i)
307 W[j][i] = std::pow(i, j);
314 for (
size_t m = 0; m < phase->
m_order; ++m)
317 for (
size_t j = 0; j < phase->
m_order; ++j)
319 for (
size_t i = 0; i < phase->
m_order; ++i)
324 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
329 phi[m] = Determinant<3>(W) / W_det;
337 phi_func[0] = phi[0];
339 for (
size_t m = 1; m < phase->
m_order; ++m)
348 for (
size_t j = 0; j < phase->
m_order; ++j)
350 for (
size_t i = 0; i < phase->
m_order; ++i)
352 W[j][i] = std::pow(i, j);
359 for (
size_t m = 0; m < phase->
m_order; ++m)
362 for (
size_t j = 0; j < phase->
m_order; ++j)
364 for (
size_t i = 0; i < phase->
m_order; ++i)
369 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
374 phi[m] = Determinant<4>(W) / W_det;
379 ASSERTL1(
false,
"Not set up for more than 4th Order.");
395 phase->
m_B_phi[k][0][0] = phi[0];
411 for (
size_t n = 1; n < phase->
m_order; ++n)
413 phase->
m_V_phi[k][0][n] = phi[n];
417 for (
size_t n = 2; n < phase->
m_order; ++n)
419 phase->
m_V_phi[k][n][n - 1] = 1.0;
427 return (n == 1 || n == 0) ? 1 : n *
factorial(n - 1);
431 const std::complex<NekDouble>
z)
const
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
static std::string className
LUE NekDouble v_GetTimeStability() const override
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, std::string variant, size_t order)
std::complex< NekDouble > phi_function(const size_t order, const std::complex< NekDouble > z) const
LUE void SetExponentialCoefficients(Array< OneD, std::complex< NekDouble > > &Lambda)
LUE std::string v_GetName() const override
~EulerExponentialTimeIntegrationScheme() override
void v_InitializeSecondaryData(TimeIntegrationAlgorithmGLM *phase, NekDouble deltaT) const override
NekDouble factorial(size_t n) const
EulerExponentialTimeIntegrationScheme(std::string variant, size_t order, std::vector< NekDouble > freeParams)
LUE std::string v_GetFullName() const override
static TimeIntegrationSchemeSharedPtr create(std::string variant, size_t order, std::vector< NekDouble > freeParams)
Array< OneD, std::complex< NekDouble > > m_L
Array< OneD, Array< TwoD, NekDouble > > m_A_phi
size_t m_nvars
Last number of vars.
Array< OneD, Array< TwoD, NekDouble > > m_B_phi
Array< OneD, Array< TwoD, NekDouble > > m_V_phi
Array< OneD, Array< TwoD, NekDouble > > m_U_phi
Base class for GLM time integration schemes.
TimeIntegrationAlgorithmGLMVector m_integration_phases
LUE size_t GetOrder() const
LUE std::string GetVariant() const
LUE std::string GetName() const
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< TimeIntegrationAlgorithmGLM > TimeIntegrationAlgorithmGLMSharedPtr
@ eExponential
Exponential scheme.
std::vector< TimeIntegrationAlgorithmGLMSharedPtr > TimeIntegrationAlgorithmGLMVector
std::shared_ptr< TimeIntegrationScheme > TimeIntegrationSchemeSharedPtr
std::vector< double > z(NPUPPER)