Skip to content

Add AMM RDII integration#56

Open
wiesnerfriedman wants to merge 1 commit into
HydroCouple:swmm6_relfrom
wiesnerfriedman:pr/amm-rdii
Open

Add AMM RDII integration#56
wiesnerfriedman wants to merge 1 commit into
HydroCouple:swmm6_relfrom
wiesnerfriedman:pr/amm-rdii

Conversation

@wiesnerfriedman
Copy link
Copy Markdown
Collaborator

@wiesnerfriedman wiesnerfriedman commented Apr 16, 2026

I have read the CLA Document and I hereby sign the CLA.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an Antecedent Moisture Model (AMM) pathway as an alternative RDII formulation in the new engine, including input parsing, solver implementation, and runtime selection via an [OPTIONS] key.

Changes:

  • Registers a new [AMM] input section and adds parsing for AMM component definitions + node assignments.
  • Introduces amm::AMMSolver and wires it into SWMMEngine with a new RdiiMethod option (RDII_METHOD).
  • Extends SimulationContext / inflow data structures to store AMM assignment/parameter definitions.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
src/engine/plugins/DefaultInputPlugin.cpp Registers [AMM] section handler.
src/engine/input/handlers/OptionsHandler.cpp Adds RDII_METHOD option parsing.
src/engine/input/handlers/InflowsHandler.hpp Declares handle_amm.
src/engine/input/handlers/InflowsHandler.cpp Implements [AMM] parsing and stores into context.
src/engine/hydrology/AMM.hpp Defines AMM parameters/state and the AMMSolver interface.
src/engine/hydrology/AMM.cpp Implements AMM initialization and timestep computation.
src/engine/data/InflowData.hpp Adds AMMAssignData + component definition storage.
src/engine/core/SWMMEngine.hpp Adds AMMSolver member include + field.
src/engine/core/SWMMEngine.cpp Calls amm_.init() and attempts to compute AMM RDII in routing.
src/engine/core/SimulationOptions.hpp Adds RdiiMethod enum and rdii_method option.
src/engine/core/SimulationContext.hpp Stores AMMAssignData in the context.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1223 to +1225
// B2a2. RDII inflows (antecedent moisture model) — AMM method
if (ctx_.options.rdii_method == RdiiMethod::AMM && amm_.componentCount() > 0) {
double avg_rainfall = 0.0;
Comment on lines +1225 to +1229
double avg_rainfall = 0.0;
for (int g = 0; g < ctx_.n_gages(); ++g) {
avg_rainfall += ctx_.gages.rainfall[static_cast<std::size_t>(g)];
}
if (ctx_.n_gages() > 0) avg_rainfall /= ctx_.n_gages();
Comment on lines +195 to +198
// Scatter flow to node lateral inflow
int ni = assigns_[c].node_idx;
if (ni >= 0 && ni < n_nodes) {
ctx.nodes.lat_flow[static_cast<size_t>(ni)] += Q_t;
Comment on lines +144 to +162
// Use the assigned area, not the parameter area
double area = assigns_[c].area;

// Ensure ring-buffer sizes match dt
int precip_slots = std::max(static_cast<int>(p.PAT / dt) + 2, 1);
if (static_cast<int>(s.precip_buf.size()) != precip_slots) {
s.precip_buf.assign(static_cast<size_t>(precip_slots), 0.0);
s.precip_head = 0;
}

int temp_slots = std::max(static_cast<int>(p.TAT / dt) + 2, 1);
if (static_cast<int>(s.temp_buf.size()) != temp_slots) {
s.temp_buf.assign(static_cast<size_t>(temp_slots), 0.0);
s.temp_head = 0;
}

// Eq 3: Moving Average Precipitation
double MAP = updateMovingAverage(s.precip_buf, s.precip_head, rainfall);

Comment on lines +136 to +145
/**
* @brief Compute AMM inflows for all groups, scatter to node lat_flow.
*
* @param ctx SimulationContext (reads nodes.lat_flow, air_temp).
* @param rainfall Average rainfall intensity this step (depth/time).
* @param air_temp Air temperature this step (same units as params).
* @param dt Routing timestep (seconds).
*/
void computeAll(SimulationContext& ctx, double rainfall,
double air_temp, double dt);
Comment on lines +131 to +134
void AMMSolver::computeAll(SimulationContext& ctx, double rainfall,
double air_temp, double dt) {
if (dt <= 0.0) return;

Comment on lines +225 to +230
std::string uval = val;
std::transform(uval.begin(), uval.end(), uval.begin(), ::toupper);
if (uval == "AMM")
opt.rdii_method = RdiiMethod::AMM;
else
opt.rdii_method = RdiiMethod::RTK;
#include <charconv>
#include <string>
#include <algorithm>
#include <unordered_map>
Comment on lines +281 to +282
std::string kw = tok[1];
std::transform(kw.begin(), kw.end(), kw.begin(), ::toupper);
Comment on lines +320 to +322
std::string kw = tok[1];
std::transform(kw.begin(), kw.end(), kw.begin(), ::toupper);
if (kw == "PARAMS" || kw == "BASEFLOW" || kw == "AREA") continue;
@cbuahin
Copy link
Copy Markdown
Member

cbuahin commented May 9, 2026

@wiesnerfriedman , could you do me a favor at your convenience and make the pr to swmm6_exp. I want to keep the work to merge later.

@cbuahin
Copy link
Copy Markdown
Member

cbuahin commented May 18, 2026

@wiesnerfriedman , per our discussion offline. I am going to close this PR without merging if that makes sense to you. We will implement as a plugin instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants