11#ifndef PBAT_SIM_INTEGRATION_BDF_H
12#define PBAT_SIM_INTEGRATION_BDF_H
75template <
class TScalar = Scalar,
class TIndex = Index>
90 Bdf(
int step = 1,
int order = 2);
92 Eigen::Matrix<ScalarType, Eigen::Dynamic, Eigen::Dynamic>
96 Eigen::Matrix<ScalarType, Eigen::Dynamic, Eigen::Dynamic>
107 [[maybe_unused]]
auto Order()
const {
return mOrder; }
112 [[maybe_unused]]
auto Step()
const {
return mStep; }
135 auto State(
int k,
int o = 0) const -> decltype(
xt.col(0));
142 auto
State(
int k,
int o = 0) -> decltype(
xt.col(0));
159 [[maybe_unused]] auto
Alpha()
const {
return mAlpha(Eigen::seqN(0, mStep)); }
164 [[maybe_unused]]
auto Beta()
const {
return mBeta; }
169 [[maybe_unused]]
auto BetaTilde()
const {
return mBeta *
h; }
201 template <
class TDerivedX>
209 template <
class... TDerivedX>
216 template <
class TDerivedX>
217 void Step(Eigen::DenseBase<TDerivedX>
const& x);
224 template <
class... TDerivedX>
225 void Step(Eigen::DenseBase<TDerivedX>
const&... xs);
244 Eigen::Vector<ScalarType, 6>
250template <
class TScalar,
class TIndex>
258template <
class TScalar,
class TIndex>
261 if (k < 0 || k > mStep)
263 throw std::out_of_range(
"0 <= k <= s");
265 if (o < 0 || o >= mOrder)
267 throw std::out_of_range(
"0 <= o < order");
269 auto kt = common::Modulo(
ti + k, mStep);
270 return xt.col(o * mStep + kt);
273template <
class TScalar,
class TIndex>
276 if (k < 0 || k > mStep)
278 throw std::out_of_range(
"0 <= k <= s");
280 if (o < 0 || o >= mOrder)
282 throw std::out_of_range(
"0 <= o < order");
284 auto kt = common::Modulo(
ti + k, mStep);
285 return xt.col(o * mStep + kt);
288template <
class TScalar,
class TIndex>
291 return State(mStep - 1, o);
294template <
class TScalar,
class TIndex>
297 return State(mStep - 1, o);
300template <
class TScalar,
class TIndex>
305 throw std::invalid_argument(
"order > 0");
310template <
class TScalar,
class TIndex>
313 if (step < 1 || step > 6)
315 throw std::invalid_argument(
"0 < s < 7.");
326 mAlpha(0) =
Scalar(1) / 3;
327 mAlpha(1) =
Scalar(-4) / 3;
331 mAlpha(0) =
Scalar(-2) / 11;
332 mAlpha(1) =
Scalar(9) / 11;
333 mAlpha(2) =
Scalar(-18) / 11;
337 mAlpha(0) =
Scalar(3) / 25;
338 mAlpha(1) =
Scalar(-16) / 25;
339 mAlpha(2) =
Scalar(36) / 25;
340 mAlpha(3) =
Scalar(-48) / 25;
344 mAlpha(0) =
Scalar(-12) / 137;
345 mAlpha(1) =
Scalar(75) / 137;
346 mAlpha(2) =
Scalar(-200) / 137;
347 mAlpha(3) =
Scalar(300) / 137;
348 mAlpha(4) =
Scalar(-300) / 137;
352 mAlpha(0) =
Scalar(10) / 147;
353 mAlpha(1) =
Scalar(-72) / 147;
354 mAlpha(2) =
Scalar(225) / 147;
355 mAlpha(3) =
Scalar(-400) / 147;
356 mAlpha(4) =
Scalar(450) / 147;
357 mAlpha(5) =
Scalar(-360) / 147;
363template <
class TScalar,
class TIndex>
368 throw std::invalid_argument(
"dt > 0");
373template <
class TScalar,
class TIndex>
377 for (
auto o = 0; o < mOrder; ++o)
378 for (
auto k = 0; k < mStep; ++k)
382template <
class TScalar,
class TIndex>
383template <
class TDerivedX>
388 xt.resize(n, mStep * mOrder);
390 for (
auto o = 0; o < mOrder; ++o)
391 xt.middleCols(o * mStep, mStep).colwise() = x0.col(o);
394template <
class TScalar,
class TIndex>
395template <
class... TDerivedX>
398 auto constexpr nDerivs =
sizeof...(TDerivedX);
399 assert(nDerivs == mOrder);
400 std::tuple<
decltype(x0)...> tup{x0...};
402 auto n = std::get<0>(tup).rows();
403 xt.resize(n, mStep * mOrder);
405#include "pbat/warning/Push.h"
406#include "pbat/warning/SignConversion.h"
408 [&]<
auto o>() {
xt.middleCols(o * mStep, mStep).colwise() = std::get<o>(tup); });
409#include "pbat/warning/Pop.h"
412template <
class TScalar,
class TIndex>
413template <
class TDerivedX>
417 for (
auto o = 0; o < mOrder; ++o)
421template <
class TScalar,
class TIndex>
422template <
class... TDerivedX>
425 auto constexpr nDerivs =
sizeof...(TDerivedX);
426 assert(nDerivs == mOrder);
428 std::tuple<
decltype(x)...> tup{x...};
432template <
class TScalar,
class TIndex>
435 io::Archive bdfArchive = archive[
"pbat.sim.integration.Bdf"];
446template <
class TScalar,
class TIndex>
449 io::Archive const group = archive[
"pbat.sim.integration.Bdf"];
Archive class for reading and writing data to HDF5 files.
Definition Archive.h:29
T ReadData(std::string const &path) const
Read data from the archive.
Definition Archive.h:179
void WriteMetaData(std::string const &key, T const &value)
Write metadata to the archive.
Definition Archive.h:158
void WriteData(std::string const &path, T const &data)
Write data to the archive.
Definition Archive.h:137
T ReadMetaData(std::string const &key) const
Read metadata from the archive.
Definition Archive.h:195
TIndex IndexType
Definition Bdf.h:80
auto Order() const
Order of the ODE.
Definition Bdf.h:107
void SetInitialConditions(Eigen::DenseBase< TDerivedX > const &x0)
Set the initial conditions for the initial value problem.
Definition Bdf.h:384
auto State(int k, int o=0) const -> decltype(xt.col(0))
state derivative
Definition Bdf.h:259
ScalarType h
Definition Bdf.h:101
auto Beta() const
Forcing term coefficient s.t. .
Definition Bdf.h:164
void SetTimeStep(ScalarType dt)
Set the time step size.
Definition Bdf.h:364
void SetInitialConditions(Eigen::DenseBase< TDerivedX > const &... x0)
Set the initial conditions for the initial value problem.
Definition Bdf.h:396
auto Step() const
Step s of the s-step BDF scheme.
Definition Bdf.h:112
auto BetaTilde() const
Time-step scaled forcing term coefficient .
Definition Bdf.h:169
auto CurrentState(int o=0) const -> decltype(xt.col(0))
Eigen::Matrix< ScalarType, Eigen::Dynamic, Eigen::Dynamic > xt
Definition Bdf.h:93
void Step(Eigen::DenseBase< TDerivedX > const &x)
Advance the BDF scheme by one time step.
Definition Bdf.h:414
void SetStep(int step)
Set the step of the BDF scheme.
Definition Bdf.h:311
IndexType ti
Definition Bdf.h:100
void SetOrder(int order)
Set the order of the ODE system.
Definition Bdf.h:301
TScalar ScalarType
Definition Bdf.h:79
Eigen::Matrix< ScalarType, Eigen::Dynamic, Eigen::Dynamic > xtilde
Definition Bdf.h:97
void Serialize(io::Archive &archive) const
Serialize to HDF5 group.
Definition Bdf.h:433
void Deserialize(io::Archive const &archive)
Deserialize from HDF5 group.
Definition Bdf.h:447
auto Dimensions() const
Number of ODEs.
Definition Bdf.h:117
Bdf(int step=1, int order=2)
Construct a step-step BDF (backward differentiation formula) time integration scheme for a system of ...
Definition Bdf.h:251
void ConstructEquations()
Construct the BDF equations, i.e. compute for all .
Definition Bdf.h:374
void Tick()
Advance the BDF scheme by one time step.
Definition Bdf.h:229
auto Inertia(int o) const
Inertia of the BDF scheme for the state derivative.
Definition Bdf.h:128
auto Alpha() const
Definition Bdf.h:159
void Step(Eigen::DenseBase< TDerivedX > const &... xs)
Advance the BDF scheme by one time step.
Definition Bdf.h:423
auto TimeStep() const
Time step size.
Definition Bdf.h:122
Concepts for common types.
constexpr void ForRange(F &&f)
Compile-time for loop over a range of values.
Definition ConstexprFor.h:55
ODE integration schemes.
Definition Bdf.cpp:3
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic-size matrix type.
Definition Aliases.h:34
Eigen::Vector< Scalar, N > Vector
Fixed-size vector type.
Definition Aliases.h:24
std::ptrdiff_t Index
Index type.
Definition Aliases.h:17
double Scalar
Scalar type.
Definition Aliases.h:18