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)
116 return std::string(
"EulerExponential");
121 return GetVariant() + GetName() +
"Order" + std::to_string(GetOrder());
130 std::string variant,
int order)
133 phase->m_variant = variant;
134 phase->m_order = order;
135 phase->m_name = variant + std::string(
"EulerExponentialOrder") +
136 std::to_string(phase->m_order);
139 phase->m_numstages = 1;
140 phase->m_numsteps = phase->m_order;
161 phase->m_B[0][0][0] = 1.0 / phase->m_order;
164 if (phase->m_order > 1)
166 phase->m_B[0][1][0] = 1.0;
170 phase->m_U[0][0] = 1.0;
173 phase->m_V[0][0] = 1.0;
176 for (
int n = 1; n < phase->m_order; ++n)
178 phase->m_V[0][n] = 1.0 / phase->m_order;
182 for (
int n = 2; n < phase->m_order; ++n)
184 phase->m_V[n][n - 1] = 1.0;
187 phase->m_numMultiStepValues = 1;
188 phase->m_numMultiStepDerivs = phase->m_order - 1;
190 phase->m_timeLevelOffset[0] = 0;
193 for (
int n = 1; n < phase->m_order; ++n)
195 phase->m_timeLevelOffset[n] = n;
198 phase->CheckAndVerify();
214 "The number of variables does not match "
215 "the number of exponential coefficents.");
224 for (
unsigned int k = 0; k < phase->
m_nvars; ++k)
229 phi[0] = phi_function(0, deltaT * phase->
m_L[k]).real();
233 phi[0] = phi_function(1, deltaT * phase->
m_L[k]).real();
237 ASSERTL1(
false,
"Cannot call EulerExponential directly "
238 "use the variant 'Lawson' or 'Norsett'.");
261 phi[1] = phi_function(2, deltaT * phase->
m_L[k]).real();
270 phi_func[0] = phi[0];
272 for (
unsigned int m = 1; m < phase->
m_order; ++m)
275 phi_function(m + 1, deltaT * phase->
m_L[k]).real();
281 for (
unsigned int j = 0; j < phase->
m_order; ++j)
283 for (
unsigned int i = 0; i < phase->
m_order; ++i)
285 W[j][i] = std::pow(i, j);
292 for (
unsigned int m = 0; m < phase->
m_order; ++m)
295 for (
unsigned int j = 0; j < phase->
m_order; ++j)
297 for (
unsigned int i = 0; i < phase->
m_order; ++i)
302 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
307 phi[m] = Determinant<3>(W) / W_det;
315 phi_func[0] = phi[0];
317 for (
unsigned int m = 1; m < phase->
m_order; ++m)
320 phi_function(m + 1, deltaT * phase->
m_L[k]).real();
326 for (
unsigned int j = 0; j < phase->
m_order; ++j)
328 for (
unsigned int i = 0; i < phase->
m_order; ++i)
330 W[j][i] = std::pow(i, j);
337 for (
unsigned int m = 0; m < phase->
m_order; ++m)
340 for (
unsigned int j = 0; j < phase->
m_order; ++j)
342 for (
unsigned int i = 0; i < phase->
m_order; ++i)
347 W[i][j] = (j == m) ? phi_func[i] : std::pow(j, i);
352 phi[m] = Determinant<4>(W) / W_det;
357 ASSERTL1(
false,
"Not set up for more than 4th Order.");
373 phase->
m_B_phi[k][0][0] = phi[0];
384 phi_function(0, deltaT * phase->
m_L[k]).real();
387 for (
int n = 1; n < phase->
m_order; ++n)
389 phase->
m_V_phi[k][0][n] = phi[n];
393 for (
int n = 2; n < phase->
m_order; ++n)
395 phase->
m_V_phi[k][n][n - 1] = 1.0;
401 Array<
OneD, std::complex<NekDouble>> &Lambda)
403 ASSERTL0(!m_integration_phases.empty(),
"No scheme")
415 for (
int i = 0; i < m_integration_phases.size(); i++)
417 m_integration_phases[i]->m_L = Lambda;
423 m_integration_phases[i]->m_lastNVars = 0;
430 return (n == 1 || n == 0) ? 1 : n * factorial(n - 1);
434 const std::complex<NekDouble> z)
const
452 return 1.0 / factorial(order);
461 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....
static std::string className
virtual ~EulerExponentialTimeIntegrationScheme()
virtual LUE NekDouble GetTimeStability() const
virtual void InitializeSecondaryData(TimeIntegrationAlgorithmGLM *phase, NekDouble deltaT) const
virtual LUE std::string GetFullName() const
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
virtual LUE std::string GetName() const
static LUE void SetupSchemeData(TimeIntegrationAlgorithmGLMSharedPtr &phase, std::string variant, int order)
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.