9 template <
class TDATA,
class TDTAU>
13 using Frhs = std::function<void(TDATA &, TDATA &, TDTAU &,
int,
real,
int)>;
14 using Fdt = std::function<void(TDATA &, TDTAU &,
real,
int)>;
16 using Fsolve = std::function<void(TDATA &, TDATA &, TDATA &, TDTAU &,
real,
real, TDATA &,
int,
real,
int)>;
17 using Fstop = std::function<bool(
int, TDATA &,
int)>;
32 for (
auto &[k,
v] : j.items())
37 template <
class TDATA,
class TDTAU>
60 template <
class Finit,
class FinitDtau>
62 index NDOF, Finit &&finit = [](TDATA &) {}, FinitDtau &&finitDtau = [](TDTAU &) {}) :
DOF(NDOF)
85 for (
int iter = 1; iter <= maxIter; iter++)
93 rhs.addTo(
x, -1. / dt);
97 fincrement(
x, xinc, 1.0, 0);
99 if (fstop(iter,
rhs, 1))
122 template <
class TDATA,
class TDTAU>
126 Eigen::Matrix<
real, -1, -1> butcherA;
127 Eigen::Vector<
real, -1> butcherC;
128 Eigen::RowVector<
real, -1> butcherB;
131 bool explicitFirst =
false;
132 int hasLastEndPointR = 0;
155 template <
class Finit,
class FinitDtau>
157 index NDOF, Finit &&finit = [](TDATA &) {}, FinitDtau &&finitDtau = [](TDTAU &) {},
int schemeCode = 0) :
DOF(NDOF)
160 schemeC = schemeCode;
164#define _zeta 0.128886400515
166 butcherA.resize(nInnerStage, nInnerStage);
167 butcherC.resize(nInnerStage);
168 butcherB.resize(nInnerStage);
170 butcherA <<
_zeta, 0, 0,
174 butcherB << 1. / (6 *
sqr(2 *
_zeta - 1)),
179 else if (schemeCode == 1)
182 explicitFirst =
true;
183 butcherA.resize(nInnerStage, nInnerStage);
184 butcherC.resize(nInnerStage);
185 butcherB.resize(nInnerStage);
188 0.25, 0.25, 0, 0, 0, 0,
189 0.137776, -0.055776, 0.25, 0, 0, 0,
190 0.1446368660269822, -0.2239319076133447, 0.4492950415863626, 0.25, 0, 0,
191 0.09825878328356477, -0.5915442428196704, 0.8101210205756877, 0.283164405707806, 0.25, 0,
192 0.1579162951616714, 0, 0.1867589405240008, 0.6805652953093346, -0.2752405309950067, 0.25;
193 butcherB = butcherA(EigenLast, EigenAll);
194 butcherC << 0, 0.5, 0.332, 0.62, 0.849999966747388, 1;
196 else if (schemeCode == 2)
199 explicitFirst =
true;
201 butcherA.resize(nInnerStage, nInnerStage);
202 butcherC.resize(nInnerStage);
203 butcherB.resize(nInnerStage);
204 double alphaC = double(1767732205903) / double(4055673282236);
207 alphaC, alphaC, 0, 0,
208 real(2746238789719) /
real(10658868560708),
real(-640167445237) /
real(6845629431997), alphaC, 0,
209 real(1471266399579) /
real(7840856788654),
real(-4482444167858) /
real(7529755066697),
real(11266239266428) /
real(11593286722821), alphaC;
211 butcherB = butcherA(EigenLast, EigenAll);
212 butcherC = butcherA.rowwise().sum();
216 else if (schemeCode == 3)
219 explicitFirst =
true;
220 butcherA.resize(nInnerStage, nInnerStage);
221 butcherC.resize(nInnerStage);
222 butcherB.resize(nInnerStage);
225 butcherB = butcherA(EigenLast, EigenAll);
228 else if (schemeCode == 4)
231 explicitFirst =
true;
232 butcherA.resize(nInnerStage, nInnerStage);
233 butcherC.resize(nInnerStage);
234 butcherB.resize(nInnerStage);
236 real gamma = 1. - std::sqrt(2.0) * 0.5;
237 real b2 = (1. - 2 * gamma) / (4 * gamma);
238 double alphaC = double(1767732205903) / double(4055673282236);
242 1 - b2 - gamma, b2, gamma;
244 butcherB = butcherA(EigenLast, EigenAll);
245 butcherC = butcherA.rowwise().sum();
254 rhsbuf.resize(nInnerStage);
275 for (
int iB = 0; iB < nInnerStage; iB++)
280 for (; iter <= maxIter; iter++)
282 if (explicitFirst && iB == 0)
284 if (hasLastEndPointR)
287 frhs(
rhsbuf[0],
x,
dTau, INT_MAX, butcherC(0), 0), latestStage = 0;
290 fdt(
x,
dTau, butcherA(iB, iB), 0);
292 frhs(
rhsbuf[iB],
x,
dTau, iter, butcherC(iB), 0), latestStage = iB;
307 for (
int jB = 0; jB < iB; jB++)
310 rhs.addTo(
x, -1. / dt);
313 fsolve(
x,
rhs,
resOther,
dTau, dt, butcherA(iB, iB), xinc, iter, butcherC(iB), 0);
315 fincrement(
x, xinc, 1.0, 0);
320 if (fstop(iter,
rhs, iB + 1))
322 if (explicitFirst && iB == 0)
328 fstop(iter,
rhs, iB + 1);
332 hasLastEndPointR = 1;
338 for (
int jB = 0; jB < nInnerStage; jB++)
339 x.addTo(
rhsbuf[jB], butcherB(jB) * dt);
344 return rhsbuf[latestStage];
362 template <
class TDATA,
class TDTAU>
366 static const Eigen::Matrix<real, 4, 5> BDFCoefs;
395 template <
class Finit,
class FinitDtau>
397 index NDOF, Finit &&finit = [](TDATA &) {}, FinitDtau &&finitDtau = [](TDTAU &) {},
400 assert(k > 0 && k <= 4);
435 for (; iter <= maxIter; iter++)
437 fdt(
x,
dTau, BDFCoefs(kCurrent - 1, 0), 0);
440 rhs.setConstant(0.0);
441 rhs.addTo(
xLast, BDFCoefs(kCurrent - 1, 1) / dt);
450 rhs.addTo(
x, -1. / dt);
451 rhs.addTo(
rhsbuf[0], BDFCoefs(kCurrent - 1, 0));
452 fsolve(
x,
rhs,
resOther,
dTau, dt, BDFCoefs(kCurrent - 1, 0), xinc, iter, 1.0, 0);
459 fincrement(
x, xinc, 1.0, 0);
464 if (fstop(iter,
rhs, 1))
484 const std::function<
void()> &,
507 for (; iter <= maxIter; iter++)
509 fdt(
x,
dTau, BDFCoefs(kCurrent - 1, 0), 0);
518 resInc.addTo(
xLast, (BDFCoefs(kCurrent - 1, 1) - 1) / dt);
526 falphaLimSource(
resInc, 0);
533 rhs.setConstant(0.0);
535 rhs.addTo(
xLast, (BDFCoefs(kCurrent - 1, 1) - 1) / dt);
543 falphaLimSource(
rhs, 0);
546 rhs.addTo(
x, -1. / dt);
547 rhs.addTo(
rhs, BDFCoefs(kCurrent - 1, 0));
548 fsolve(
x,
rhs,
resOther,
dTau, dt, BDFCoefs(kCurrent - 1, 0), xinc, iter, 1.0, 0);
555 fincrement(
x, xinc, 1.0, 0);
560 if (fstop(iter,
rhs, 1))
593 template <
class TDATA,
class TDTAU>
595 {1. / 1., 1. / 1., std::nan(
"1"), std::nan(
"1"), std::nan(
"1")},
596 {2. / 3., 4. / 3., -1. / 3., std::nan(
"1"), std::nan(
"1")},
597 {6. / 11., 18. / 11., -9. / 11., 2. / 11., std::nan(
"1")},
598 {12. / 25., 48. / 25., -36. / 25., 16. / 25., -3. / 25.}};
600 template <
class TDATA,
class TDTAU>
631 Eigen::Vector<real, Eigen::Dynamic> BDFCoefs;
638 template <
class Finit,
class FinitDtau>
640 index NDOF, Finit &&finit = [](TDATA &) {}, FinitDtau &&finitDtau = [](TDTAU &) {},
643 assert(k > 0 && k <= 4);
667 BDFCoefs.resize(kCurrent + 1);
672 BDFCoefs(0) = BDFCoefs(1) = 1;
678 BDFCoefs(0) = 1 / (1 + phi);
679 BDFCoefs(1) = 1 + Rt * phi / (1 + phi);
680 BDFCoefs(2) = -Rt * phi / (1 + phi);
705 for (; iter <= maxIter; iter++)
707 fdt(
x,
dTau, BDFCoefs(0), 0);
711 rhs.setConstant(0.0);
721 rhs.addTo(
x, -1. / dt);
730 fincrement(
x, xinc, 1.0, 0);
735 if (fstop(iter,
rhs, 1))
755 const std::function<
void()> &,
781 xLast *= -BDFCoefs(2);
782 real limitingV = flimitDtBDF(xIn,
xLast);
788 auto fB = [=](
real dt)
791 real phi = dt / (dt + dtm1);
792 return Rt * phi / (1 + phi);
794 real targetB = limitingV * -BDFCoefs(2);
796 if (targetB >= fB(dtm1 * maxIncrease))
797 dtNew = dtm1 * maxIncrease;
801 dtOut = std::min(dtNew, dtOut);
822 for (; iter <= maxIter; iter++)
824 fdt(
x,
dTau, BDFCoefs(0), 0);
828 xBase.setConstant(0.0);
862 rhs.addTo(
x, -1. / dt);
872 fincrement(
x, xinc, 1.0, 0);
877 if (fstop(iter,
rhs, 1))
916 template <
class TDATA,
class TDTAU>
919 int hasLastEndPointR = 0;
929 TDATA &, TDATA &, TDATA &,
930 TDTAU &,
const std::vector<real> &,
965 template <
class Finit,
class FinitDtau>
967 index NDOF, Finit &&finit = [](TDATA &) {}, FinitDtau &&finitDtau = [](TDTAU &) {},
968 real alpha = 0.55,
int nCurSolveMethod = 0,
int nnStartIter = 0,
969 real thetaM1n = 0.9146,
real thetaM2n = 0.0,
int mask = 0,
999 DNDS_assert_info(mask == 0 || mask == 1 || mask == 2,
"mask not supported");
1005 for (
auto &[k,
v] : j.items())
1012 else if (k ==
"thetaMMG")
1017 else if (k ==
"coefIncMidMG")
1056 if (
prevSize == 1 && (hR1 < 1e2 && hR1 > 1e-2))
1059 cInter[2] = -(
alpha * pow(
alpha - 1.0, 2.0) * 1.0 / pow(hR1 + 1.0, 2.0)) / hR1;
1082 wInteg[2] = 1.0 / (
alpha * 6.0 - 6.0) + 1.0 / 2.0;
1099 if (hasLastEndPointR)
1119 for (; iter <= maxIter; iter++)
1124 fdt(
x,
dTau, 1.0, 0);
1155 fincrement(
xMid, xinc, 1.0, 1);
1162 theta2Scale = 1. / theta2Scale;
1163 bool theta2LimitSitu =
thetaM2 < -1e5;
1164 real xLastCoef = !theta2LimitSitu
1167 real xMidCoef = !theta2LimitSitu
1168 ? (-theta2Scale *
thetaM2 * 1. / dt)
1169 : (1 /
cInter(1) * 1. / dt);
1170 real xPrevCoef = !theta2LimitSitu
1174 if (theta2LimitSitu)
1175 rLastCoef = -1. /
cInter(1) * (stepIsRealU3R1 ? 0.0 :
cInter(2));
1176 real rMidCoef = theta2LimitSitu ? 0.0 : theta2Scale *
wInteg(1);
1205 fincrement(
x, xinc, 1.0, 0);
1206 fdt(
x,
dTau, 1.0, 0);
1246 real mgTrapzAlpha = 1.0;
1247 for (
int iMG = 1; iMG <=
nMG; iMG++)
1252 if (iMG == 1 and
nMG > 1)
1265 fincrement(
xMG, xinc, 1.0, 2);
1268 xinc.addTo(
xMG0, -1.0);
1269 fincrement(
x, xinc, 1.0, 0);
1275 fdt(
x,
dTau, 1.0, 0);
1294 hasLastEndPointR = 1;
1309 for (; iter <= maxIter; iter++)
1314 fdt(
x,
dTau, 1.0, 0);
1325 fdt(
x,
dTau, 1.0, 0);
1328 xMid.setConstant(0.0);
1377 dt, 1.0, xinc, iter, 0);
1396 fincrement(
x, xinc, 1.0, 0);
1401 if (fstop(iter, xinc, 1))
1406 fstop(iter, xinc, 1);
1437 template <
class TDATA,
class TDTAU>
1456 template <
class Finit,
class FinitDtau>
1458 index NDOF, Finit &&finit = [](TDATA &) {}, FinitDtau &&finitDtau = [](TDTAU &) {},
1459 bool nLocalDtStepping =
false)
1481 fdt(
x,
dTau, 1.0, 0);
1494 fincrement(
x,
rhs, 1.0, 0);
1505 fincrement(
x,
rhs, 0.25, 0);
1516 fincrement(
x,
rhs, 2. / 3., 0);
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
#define DNDS_assert_info(expr, info)
Debug-only assertion with an extra std::string info message.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
MPI wrappers: MPIInfo, collective operations, type mapping, CommStrategy.
std::vector< TDATA > rhsbuf
virtual TDATA & getLatestRHS() override
ExplicitSSPRK3TimeStepAsImplicitDualTimeStep(index NDOF, Finit &&finit=[](TDATA &) {}, FinitDtau &&finitDtau=[](TDTAU &) {}, bool nLocalDtStepping=false)
typename tBase::Frhs Frhs
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt) override
fsolve, maxIter, fstop are omitted here
TDATA & getRES(int i) override
typename tBase::Fsolve Fsolve
typename tBase::Fincrement Fincrement
typename tBase::Fstop Fstop
TDATA & getRHS(int i) override
virtual TDATA & getLatestRHS() override
ImplicitBDFDualTimeStep(index NDOF, Finit &&finit=[](TDATA &) {}, FinitDtau &&finitDtau=[](TDTAU &) {}, index k=2)
mind that NDOF is the dof of dt finit(TDATA& data)
typename tBase::Fsolve Fsolve
void StepPP(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt, const FalphaLimSource &falphaLimSource, const FresidualIncPP &fresidualIncPP)
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt) override
frhs(TDATA &rhs, TDATA &x) fdt(TDTAU& dTau) fsolve(TDATA &x, TDATA &rhs, TDTAU& dTau,...
std::function< void(TDATA &, TDATA &, TDATA &, TDATA &, const std::function< void()> &, real, int)> FresidualIncPP
typename tBase::Frhs Frhs
typename tBase::Fincrement Fincrement
TDATA & getRES(int i) override
std::vector< TDATA > xPrevs
std::function< void(TDATA &, int)> FalphaLimSource
typename tBase::Fstop Fstop
virtual ~ImplicitBDFDualTimeStep()=default
std::vector< TDATA > rhsbuf
TDATA & getRHS(int i) override
std::function< void(TDATA &, TDATA &, TDTAU &, int, real, int)> Frhs
virtual TDATA & getLatestRHS()=0
virtual ~ImplicitDualTimeStep()=default
std::function< void(TDATA &, TDATA &, TDATA &, TDTAU &, real, real, TDATA &, int, real, int)> Fsolve
virtual TDATA & getRHS(int i)=0
virtual void SetExtraParams(const nlohmann::ordered_json &j)
std::function< void(TDATA &, TDTAU &, real, int)> Fdt
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt)=0
virtual TDATA & getRES(int i)=0
std::function< void(TDATA &, TDATA &, real, int)> Fincrement
std::function< bool(int, TDATA &, int)> Fstop
std::vector< TDATA > rhsbuf
typename tBase::Fsolve Fsolve
typename tBase::Fstop Fstop
TDATA & getRHS(int i) override
TDATA & getRES(int i) override
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt) override
frhs(TDATA &rhs, TDATA &x) fdt(TDTAU& dTau) fsolve(TDATA &x, TDATA &rhs, TDTAU& dTau,...
virtual ~ImplicitEulerDualTimeStep()=default
virtual TDATA & getLatestRHS() override
ImplicitEulerDualTimeStep(index NDOF, Finit &&finit=[](TDATA &) {}, FinitDtau &&finitDtau=[](TDTAU &) {})
mind that NDOF is the dof of dt finit(TDATA& data)
typename tBase::Frhs Frhs
typename tBase::Fincrement Fincrement
void StepNested(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, const FsolveNest &fsolveN, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt)
ImplicitHermite3SimpleJacobianDualStep(index NDOF, Finit &&finit=[](TDATA &) {}, FinitDtau &&finitDtau=[](TDTAU &) {}, real alpha=0.55, int nCurSolveMethod=0, int nnStartIter=0, real thetaM1n=0.9146, real thetaM2n=0.0, int mask=0, int nMGn=4)
mind that NDOF is the dof of dt finit(TDATA& data)
Eigen::Vector< real, 3 > wInteg
virtual void SetExtraParams(const nlohmann::ordered_json &j) override
typename tBase::Frhs Frhs
typename tBase::Fstop Fstop
TDATA & getRES(int i) override
typename tBase::Fincrement Fincrement
Eigen::Vector< real, 4 > cInter
void SetCoefs(real hR1=1)
typename tBase::Fsolve Fsolve
std::vector< TDATA > rhsbuf
virtual ~ImplicitHermite3SimpleJacobianDualStep()=default
virtual TDATA & getLatestRHS() override
std::function< void(TDATA &, TDATA &, TDATA &, TDTAU &, const std::vector< real > &, real, real, TDATA &, int, int)> FsolveNest
TDATA & getRHS(int i) override
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt) override
frhs(TDATA &rhs, TDATA &x) fdt(TDTAU& dTau) fsolve(TDATA &x, TDATA &rhs, TDTAU& dTau,...
typename tBase::Fincrement Fincrement
virtual TDATA & getLatestRHS() override
TDATA & getRES(int i) override
TDATA & getRHS(int i) override
ImplicitSDIRK4DualTimeStep(index NDOF, Finit &&finit=[](TDATA &) {}, FinitDtau &&finitDtau=[](TDTAU &) {}, int schemeCode=0)
mind that NDOF is the dof of dt finit(TDATA& data)
virtual ~ImplicitSDIRK4DualTimeStep()=default
typename tBase::Fsolve Fsolve
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt) override
frhs(TDATA &rhs, TDATA &x) fdt(TDTAU& dTau) fsolve(TDATA &x, TDATA &rhs, TDTAU& dTau,...
std::vector< TDATA > rhsbuf
typename tBase::Fstop Fstop
typename tBase::Frhs Frhs
typename tBase::Fstop Fstop
void StepPP(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt, const FalphaLimSource &falphaLimSource, const FresidualIncPP &fresidualIncPP)
void VBDFFrontMatters(real dt)
typename tBase::Fsolve Fsolve
ImplicitVBDFDualTimeStep(index NDOF, Finit &&finit=[](TDATA &) {}, FinitDtau &&finitDtau=[](TDTAU &) {}, index k=2)
mind that NDOF is the dof of dt finit(TDATA& data)
virtual void Step(TDATA &x, TDATA &xinc, const Frhs &frhs, const Fdt &fdt, const Fsolve &fsolve, int maxIter, const Fstop &fstop, const Fincrement &fincrement, real dt) override
frhs(TDATA &rhs, TDATA &x) fdt(std::vector<real>& dTau) fsolve(TDATA &x, TDATA &rhs,...
std::function< real(TDATA &, TDATA &)> FlimitDtBDF
TDATA & getRES(int i) override
TDATA & getRHS(int i) override
std::function< void(TDATA &, TDATA &, TDATA &, TDATA &, const std::function< void()> &, real, int)> FresidualIncPP
std::function< void(TDATA &, int)> FalphaLimSource
virtual TDATA & getLatestRHS() override
std::vector< TDATA > rhsbuf
void LimitDt_StepPPV2(TDATA &xIn, const FlimitDtBDF &flimitDtBDF, real &dtOut, real maxIncrease=2)
typename tBase::Frhs Frhs
std::vector< TDATA > xPrevs
virtual ~ImplicitVBDFDualTimeStep()=default
typename tBase::Fincrement Fincrement
real BisectSolveLower(TF &&F, real v0, real v1, real fTarget, int maxIter)
DNDS_CONSTANT const real verySmallReal
Catch-all lower bound ("effectively zero").
int64_t index
Global row / DOF index type (signed 64-bit; handles multi-billion-cell meshes).
constexpr T mod(T a, T b)
Mathematical modulo that always returns a non-negative result. Unlike % in C++ where (-1) % 3 == -1,...
constexpr T sqr(const T &a)
a * a, constexpr. Works for all arithmetic types.
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Eigen::Matrix< real, 5, 1 > v