OpenSWMM Engine  6.0.0-alpha.3
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.3)
Loading...
Searching...
No Matches
Controls.hpp
Go to the documentation of this file.
1
20
21#ifndef OPENSWMM_CONTROLS_HPP
22#define OPENSWMM_CONTROLS_HPP
23
24#include <cstdint>
25#include <vector>
26#include <string>
27#include <unordered_map>
28#include "../math/MathExpr.hpp"
29
30namespace openswmm {
31
33
34namespace controls {
35
36// ============================================================================
37// Comparison and logic operators
38// ============================================================================
39
40enum class CompareOp : int { EQ = 0, NE = 1, LT = 2, LE = 3, GT = 4, GE = 5 };
41enum class LogicOp : int { AND = 0, OR = 1 };
42
43// ============================================================================
44// Condition variable types (matching ALL legacy RuleAttrib values)
45// ============================================================================
46
47enum class ConditionVar : int {
48 // Node attributes
54
55 // Link attributes
67
68 // Gage attributes
69 GAGE_RAIN = 30,
71
72 // System / time
76 SIM_DAY = 43,
77 SIM_MONTH = 44,
79};
80
81// ============================================================================
82// Action attribute (what is being set on the link)
83// ============================================================================
84
85enum class ActionType : int {
86 NUMERIC = 0,
87 CURVE = 1,
89 PID = 3
90};
91
92// ============================================================================
93// Rule premise (condition)
94// ============================================================================
95
112
113// ============================================================================
114// Rule action
115// ============================================================================
116
117struct Action {
118 int link_idx = -1;
119 int rule_idx = -1;
121 double value = 0.0;
122 int curve_idx = -1;
123 int tseries_idx = -1;
124 int pid_idx = -1;
125};
126
127// ============================================================================
128// PID controller state (per action)
129// ============================================================================
130
131struct PIDState {
132 double kp = 0.0;
133 double ki = 0.0;
134 double kd = 0.0;
135 double setpoint = 0.0;
136 double e1 = 0.0;
137 double e2 = 0.0;
138 int action_idx = -1;
139};
140
141// ============================================================================
142// Named variable (for rule expressions)
143// ============================================================================
144
146 std::string name;
148 int idx = -1;
149};
150
151// ============================================================================
152// Control rule
153// ============================================================================
154
155struct Rule {
156 std::string name;
157 std::vector<Premise> premises;
158 std::vector<Action> then_actions;
159 std::vector<Action> else_actions;
160 double priority = 0.0;
161};
162
163// ============================================================================
164// Control engine
165// ============================================================================
166
168public:
169 void init(const std::vector<Rule>& rules);
170
186 int evaluate(SimulationContext& ctx, double current_time, double dt);
187
188 // Rule parsing (from [CONTROLS] text)
189 int parseRuleText(const std::string& text, SimulationContext& ctx);
190
191 // Named variables
192 void addNamedVariable(const std::string& name, ConditionVar var, int idx);
193
194 // Math expressions
195 int addExpression(const std::string& name, const std::string& formula);
196
197 std::vector<Rule>& rules() { return rules_; }
198
200 int lastActionCount() const { return last_action_count_; }
201
205 void resetRuleStep() { next_rule_eval_time_ = -1.0; }
206
207 // ========================================================================
208 // SoA batch evaluation index (AD-14)
209 // ========================================================================
210
226 struct PremiseSoA {
228 int count = 0;
229
230 // Per-premise SoA (contiguous, aligned for SIMD)
231 std::vector<int> rule_idx;
232 std::vector<int> premise_idx;
233 std::vector<int> obj_idx;
234 std::vector<int> flat_idx;
235 std::vector<int> op;
236 std::vector<double> rhs_value;
237
238 // Per-premise flags
239 std::vector<bool> rhs_is_variable;
240 std::vector<bool> is_expression;
241
242 // Working buffer (reused each evaluate call)
243 std::vector<double> lhs_values;
244 std::vector<bool> results;
245 };
246
248 void buildPremiseSoA();
249
251 void batchEvaluateGroup(PremiseSoA& group,
252 const SimulationContext& ctx,
253 double current_time, double half_step);
254
255private:
256 int last_action_count_ = 0;
257 std::vector<Rule> rules_;
258 std::vector<PIDState> pid_states_;
259 std::vector<NamedVariable> named_vars_;
260 std::vector<mathexpr::Expression> expressions_;
261 std::unordered_map<std::string, int> expr_index_;
262
263 // SoA premise groups (one per variable type that has premises)
264 std::vector<PremiseSoA> premise_groups_;
265
266 // ------------------------------------------------------------------
267 // Two-phase evaluator state (ยง7 of CONTROL_RULES_LEGACY_PARITY_AUDIT)
268 // ------------------------------------------------------------------
269 // Phase 1 batch-evaluates premises (group-major) into the flat cache.
270 // Phase 2 walks each rule's premises in declaration order and applies
271 // legacy AND/OR semantics by reading the flat cache.
272 //
273 // Layout: premise_results_[ rule_premise_offset_[r] + p ] holds the
274 // result of rule r's premise p. uint8_t (not bool) so Phase 1's
275 // compare loops remain SIMD-writable.
276
277 std::vector<uint8_t> premise_results_;
278 std::vector<int> rule_premise_offset_;
279 int total_premises_ = 0;
280
281 // Per-rule premise result tracking (for combining AND/OR)
282 std::vector<bool> rule_results_;
283
284 // TIMEOPEN/TIMECLOSED tracking: when each link's setting last changed.
285 // Stored as absolute date (decimal days) matching legacy Link[j].timeLastSet.
286 // Step 6 of the parity remediation will move this to ctx.links.time_last_set.
287 std::vector<double> link_time_last_set_;
288
292 double next_rule_eval_time_ = -1.0;
293
294 // Tracked across a single evaluate() call
295 double control_value_ = 0.0;
296 double set_point_ = 0.0;
297
298 // Pending action list (for priority deduplication)
299 struct PendingAction {
300 int link_idx;
301 double value;
302 double priority;
303 int rule_idx;
305 };
306 std::vector<PendingAction> pending_actions_;
307
308 double getVariableValue(const SimulationContext& ctx,
309 ConditionVar var, int idx,
310 double current_time, int param = 0) const;
311
312 bool evaluatePremise(const SimulationContext& ctx,
313 const Premise& p, double current_time, double half_step);
314
315 bool compareValues(double lhs, CompareOp op, double rhs) const;
316 bool compareTimes(double lhs, CompareOp op, double rhs, double half_step) const;
317
318 double computePIDSetting(PIDState& pid, double control_value,
319 double current_setting, bool is_pump, double dt);
320
322 double current_time, double dt);
323
325 int applyPendingActions(SimulationContext& ctx, double current_time);
326
328 double getNamedVariableValue(const std::string& name,
329 const SimulationContext& ctx,
330 double current_time) const;
331};
332
333} // namespace controls
334} // namespace openswmm
335
336#endif // OPENSWMM_CONTROLS_HPP
Mathematical expression parser and evaluator.
Definition Controls.hpp:167
void resetRuleStep()
Definition Controls.hpp:205
int parseRuleText(const std::string &text, SimulationContext &ctx)
Definition Controls.cpp:908
std::vector< Rule > & rules()
Definition Controls.hpp:197
void buildPremiseSoA()
Build SoA index from rules. Called once at init().
Definition Controls.cpp:51
int addExpression(const std::string &name, const std::string &formula)
Definition Controls.cpp:644
void init(const std::vector< Rule > &rules)
Definition Controls.cpp:33
int lastActionCount() const
Number of actions taken in the last evaluate() call.
Definition Controls.hpp:200
int evaluate(SimulationContext &ctx, double current_time, double dt)
Evaluate all control rules and set link target settings.
Definition Controls.cpp:180
void batchEvaluateGroup(PremiseSoA &group, const SimulationContext &ctx, double current_time, double half_step)
Batch evaluate all premises of one variable type.
Definition Controls.cpp:132
void addNamedVariable(const std::string &name, ConditionVar var, int idx)
Definition Controls.cpp:640
int compareValues(double lhsValue, int relation, double rhsValue)
Compares two values.
Definition controls.c:2007
int compareTimes(double lhsValue, int relation, double rhsValue, double halfStep)
Compares two times.
Definition controls.c:1982
int evaluatePremise(struct TPremise *p, double tStep)
Evaluates premise clause of a control rule.
Definition controls.c:1788
void updateActionValue(struct TAction *a, DateTime currentTime, double dt)
Updates the value of a control action.
Definition controls.c:1624
double getNamedVariableValue(int varIndex)
Gets named variable value.
Definition controls.c:1055
double getVariableValue(struct TVariable v)
Gets the value of a variable.
Definition controls.c:1831
Definition Controls.cpp:29
ConditionVar
Definition Controls.hpp:47
@ LINK_TIMECLOSED
Definition Controls.hpp:66
@ SIM_TIME
Definition Controls.hpp:73
@ LINK_FULLFLOW
Definition Controls.hpp:60
@ CLOCK_TIME
Definition Controls.hpp:75
@ GAGE_RAIN_PAST
Past n-hours rainfall (n stored in idx field)
Definition Controls.hpp:70
@ NODE_INFLOW
Definition Controls.hpp:53
@ LINK_FULLDEPTH
Definition Controls.hpp:61
@ LINK_STATUS
Definition Controls.hpp:59
@ LINK_VELOCITY
Definition Controls.hpp:62
@ NODE_VOLUME
Definition Controls.hpp:52
@ NODE_DEPTH
Definition Controls.hpp:49
@ LINK_DEPTH
Definition Controls.hpp:57
@ NODE_MAXDEPTH
Definition Controls.hpp:50
@ SIM_MONTH
Month (1-12)
Definition Controls.hpp:77
@ LINK_SETTING
Definition Controls.hpp:58
@ SIM_DATE
Definition Controls.hpp:74
@ LINK_TIMEOPEN
Definition Controls.hpp:65
@ NODE_HEAD
Definition Controls.hpp:51
@ GAGE_RAIN
Current rainfall intensity.
Definition Controls.hpp:69
@ LINK_LENGTH
Definition Controls.hpp:63
@ LINK_SLOPE
Definition Controls.hpp:64
@ SIM_DAYOFYEAR
Day of year (1-365)
Definition Controls.hpp:78
@ LINK_FLOW
Definition Controls.hpp:56
@ SIM_DAY
Day of week (1-7, Sun=1)
Definition Controls.hpp:76
LogicOp
Definition Controls.hpp:41
@ OR
Definition Controls.hpp:41
@ AND
Definition Controls.hpp:41
CompareOp
Definition Controls.hpp:40
@ EQ
Definition Controls.hpp:40
@ LT
Definition Controls.hpp:40
@ GT
Definition Controls.hpp:40
@ LE
Definition Controls.hpp:40
@ NE
Definition Controls.hpp:40
@ GE
Definition Controls.hpp:40
ActionType
Definition Controls.hpp:85
@ CURVE
Setting from curve lookup(ControlValue)
Definition Controls.hpp:87
@ PID
PID controller output.
Definition Controls.hpp:89
@ TIMESERIES
Setting from timeseries lookup(currentTime)
Definition Controls.hpp:88
@ NUMERIC
Direct numeric setting value.
Definition Controls.hpp:86
Definition NodeCoupling.cpp:15
Central, reentrant simulation context.
Definition SimulationContext.hpp:292
Definition Controls.hpp:117
int rule_idx
Parent rule index (for priority lookup)
Definition Controls.hpp:119
int link_idx
Link being controlled.
Definition Controls.hpp:118
ActionType type
Definition Controls.hpp:120
int curve_idx
Curve index (for CURVE type)
Definition Controls.hpp:122
int pid_idx
PID state index (for PID type)
Definition Controls.hpp:124
double value
Direct value or computed result.
Definition Controls.hpp:121
int tseries_idx
Timeseries index (for TIMESERIES type)
Definition Controls.hpp:123
Pre-sorted premise index for batch evaluation.
Definition Controls.hpp:226
ConditionVar var_type
All premises in this group test this variable.
Definition Controls.hpp:227
std::vector< bool > rhs_is_variable
True if RHS is a variable (not batch-able)
Definition Controls.hpp:239
std::vector< int > premise_idx
Position within the rule's premise list.
Definition Controls.hpp:232
std::vector< int > flat_idx
Position in flat premise_results_ cache.
Definition Controls.hpp:234
std::vector< int > op
CompareOp as int.
Definition Controls.hpp:235
std::vector< bool > results
Comparison results.
Definition Controls.hpp:244
std::vector< bool > is_expression
True if LHS is an expression.
Definition Controls.hpp:240
std::vector< double > rhs_value
RHS threshold value.
Definition Controls.hpp:236
std::vector< double > lhs_values
Gathered LHS values.
Definition Controls.hpp:243
std::vector< int > obj_idx
Object index (node/link/gage)
Definition Controls.hpp:233
std::vector< int > rule_idx
Which rule this premise belongs to.
Definition Controls.hpp:231
int count
Definition Controls.hpp:228
Definition Controls.hpp:145
int idx
Definition Controls.hpp:148
ConditionVar var
Definition Controls.hpp:147
std::string name
Definition Controls.hpp:146
Definition Controls.hpp:131
double kd
Definition Controls.hpp:134
double kp
Definition Controls.hpp:132
double e2
Error two steps back.
Definition Controls.hpp:137
double ki
Integral time (minutes, 0=disable)
Definition Controls.hpp:133
int action_idx
Associated action index.
Definition Controls.hpp:138
double setpoint
Definition Controls.hpp:135
double e1
Previous error.
Definition Controls.hpp:136
Definition Controls.hpp:96
int lhs_param
Extra parameter (e.g. n-hours for GAGE_RAIN_PAST)
Definition Controls.hpp:103
double rhs_value
Definition Controls.hpp:110
ConditionVar lhs_var
Definition Controls.hpp:101
int expr_idx
Index into expressions_ (-1 if N/A)
Definition Controls.hpp:99
int lhs_idx
Object index (node/link/gage)
Definition Controls.hpp:102
bool is_expression
True if LHS is a math expression.
Definition Controls.hpp:98
ConditionVar rhs_var
Definition Controls.hpp:108
int rhs_idx
Definition Controls.hpp:109
bool rhs_is_variable
Definition Controls.hpp:107
LogicOp logic
Definition Controls.hpp:97
CompareOp op
Definition Controls.hpp:105
Definition Controls.hpp:155
std::string name
Definition Controls.hpp:156
double priority
Definition Controls.hpp:160
std::vector< Action > else_actions
Definition Controls.hpp:159
std::vector< Action > then_actions
Definition Controls.hpp:158
std::vector< Premise > premises
Definition Controls.hpp:157