Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/engine/core/SWMMEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,17 @@ void SWMMEngine::stepRouting(double dt_routing) noexcept {
rdii_.applyRdiiInflows(ctx_);
}

// 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 +1223 to +1225
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 +1225 to +1229
double air_temp = climate_.temperature; // current air temperature (deg F)
amm_.computeAll(ctx_, avg_rainfall, air_temp, dt_routing);
}

// B2b. Interface file inflows (from upstream model coupling)
iface_.readInflows(ctx_, ctx_.current_date);

Expand Down Expand Up @@ -2446,6 +2457,9 @@ void SWMMEngine::initHydraulics() noexcept {
// 10a. RDII solver: initialize unit hydrograph groups
rdii_.init(ctx_);

// 10a2. AMM solver: initialize antecedent moisture model groups
amm_.init(ctx_);

// 10b. Non-conduit hydraulic structures (pumps, orifices, weirs, outlets)
hydstruct_.init(ctx_);

Expand Down
2 changes: 2 additions & 0 deletions src/engine/core/SWMMEngine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "../hydrology/LID.hpp"
#include "../hydrology/Inflow.hpp"
#include "../hydrology/RDII.hpp"
#include "../hydrology/AMM.hpp"
#include "../quality/QualityRouting.hpp"
#include "../quality/Landuse.hpp"
#include "../controls/Controls.hpp"
Expand Down Expand Up @@ -236,6 +237,7 @@ class SWMMEngine {
controls::ControlEngine controls_; ///< Control rule evaluation
inflow::InflowSolver inflow_; ///< External + DWF inflows
rdii::RDIISolver rdii_; ///< RDII (unit hydrograph convolution)
amm::AMMSolver amm_; ///< AMM (antecedent moisture model)
exfil::ExfilSolver exfil_; ///< Storage node exfiltration
inlet::InletSolver inlet_; ///< Street inlet capture
std::vector<int> culvert_links_;///< Pre-built culvert link indices (avoid per-timestep alloc)
Expand Down
1 change: 1 addition & 0 deletions src/engine/core/SimulationContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ struct SimulationContext {
DwfData dwf_inflows;
RDIIAssignData rdii_assigns;
UnitHydData unit_hyds; ///< Parsed [HYDROGRAPHS] data
AMMAssignData amm_assigns;
PatternData patterns;

// =========================================================================
Expand Down
14 changes: 14 additions & 0 deletions src/engine/core/SimulationOptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ namespace openswmm {
// Enumerators matching legacy SWMM enums.h
// ============================================================================

/**
* @brief RDII computation method.
*
* RTK uses the traditional 3-triangle unit hydrograph convolution.
* AMM uses the Antecedent Moisture Model (Edgren et al., JWMM C525).
*/
enum class RdiiMethod : int {
RTK = 0, ///< Traditional RTK unit hydrograph (default)
AMM = 1 ///< Antecedent Moisture Model
};

/**
* @brief Flow unit systems.
* @see Legacy: FlowUnitsType in enums.h
Expand Down Expand Up @@ -293,6 +304,9 @@ struct SimulationOptions {
/** @brief Ignore RDII. */
bool ignore_rdii = false;

/** @brief RDII computation method (RTK or AMM). */
RdiiMethod rdii_method = RdiiMethod::RTK;

/** @brief Ignore routing. */
bool ignore_routing = false;

Expand Down
40 changes: 40 additions & 0 deletions src/engine/data/InflowData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include <vector>
#include <string>
#include <unordered_map>

namespace openswmm {

Expand Down Expand Up @@ -88,6 +89,7 @@ struct RDIIAssignData {
}
};

// ============================================================================
// ============================================================================
// Unit Hydrograph data (from [HYDROGRAPHS] section)
// ============================================================================
Expand Down Expand Up @@ -122,6 +124,44 @@ struct UnitHydData {
void add(const UnitHydEntry& e) { entries.push_back(e); }
};

// ============================================================================
// AMM assignments (from [AMM] section)
// ============================================================================

struct AMMAssignData {
int count() const { return static_cast<int>(node_idx.size()); }

std::vector<int> node_idx; ///< Target node
std::vector<std::string> amm_name; ///< AMM component group name
std::vector<double> sewer_area; ///< Tributary sewer area

void add(int ni, const std::string& name, double area) {
node_idx.push_back(ni); amm_name.push_back(name);
sewer_area.push_back(area);
}

/// Raw component parameter definition (parsed from [AMM] section).
/// Transferred to AMMSolver::addComponentParams() during init().
struct ComponentDef {
double area = 0.0;
double RD = 0.0;
double PAT = 0.0;
double HHL = 3600.0;
double AMHL = 28800.0;
double cold_SHCF = 0.0;
double hot_SHCF = 0.0;
double cold_temp = 30.0;
double hot_temp = 70.0;
double TAT = 0.0;
bool is_baseflow = false;
double cold_R = 0.0;
double hot_R = 0.0;
};

/// Map: component name → parsed parameters (populated by handle_amm).
std::unordered_map<std::string, ComponentDef> component_defs;
};

// ============================================================================
// Time patterns (from [PATTERNS] section)
// ============================================================================
Expand Down
Loading