#include "FluidSim/Solver.hpp" #include namespace fluidsim::port { Solver::Solver(std::vector &pipes, BoundarySystem &boundaries) : pipes_(pipes), boundaries_(boundaries) {} void Solver::add_component(Component &component) { components_.push_back(&component); } void Solver::step(float dt) { if (!std::isfinite(dt) || dt < 0) throw std::invalid_argument("invalid solver timestep"); if (dt == 0) return; boundaries_.validate_topology(); const float maximum_dt = dt / static_cast(std::max(minimum_substeps, 1)); double remaining = dt; int count = 0; while (remaining > double(dt) * 1e-7) { float sub_dt = std::min(maximum_dt, static_cast(remaining)); for (auto &pipe : pipes_) sub_dt = std::min(sub_dt, pipe.prepare_step()); if (!(sub_dt > 0) || ++count > 1000000) throw std::runtime_error("solver timestep failed to progress"); ++substep_count_; boundaries_.resolve(sub_dt); for (auto &pipe : pipes_) pipe.advance(sub_dt); for (Component *component : components_) component->update_state(sub_dt); remaining -= sub_dt; } ++step_count_; } } // namespace fluidsim::port