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)
97 std::string variant,
size_t order, std::vector<NekDouble> freeParams)
109 std::string variant,
size_t order)
112 phase->m_variant = variant;
113 phase->m_order = order;
114 phase->m_name = variant + std::string(
"EulerExponentialOrder") +
115 std::to_string(phase->m_order);
118 phase->m_numstages = 1;
119 phase->m_numsteps = phase->m_order;
137 phase->m_B[0][0][0] = 1.0 / phase->m_order;
140 if (phase->m_order > 1)
142 phase->m_B[0][1][0] = 1.0;
146 phase->m_U[0][0] = 1.0;
149 phase->m_V[0][0] = 1.0;
152 for (
size_t n = 1; n < phase->m_order; ++n)
154 phase->m_V[0][n] = 1.0 / phase->m_order;
158 for (
size_t n = 2; n < phase->m_order; ++n)
160 phase->m_V[n][n - 1] = 1.0;
163 phase->m_numMultiStepValues = 1;
164 phase->m_numMultiStepImplicitDerivs = 0;
165 phase->m_numMultiStepExplicitDerivs = phase->m_order - 1;
167 phase->m_timeLevelOffset[0] = 0;
170 for (
size_t n = 1; n < phase->m_order; ++n)
172 phase->m_timeLevelOffset[n] = n;
175 phase->CheckAndVerify();
179 Array<
OneD, std::complex<NekDouble>> &Lambda)
208 return std::string(
"EulerExponential");
234 "The number of variables does not match "
235 "the number of exponential coefficents.");
244 for (
size_t k = 0; k < phase->
m_nvars; ++k)
257 ASSERTL1(
false,
"Cannot call EulerExponential directly "
258 "use the variant 'Lawson' or 'Norsett'.");
290 phi_func[0] = phi[0];
292 for (
size_t m = 1; m < phase->
m_order; ++m)
301 for (
size_t j = 0; j < phase->
m_order; ++j)
303 for (
size_t i = 0; i < phase->
m_order; ++i)
305 W[j][i] = std::pow(i, j);
312 for (
size_t m = 0; m < phase->
m_order; ++m)
315 for (
size_t j = 0; j < phase->
m_order; ++j)
317 for (
size_t i = 0; i < phase->
m_order; ++i)
322 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
327 phi[m] = Determinant<3>(W) / W_det;
335 phi_func[0] = phi[0];
337 for (
size_t m = 1; m < phase->
m_order; ++m)
346 for (
size_t j = 0; j < phase->
m_order; ++j)
348 for (
size_t i = 0; i < phase->
m_order; ++i)
350 W[j][i] = std::pow(i, j);
357 for (
size_t m = 0; m < phase->
m_order; ++m)
360 for (
size_t j = 0; j < phase->
m_order; ++j)
362 for (
size_t i = 0; i < phase->
m_order; ++i)
367 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
372 phi[m] = Determinant<4>(W) / W_det;
377 ASSERTL1(
false,
"Not set up for more than 4th Order.");
393 phase->
m_B_phi[k][0][0] = phi[0];
409 for (
size_t n = 1; n < phase->
m_order; ++n)
411 phase->
m_V_phi[k][0][n] = phi[n];
415 for (
size_t n = 2; n < phase->
m_order; ++n)
417 phase->
m_V_phi[k][n][n - 1] = 1.0;
425 return (n == 1 || n == 0) ? 1 : n *
factorial(n - 1);
429 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
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
~EulerExponentialTimeIntegrationScheme() override=default
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