OpenSWMM Engine  6.0.0-alpha.3
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.3)
Loading...
Searching...
No Matches
CvodeSurfaceSolver.hpp
Go to the documentation of this file.
1
26
27#ifndef OPENSWMM_ENGINE_2D_CVODE_SURFACE_SOLVER_HPP
28#define OPENSWMM_ENGINE_2D_CVODE_SURFACE_SOLVER_HPP
29
30#include "../data/MeshData.hpp"
33#include "ISurfaceSolver.hpp"
34
35#ifdef OPENSWMM_HAS_2D
36
37#include <vector>
38#include <memory>
39
40// Forward declarations for SUNDIALS types (avoid pulling in full headers)
41struct SUNContext_;
42typedef struct SUNContext_* SUNContext;
43typedef struct _generic_N_Vector* N_Vector;
44typedef struct _generic_SUNLinearSolver* SUNLinearSolver;
45
46namespace openswmm::twoD {
47
48class CvodeSurfaceSolver;
49#if defined(OPENSWMM_HAVE_HYPRE)
50class HypreAmgPreconditioner; // complete type only in the .cpp (guarded)
51#endif
52
64struct CvodeSolverContext {
65 MeshData* mesh = nullptr;
66 SurfaceStateData* state = nullptr;
67 SolverOptions2D* opts = nullptr;
68 CvodeSurfaceSolver* solver = nullptr;
69 bool amg_active = false;
70};
71
75class CvodeSurfaceSolver : public ISurfaceSolver {
76public:
77 // Defined out-of-line in the .cpp (where HypreAmgPreconditioner is a
78 // complete type) so the unique_ptr member's destructor can be instantiated
79 // there rather than at every construction site.
80 CvodeSurfaceSolver();
81 ~CvodeSurfaceSolver() override;
82
83 // Non-copyable
84 CvodeSurfaceSolver(const CvodeSurfaceSolver&) = delete;
85 CvodeSurfaceSolver& operator=(const CvodeSurfaceSolver&) = delete;
86
87 // Movable
88 CvodeSurfaceSolver(CvodeSurfaceSolver&& o) noexcept;
89 CvodeSurfaceSolver& operator=(CvodeSurfaceSolver&& o) noexcept;
90
101 void initialize(MeshData& mesh, SurfaceStateData& state,
102 SolverOptions2D& opts) override;
103
115 double advance(double t_current, double t_target) override;
116
124 void reinitialize(double t0) override;
125
129 void finalize() override;
130
132 long last_num_steps() const noexcept override { return last_nsteps_; }
133
135 double last_step_size() const noexcept override { return last_h_; }
136
141 const std::vector<double>& last_coupling_exchange() const noexcept override {
142 return last_coupling_exchange_;
143 }
144
146 bool is_initialized() const noexcept override { return cvode_mem_ != nullptr; }
147
148private:
149 void* cvode_mem_ = nullptr;
150 SUNLinearSolver ls_ = nullptr;
151 N_Vector y_ = nullptr;
152 N_Vector abstol_ = nullptr;
153 SUNContext sun_ctx_ = nullptr;
154
155 CvodeSolverContext ctx_;
156
157 long last_nsteps_ = 0;
158 double last_h_ = 0.0;
159
160 // ── Live node-coupling (macro-step) state augmentation ────────────────────
161 // When state.node_coupling is set (COUPLING_INTERVAL > 1), the state vector
162 // is augmented to nt + nc_: the extra nc_ entries A_k = ∫Q_k dt accumulate
163 // the live orifice exchange per coupling point so the 1D↔2D booking is
164 // conservative (CVODE integrates A_k with the same BDF method as V). nc_ == 0
165 // (default) ⇒ no augmentation, byte-identical to the legacy held-flux path.
166 int nc_ = 0;
167 std::vector<double> coupling_accum_start_;
168 std::vector<double> last_coupling_exchange_;
169
174 std::vector<double> precond_diag_;
175
176#if defined(OPENSWMM_HAVE_HYPRE)
180 std::unique_ptr<HypreAmgPreconditioner> amg_precond_;
185 bool amg_used_last_setup_ = false;
186#endif
187
188 // ------------------------------------------------------------------
189 // SUNDIALS callbacks. All three have C linkage requirements imposed
190 // by SUNDIALS' function-pointer typedefs; we expose them as static
191 // member functions to keep them inside the class scope.
192 // ------------------------------------------------------------------
193
200 static int rhs_fn(double t, N_Vector y, N_Vector ydot, void* user_data);
201
213 static int psetup_fn(double t, N_Vector y, N_Vector fy,
214 int jok, int* jcurPtr, double gamma,
215 void* user_data);
216
223 static int psolve_fn(double t, N_Vector y, N_Vector fy,
224 N_Vector r, N_Vector z,
225 double gamma, double delta, int lr,
226 void* user_data);
227};
228
229} // namespace openswmm::twoD
230
231#endif // OPENSWMM_HAS_2D
232
233#endif // OPENSWMM_ENGINE_2D_CVODE_SURFACE_SOLVER_HPP
Backend-neutral interface for the 2D surface-routing time integrator.
Structure-of-Arrays (SoA) storage for 2D triangular mesh geometry.
Configuration options for the 2D surface routing solver.
Structure-of-Arrays (SoA) storage for 2D surface routing state.
BoomerAMG preconditioner over the 2D diffusion Newton matrix.
Definition HypreAmgPreconditioner.hpp:42
Abstract time integrator for the 2D surface-routing ODE system.
Definition ISurfaceSolver.hpp:49
Definition NodeCoupling.cpp:15
double * y
Definition odesolve.c:28