ODE routines cover fixed-step explicit schemes, adaptive RK45, symplectic second-order schemes, and implicit field updates.
Adaptive RK45
dy[0] = y[1];
dy[1] = -y[0];
};
ODEResult solve(const P &prob, const RK45 &alg, ObserverFn obs=nullptr)
Umbrella include for the numerics library.
result.u is the final state, result.t is the final time, and result.steps is the accepted step count.
Fixed-Step RK4 With Samples
auto steps =
num::rk4(rhs, {1.0, 0.0}, {.t0 = 0.0, .tf = 10.0, .h = 1e-2});
for (const auto& s : steps) {
const double energy = 0.5 * (s.u[0] * s.u[0] + s.u[1] * s.u[1]);
(void)energy;
}
RK4Steps rk4(ODERhsFn f, Vector y0, ODEParams p={})
The range API is useful when every accepted step is part of the output.
Symplectic Verlet
a[0] = -q[0];
a[1] = -q[1];
};
auto orbit =
num::ode_verlet(accel, q0, v0, {.t0 = 0.0, .tf = 100.0, .h = 1
e-2});
SymplecticResult ode_verlet(AccelFn accel, Vector q0, Vector v0, ODEParams p={}, SympObserverFn obs=nullptr)
Velocity Verlet, 2nd-order symplectic, 1 force evaluation per step.
Use ode_yoshida4 when a fourth-order symplectic update is required.
Backward Euler Field Step
};
void advance(Field &u, const LinearSolver &solver, ImplicitParams p, Observer &&obs)
SPDOp< Op > assume_spd(Op op)
std::function< SolverResult(const Vector &rhs, Vector &x)> LinearSolver
Callable that solves .
SolverResult cg(const Matrix &A, const Vector &b, Vector &x, real tol=1e-10, idx max_iter=1000, Backend backend=default_backend)
bool converged
Whether tolerance was met.
Adapt a SparseMatrix to the operator protocol.
This form separates the implicit update from the linear solver used at each step.