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
49 #include <NekMesh/Module/ProcessModules/ProcessVarOpti/Evaluator.hxx>
54 using namespace NekMesh;
56 namespace LibUtilities
67 std::vector<NekDouble> freeParams)
73 ASSERTL1(variant ==
"Lawson" || variant ==
"Norsett",
74 "EulerExponential Time integration scheme unknown variant: " +
75 variant +
". Must be 'Lawson' or 'Norsett'.");
77 ASSERTL1(((variant ==
"Lawson" && 1 <= order && order <= 1) ||
78 (variant ==
"Norsett" && 1 <= order && order <= 4)),
79 "EulerExponential Time integration scheme bad order, "
80 "Lawson (1) or Norsett (1-4): " +
81 std::to_string(order));
87 for (
unsigned int n = 0; n < order; ++n)
93 m_integration_phases[n], variant, n + 1);
102 std::string variant,
unsigned int order,
103 std::vector<NekDouble> freeParams)
115 std::string variant,
int order)
118 phase->m_variant = variant;
119 phase->m_order = order;
120 phase->m_name = variant + std::string(
"EulerExponentialOrder") +
121 std::to_string(phase->m_order);
124 phase->m_numstages = 1;
125 phase->m_numsteps = phase->m_order;
146 phase->m_B[0][0][0] = 1.0 / phase->m_order;
149 if (phase->m_order > 1)
151 phase->m_B[0][1][0] = 1.0;
155 phase->m_U[0][0] = 1.0;
158 phase->m_V[0][0] = 1.0;
161 for (
int n = 1; n < phase->m_order; ++n)
163 phase->m_V[0][n] = 1.0 / phase->m_order;
167 for (
int n = 2; n < phase->m_order; ++n)
169 phase->m_V[n][n - 1] = 1.0;
172 phase->m_numMultiStepValues = 1;
173 phase->m_numMultiStepImplicitDerivs = 0;
174 phase->m_numMultiStepDerivs = phase->m_order - 1;
176 phase->m_timeLevelOffset[0] = 0;
179 for (
int n = 1; n < phase->m_order; ++n)
181 phase->m_timeLevelOffset[n] = n;
184 phase->CheckAndVerify();
188 Array<
OneD, std::complex<NekDouble>> &Lambda)
190 ASSERTL0(!m_integration_phases.empty(),
"No scheme")
202 for (
int i = 0; i < m_integration_phases.size(); i++)
204 m_integration_phases[i]->m_L = Lambda;
210 m_integration_phases[i]->m_lastNVars = 0;
217 return std::string(
"EulerExponential");
222 return GetVariant() + GetName() +
"Order" + std::to_string(GetOrder());
243 "The number of variables does not match "
244 "the number of exponential coefficents.");
253 for (
unsigned int k = 0; k < phase->
m_nvars; ++k)
258 phi[0] = phi_function(0, deltaT * phase->
m_L[k]).real();
262 phi[0] = phi_function(1, deltaT * phase->
m_L[k]).real();
266 ASSERTL1(
false,
"Cannot call EulerExponential directly "
267 "use the variant 'Lawson' or 'Norsett'.");
290 phi[1] = phi_function(2, deltaT * phase->
m_L[k]).real();
299 phi_func[0] = phi[0];
301 for (
unsigned int m = 1; m < phase->
m_order; ++m)
304 phi_function(m + 1, deltaT * phase->
m_L[k]).real();
310 for (
unsigned int j = 0; j < phase->
m_order; ++j)
312 for (
unsigned int i = 0; i < phase->
m_order; ++i)
314 W[j][i] = std::pow(i, j);
321 for (
unsigned int m = 0; m < phase->
m_order; ++m)
324 for (
unsigned int j = 0; j < phase->
m_order; ++j)
326 for (
unsigned int i = 0; i < phase->
m_order; ++i)
331 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
336 phi[m] = Determinant<3>(W) / W_det;
344 phi_func[0] = phi[0];
346 for (
unsigned int m = 1; m < phase->
m_order; ++m)
349 phi_function(m + 1, deltaT * phase->
m_L[k]).real();
355 for (
unsigned int j = 0; j < phase->
m_order; ++j)
357 for (
unsigned int i = 0; i < phase->
m_order; ++i)
359 W[j][i] = std::pow(i, j);
366 for (
unsigned int m = 0; m < phase->
m_order; ++m)
369 for (
unsigned int j = 0; j < phase->
m_order; ++j)
371 for (
unsigned int i = 0; i < phase->
m_order; ++i)
376 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
381 phi[m] = Determinant<4>(W) / W_det;
386 ASSERTL1(
false,
"Not set up for more than 4th Order.");
402 phase->
m_B_phi[k][0][0] = phi[0];
413 phi_function(0, deltaT * phase->
m_L[k]).real();
416 for (
int n = 1; n < phase->
m_order; ++n)
418 phase->
m_V_phi[k][0][n] = phi[n];
422 for (
int n = 2; n < phase->
m_order; ++n)
424 phase->
m_V_phi[k][n][n - 1] = 1.0;
432 return (n == 1 || n == 0) ? 1 : n * factorial(n - 1);
436 const std::complex<NekDouble> z)
const
454 return 1.0 / factorial(order);
463 return (phi_function(order - 1, z) - 1.0 / factorial(order - 1)) /
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
virtual LUE std::string v_GetName() const override
static std::string className
virtual ~EulerExponentialTimeIntegrationScheme()
virtual LUE NekDouble v_GetTimeStability() const override
virtual void v_InitializeSecondaryData(TimeIntegrationAlgorithmGLM *phase, NekDouble deltaT) const override
static TimeIntegrationSchemeSharedPtr create(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
EulerExponentialTimeIntegrationScheme(std::string variant, unsigned int order, std::vector< NekDouble > freeParams)
NekDouble factorial(unsigned int n) const
std::complex< NekDouble > phi_function(const unsigned int order, const std::complex< NekDouble > z) const
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, std::string variant, int order)
virtual LUE std::string v_GetFullName() const override
LUE void SetExponentialCoefficients(Array< OneD, std::complex< NekDouble >> &Lambda)
Array< OneD, std::complex< NekDouble > > m_L
Array< OneD, Array< TwoD, NekDouble > > m_A_phi
Array< OneD, Array< TwoD, NekDouble > > m_B_phi
Array< OneD, Array< TwoD, NekDouble > > m_V_phi
int m_nvars
Last number of vars.
Array< OneD, Array< TwoD, NekDouble > > m_U_phi
Base class for GLM time integration schemes.
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
The above copyright notice and this permission notice shall be included.