OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
NodeData.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2//
3// Copyright 2026 Caleb Buahin
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
40
41#ifndef OPENSWMM_ENGINE_NODE_DATA_HPP
42#define OPENSWMM_ENGINE_NODE_DATA_HPP
43
44#include <vector>
45#include <cstdint>
46#include <string>
47#include <algorithm>
48
49namespace openswmm {
50
51// ============================================================================
52// Node type enumeration
53// ============================================================================
54
59enum class NodeType : int8_t {
64};
65
70enum class OutfallType : int8_t {
71 FREE = 0,
72 NORMAL = 1,
73 FIXED = 2,
74 TIDAL = 3,
76};
77
82enum class DividerType : int8_t {
83 CUTOFF = 0,
86 WEIR = 3
87};
88
104enum class StorageShape : int8_t {
111};
112
113// ============================================================================
114// NodeData — SoA layout
115// ============================================================================
116
130struct NodeData {
131
132 // -----------------------------------------------------------------------
133 // Static properties — set at parse time
134 // -----------------------------------------------------------------------
135
137 std::vector<NodeType> type;
138
143 std::vector<double> invert_elev;
144
149 std::vector<double> full_depth;
150
155 std::vector<double> init_depth;
156
161 std::vector<double> sur_depth;
162
167 std::vector<double> ponded_area;
168
178 std::vector<uint8_t> is_virtual;
179
190 std::vector<uint8_t> is_inlet;
191
206 std::vector<double> rim_depth;
207
208 // -----------------------------------------------------------------------
209 // Node subtype properties (storage / outfall / divider)
210 // -----------------------------------------------------------------------
211 // Relational node refactor (Phase 4): the wide per-node storage_* / outfall_*
212 // / divider_* / exfil_* arrays that used to live here have been REMOVED. They
213 // now live in the dense relational side-tables (StorageData / OutfallData /
214 // DividerData in NodeSubtypes.hpp), sized to the count of each subtype and
215 // joined to base nodes by node_idx — the memory win of the refactor. Only the
216 // base `type[i]` discriminator remains on NodeData. See
217 // docs/relational/RELATIONAL_NODE_REFACTOR_PLAN.md.
218
219 // -----------------------------------------------------------------------
220 // State variables — updated each timestep
221 // -----------------------------------------------------------------------
222
227 std::vector<double> depth;
228
233 std::vector<double> head;
234
239 std::vector<double> volume;
240
245 std::vector<double> lat_flow;
246
254 std::vector<double> user_lat_flow;
255
256 // -----------------------------------------------------------------------
257 // Decomposed lateral inflow sources
258 // Each source process writes to its own buffer.
259 // assembleLateralInflows() sums them all into lat_flow.
260 // -----------------------------------------------------------------------
261
263 std::vector<double> runoff_inflow;
264
266 std::vector<double> gw_inflow;
267
269 std::vector<double> ext_inflow;
270
272 std::vector<double> dwf_inflow;
273
275 std::vector<double> rdii_inflow;
276
278 std::vector<double> iface_inflow;
279
301 std::vector<double> coupling_inflow;
302
316 std::vector<double> coupling_volume;
317
334 std::vector<double> coupling_queue;
335
350 std::vector<double> coupling_qual_queue;
353 std::vector<double> coupling_qual_inflow;
354
365 std::vector<double> coupling_age_vol_queue;
366 std::vector<double> coupling_temp_vol_queue;
367 std::vector<double> coupling_age_vol_inflow;
368 std::vector<double> coupling_temp_vol_inflow;
369 bool coupling_tuple_age = false;
371
372 // -----------------------------------------------------------------------
373 // Quality mass inflow assembly arrays
374 // assembleQualityInflows() writes these; mixAtNodes() reads them.
375 // -----------------------------------------------------------------------
376
379 std::vector<double> qual_mass_in;
380
382 std::vector<double> qual_vol_in;
383
392 std::vector<double> iface_qual_mass;
393
406 std::vector<double> ext_qual_mass;
407
417 std::vector<double> dwf_qual_mass;
418
428 std::vector<double> lid_drain_qual_load;
429
436 std::vector<double> lid_drain_qual_vol;
449 std::vector<double> lid_drain_inflow;
450
451 // -----------------------------------------------------------------------
452 // Per-node quality state — flat 2D: [node * n_pollutants + pollutant]
453 // -----------------------------------------------------------------------
454
460 std::vector<double> conc;
461
463 std::vector<double> conc_old;
464
466 std::vector<double> hrt;
467
477 std::vector<double> user_conc_mass_flux;
478
481
486 std::vector<double> inflow;
487
492 std::vector<double> outflow;
493
498 std::vector<double> overflow;
499
504 std::vector<double> losses;
505
510 std::vector<double> crown_elev;
511
516 std::vector<int> degree;
517
522 std::vector<double> old_net_inflow;
523
528 std::vector<double> full_volume;
529
530 // -----------------------------------------------------------------------
531 // Previous-step state (for output interpolation / CFL checks)
532 // -----------------------------------------------------------------------
533
535 std::vector<double> old_depth;
536
538 std::vector<double> old_volume;
539
541 std::vector<double> old_lat_flow;
542
547 std::vector<double> old_inflow;
548
549 // -----------------------------------------------------------------------
550 // Per-object INP comment
551 // -----------------------------------------------------------------------
552
562 std::vector<std::string> comments;
563
575 std::vector<std::string> tags;
576
577 // -----------------------------------------------------------------------
578 // Report flag — per-object output filter
579 // -----------------------------------------------------------------------
580
583 std::vector<char> rpt_flag;
584
585 // -----------------------------------------------------------------------
586 // Cumulative statistics
587 // -----------------------------------------------------------------------
588
593 std::vector<double> stat_vol_flooded;
594
599 std::vector<double> stat_time_flooded;
600
605 std::vector<double> stat_max_depth;
606
611 std::vector<double> stat_max_overflow;
612
614 std::vector<double> stat_max_overflow_date;
615
618 std::vector<double> stat_sum_depth;
619
625 std::vector<double> stat_sum_volume;
626
629 std::vector<double> stat_max_depth_date;
630
633 std::vector<double> stat_max_rpt_depth;
634
637 std::vector<double> stat_max_inflow_date;
638
641 std::vector<double> stat_time_surcharged;
642
645 std::vector<double> stat_max_surcharge_height;
646
651 std::vector<double> stat_outfall_avg_flow;
652
655 std::vector<double> stat_max_lat_inflow;
656
659 std::vector<double> stat_max_total_inflow;
660
665 std::vector<double> stat_storage_max_outflow;
666
669 std::vector<double> stat_lat_inflow_vol;
670
672 std::vector<double> stat_total_inflow_vol;
673
676 std::vector<double> stat_total_outflow_vol;
677
682 std::vector<double> stat_outfall_max_flow;
683
688 std::vector<long> stat_outfall_periods;
689
696 std::vector<int> stat_non_converged_count;
697
705 std::vector<double> stat_time_courant_critical;
706
713 std::vector<double> stat_total_load;
715
716 // -----------------------------------------------------------------------
717 // Capacity management
718 // -----------------------------------------------------------------------
719
721 int count() const noexcept { return static_cast<int>(type.size()); }
722
730 void resize(int n) {
731 const auto un = static_cast<std::size_t>(n);
732 type.assign(un, NodeType::JUNCTION);
733 invert_elev.assign(un, 0.0);
734 full_depth.assign(un, 0.0);
735 init_depth.assign(un, 0.0);
736 sur_depth.assign(un, 0.0);
737 ponded_area.assign(un, 0.0);
738 is_virtual.assign(un, 0);
739 is_inlet.assign(un, 0);
740 rim_depth.assign(un, 0.0);
741
742 // Subtype config (storage/outfall/divider) lives in NodeSubtypes side-tables.
743 depth.assign(un, 0.0);
744 head.assign(un, 0.0);
745 volume.assign(un, 0.0);
746 lat_flow.assign(un, 0.0);
747 user_lat_flow.assign(un, 0.0);
748 runoff_inflow.assign(un, 0.0);
749 gw_inflow.assign(un, 0.0);
750 ext_inflow.assign(un, 0.0);
751 dwf_inflow.assign(un, 0.0);
752 rdii_inflow.assign(un, 0.0);
753 iface_inflow.assign(un, 0.0);
754 coupling_inflow.assign(un, 0.0);
755 coupling_volume.assign(un, 0.0);
756 coupling_queue.assign(un, 0.0);
757 coupling_age_vol_queue.assign(un, 0.0);
758 coupling_temp_vol_queue.assign(un, 0.0);
759 coupling_age_vol_inflow.assign(un, 0.0);
760 coupling_temp_vol_inflow.assign(un, 0.0);
761 qual_mass_in.clear();
762 iface_qual_mass.clear();
763 coupling_qual_queue.clear();
764 coupling_qual_inflow.clear();
765 ext_qual_mass.clear();
766 dwf_qual_mass.clear();
767 qual_vol_in.assign(un, 0.0);
768 lid_drain_qual_load.clear();
769 lid_drain_qual_vol.assign(un, 0.0);
770 lid_drain_inflow.assign(un, 0.0);
771 inflow.assign(un, 0.0);
772 outflow.assign(un, 0.0);
773 overflow.assign(un, 0.0);
774 losses.assign(un, 0.0);
775 crown_elev.assign(un, 0.0);
776 degree.assign(un, 0);
777 old_net_inflow.assign(un, 0.0);
778 full_volume.assign(un, 0.0);
779 old_depth.assign(un, 0.0);
780 old_volume.assign(un, 0.0);
781 old_lat_flow.assign(un, 0.0);
782 old_inflow.assign(un, 0.0);
783
784 comments.assign(un, std::string{});
785 tags.assign(un, std::string{});
786
787 rpt_flag.assign(un, 0);
788
789 stat_vol_flooded.assign(un, 0.0);
790 stat_time_flooded.assign(un, 0.0);
791 stat_max_depth.assign(un, 0.0);
792 stat_max_overflow.assign(un, 0.0);
793 stat_max_overflow_date.assign(un, 0.0);
794 stat_sum_depth.assign(un, 0.0);
795 stat_sum_volume.assign(un, 0.0);
796 stat_max_depth_date.assign(un, 0.0);
797 stat_max_rpt_depth.assign(un, 0.0);
798 stat_max_inflow_date.assign(un, 0.0);
799 stat_time_surcharged.assign(un, 0.0);
800 stat_max_surcharge_height.assign(un, 0.0);
801 stat_max_lat_inflow.assign(un, 0.0);
802 stat_max_total_inflow.assign(un, 0.0);
803 stat_storage_max_outflow.assign(un, 0.0);
804 stat_lat_inflow_vol.assign(un, 0.0);
805 stat_total_inflow_vol.assign(un, 0.0);
806 stat_total_outflow_vol.assign(un, 0.0);
807 stat_outfall_avg_flow.assign(un, 0.0);
808 stat_outfall_max_flow.assign(un, 0.0);
809 stat_outfall_periods.assign(un, 0);
810 stat_non_converged_count.assign(un, 0);
811 stat_time_courant_critical.assign(un, 0.0);
812 }
813
821 void grow_to(int n) {
822 if (n <= count()) return;
823 const auto un = static_cast<std::size_t>(n);
824 auto g = [&](auto& vec, auto def) { vec.resize(un, def); };
826 g(invert_elev, 0.0); g(full_depth, 0.0); g(init_depth, 0.0);
827 g(sur_depth, 0.0); g(ponded_area, 0.0);
828 g(is_virtual, static_cast<uint8_t>(0));
829 g(is_inlet, static_cast<uint8_t>(0));
830 g(rim_depth, 0.0);
831 // Subtype config (storage/outfall/divider) lives in NodeSubtypes side-tables.
832 g(depth, 0.0); g(head, 0.0); g(volume, 0.0);
833 g(lat_flow, 0.0); g(user_lat_flow, 0.0);
834 g(runoff_inflow, 0.0); g(gw_inflow, 0.0); g(ext_inflow, 0.0);
835 g(dwf_inflow, 0.0); g(rdii_inflow, 0.0); g(iface_inflow, 0.0);
836 g(coupling_inflow, 0.0); g(coupling_volume, 0.0); g(coupling_queue, 0.0);
839 qual_vol_in.resize(un, 0.0);
840 lid_drain_qual_vol.resize(un, 0.0);
841 lid_drain_inflow.resize(un, 0.0);
842 g(inflow, 0.0); g(outflow, 0.0); g(overflow, 0.0);
843 g(losses, 0.0); g(crown_elev, 0.0); g(degree, 0);
844 g(old_net_inflow, 0.0); g(full_volume, 0.0);
845 g(old_depth, 0.0); g(old_volume, 0.0); g(old_lat_flow, 0.0);
846 g(old_inflow, 0.0);
847 comments.resize(un, std::string{});
848 tags.resize(un, std::string{});
849
850 g(rpt_flag, static_cast<char>(0));
851 g(stat_vol_flooded, 0.0); g(stat_time_flooded, 0.0);
852 g(stat_max_depth, 0.0); g(stat_max_overflow, 0.0);
853 g(stat_max_overflow_date, 0.0); g(stat_sum_depth, 0.0);
854 g(stat_sum_volume, 0.0);
865 // Note: qual_mass_in, conc, conc_old, hrt handled by resize_quality()
866 }
867
886 void reserve_to(int n) {
887 if (n <= 0) return;
888 const auto un = static_cast<std::size_t>(n);
889 if (type.capacity() >= un) return;
890 auto r = [&](auto& vec) { vec.reserve(un); };
891 r(type); r(invert_elev); r(full_depth); r(init_depth);
893 r(head); r(volume); r(lat_flow); r(user_lat_flow);
896 r(coupling_queue); r(inflow); r(outflow); r(overflow);
899 r(losses); r(crown_elev); r(degree); r(old_net_inflow);
909 }
910
920 void erase_at(int idx) {
921 const auto ui = static_cast<std::size_t>(idx);
922 auto e = [&](auto& v) { if (ui < v.size()) v.erase(v.begin() + static_cast<std::ptrdiff_t>(idx)); };
923
925 e(is_virtual); e(is_inlet); e(rim_depth);
926
927 // Subtype config (storage/outfall/divider) lives in NodeSubtypes side-tables;
928 // its rows are erased/renumbered by NodeSubtypes::erase_node (called by the
929 // node-delete path), not here.
930 e(depth); e(head); e(volume);
931 e(lat_flow); e(user_lat_flow);
938 e(inflow); e(outflow); e(overflow); e(losses);
941 e(comments); e(tags); e(rpt_flag);
942
951
952 // Flat 2D quality arrays: [node * np + p] → erase the stride for idx
953 if (conc_n_pollutants > 0) {
954 const auto np = static_cast<std::size_t>(conc_n_pollutants);
955 const auto base = ui * np;
956 auto erase2d = [&](auto& v) {
957 if (base + np <= v.size())
958 v.erase(v.begin() + static_cast<std::ptrdiff_t>(base),
959 v.begin() + static_cast<std::ptrdiff_t>(base + np));
960 };
961 erase2d(conc); erase2d(conc_old);
962 erase2d(qual_mass_in); erase2d(iface_qual_mass);
963 erase2d(coupling_qual_queue); erase2d(coupling_qual_inflow);
964 erase2d(ext_qual_mass);
965 erase2d(dwf_qual_mass);
966 erase2d(lid_drain_qual_load); erase2d(user_conc_mass_flux);
967 if (ui < hrt.size()) hrt.erase(hrt.begin() + static_cast<std::ptrdiff_t>(idx));
968 }
969
970 // Flat 2D stat load: [node * np + p]
971 if (stat_n_pollutants > 0) {
972 const auto np = static_cast<std::size_t>(stat_n_pollutants);
973 const auto base = ui * np;
974 if (base + np <= stat_total_load.size())
975 stat_total_load.erase(
976 stat_total_load.begin() + static_cast<std::ptrdiff_t>(base),
977 stat_total_load.begin() + static_cast<std::ptrdiff_t>(base + np));
978 }
979 }
980
984 void resize_loads(int n_pollutants) {
985 stat_n_pollutants = n_pollutants;
986 if (n_pollutants > 0) {
987 auto total = static_cast<std::size_t>(count()) *
988 static_cast<std::size_t>(n_pollutants);
989 stat_total_load.assign(total, 0.0);
990 }
991 }
992
996 void resize_quality(int n_pollutants) {
997 conc_n_pollutants = n_pollutants;
998 if (n_pollutants > 0) {
999 auto total = static_cast<std::size_t>(count()) *
1000 static_cast<std::size_t>(n_pollutants);
1001 conc.assign(total, 0.0);
1002 conc_old.assign(total, 0.0);
1003 hrt.assign(static_cast<std::size_t>(count()), 0.0);
1004 user_conc_mass_flux.assign(total, 0.0);
1005 qual_mass_in.assign(total, 0.0);
1006 iface_qual_mass.assign(total, 0.0);
1007 coupling_qual_queue.assign(total, 0.0);
1008 coupling_qual_inflow.assign(total, 0.0);
1009 ext_qual_mass.assign(total, 0.0);
1010 dwf_qual_mass.assign(total, 0.0);
1011 lid_drain_qual_load.assign(total, 0.0);
1012 }
1013 }
1014
1023 type.shrink_to_fit();
1024 invert_elev.shrink_to_fit();
1025 full_depth.shrink_to_fit();
1026 init_depth.shrink_to_fit();
1027 sur_depth.shrink_to_fit();
1028 ponded_area.shrink_to_fit();
1029 is_virtual.shrink_to_fit();
1030 is_inlet.shrink_to_fit();
1031 rim_depth.shrink_to_fit();
1032
1033 // Subtype config (storage/outfall/divider) lives in NodeSubtypes side-tables.
1034 depth.shrink_to_fit();
1035 head.shrink_to_fit();
1036 volume.shrink_to_fit();
1037 lat_flow.shrink_to_fit();
1038 user_lat_flow.shrink_to_fit();
1039 runoff_inflow.shrink_to_fit();
1040 gw_inflow.shrink_to_fit();
1041 ext_inflow.shrink_to_fit();
1042 dwf_inflow.shrink_to_fit();
1043 rdii_inflow.shrink_to_fit();
1044 iface_inflow.shrink_to_fit();
1045 coupling_inflow.shrink_to_fit();
1046 coupling_volume.shrink_to_fit();
1047 coupling_queue.shrink_to_fit();
1048 coupling_age_vol_queue.shrink_to_fit(); coupling_temp_vol_queue.shrink_to_fit();
1049 coupling_age_vol_inflow.shrink_to_fit(); coupling_temp_vol_inflow.shrink_to_fit();
1050 qual_mass_in.shrink_to_fit();
1051 iface_qual_mass.shrink_to_fit();
1052 coupling_qual_queue.shrink_to_fit();
1053 coupling_qual_inflow.shrink_to_fit();
1054 ext_qual_mass.shrink_to_fit();
1055 dwf_qual_mass.shrink_to_fit();
1056 qual_vol_in.shrink_to_fit();
1057 conc.shrink_to_fit();
1058 conc_old.shrink_to_fit();
1059 user_conc_mass_flux.shrink_to_fit();
1060 inflow.shrink_to_fit();
1061 outflow.shrink_to_fit();
1062 overflow.shrink_to_fit();
1063 losses.shrink_to_fit();
1064 crown_elev.shrink_to_fit();
1065 degree.shrink_to_fit();
1066 old_net_inflow.shrink_to_fit();
1067 full_volume.shrink_to_fit();
1068 old_depth.shrink_to_fit();
1069 old_volume.shrink_to_fit();
1070 old_lat_flow.shrink_to_fit();
1071 old_inflow.shrink_to_fit();
1072
1073 comments.shrink_to_fit();
1074 tags.shrink_to_fit();
1075
1076 rpt_flag.shrink_to_fit();
1077
1078 stat_vol_flooded.shrink_to_fit();
1079 stat_time_flooded.shrink_to_fit();
1080 stat_max_depth.shrink_to_fit();
1081 stat_max_overflow.shrink_to_fit();
1082 stat_max_overflow_date.shrink_to_fit();
1083 stat_sum_depth.shrink_to_fit();
1084 stat_max_depth_date.shrink_to_fit();
1085 stat_max_rpt_depth.shrink_to_fit();
1086 stat_max_inflow_date.shrink_to_fit();
1087 stat_time_surcharged.shrink_to_fit();
1088 stat_max_surcharge_height.shrink_to_fit();
1089 stat_max_lat_inflow.shrink_to_fit();
1090 stat_max_total_inflow.shrink_to_fit();
1091 stat_storage_max_outflow.shrink_to_fit();
1092 stat_lat_inflow_vol.shrink_to_fit();
1093 stat_total_inflow_vol.shrink_to_fit();
1094 stat_total_outflow_vol.shrink_to_fit();
1095 stat_outfall_avg_flow.shrink_to_fit();
1096 stat_outfall_max_flow.shrink_to_fit();
1097 stat_outfall_periods.shrink_to_fit();
1098 stat_total_load.shrink_to_fit();
1099 }
1100
1104 void save_state() noexcept {
1105 std::copy(depth.begin(), depth.end(), old_depth.begin());
1106 std::copy(volume.begin(), volume.end(), old_volume.begin());
1107 std::copy(lat_flow.begin(), lat_flow.end(), old_lat_flow.begin());
1108 // Legacy node_setOldHydState (node.c:294): oldFlowInflow = inflow
1109 std::copy(inflow.begin(), inflow.end(), old_inflow.begin());
1110 // Save net inflow for trapezoidal averaging in next step
1111 for (std::size_t i = 0; i < inflow.size(); ++i) {
1112 old_net_inflow[i] = inflow[i] - outflow[i];
1113 }
1114 std::copy(conc.begin(), conc.end(), conc_old.begin());
1115 }
1116
1123 void reset_state() noexcept {
1124 const auto n = depth.size();
1125 // Apply initial depths from input (matching legacy node_initState)
1126 for (std::size_t i = 0; i < n; ++i) {
1127 depth[i] = init_depth[i];
1128 old_depth[i] = init_depth[i];
1129 head[i] = invert_elev[i] + init_depth[i];
1130 }
1131 // Volumes must be computed from init_depth by caller (needs table data)
1132 std::fill(volume.begin(), volume.end(), 0.0);
1133 std::fill(old_volume.begin(), old_volume.end(), 0.0);
1134 // Zero flows
1135 std::fill(lat_flow.begin(), lat_flow.end(), 0.0);
1136 std::fill(inflow.begin(), inflow.end(), 0.0);
1137 std::fill(outflow.begin(), outflow.end(), 0.0);
1138 std::fill(overflow.begin(), overflow.end(), 0.0);
1139 std::fill(losses.begin(), losses.end(), 0.0);
1140 std::fill(old_net_inflow.begin(), old_net_inflow.end(), 0.0);
1141 std::fill(old_lat_flow.begin(), old_lat_flow.end(), 0.0);
1142 std::fill(old_inflow.begin(), old_inflow.end(), 0.0);
1143 // coupling_inflow / coupling_volume / coupling_queue are NOT cleared by
1144 // clearInflowSources (coupling_volume and coupling_queue are the
1145 // carry-across-steps fields — their end-of-step values must persist into
1146 // the next step's assembly), so zero them explicitly on cold start.
1147 std::fill(coupling_inflow.begin(), coupling_inflow.end(), 0.0);
1148 std::fill(coupling_volume.begin(), coupling_volume.end(), 0.0);
1149 std::fill(coupling_queue.begin(), coupling_queue.end(), 0.0);
1150 std::fill(coupling_qual_queue.begin(), coupling_qual_queue.end(), 0.0);
1151 std::fill(coupling_qual_inflow.begin(), coupling_qual_inflow.end(), 0.0);
1152 std::fill(coupling_age_vol_queue.begin(), coupling_age_vol_queue.end(), 0.0);
1153 std::fill(coupling_temp_vol_queue.begin(), coupling_temp_vol_queue.end(), 0.0);
1154 std::fill(coupling_age_vol_inflow.begin(), coupling_age_vol_inflow.end(), 0.0);
1155 std::fill(coupling_temp_vol_inflow.begin(), coupling_temp_vol_inflow.end(), 0.0);
1157 std::fill(conc.begin(), conc.end(), 0.0);
1158 std::fill(conc_old.begin(), conc_old.end(), 0.0);
1159 (void)n;
1160 }
1161
1171 void clearInflowSources() noexcept {
1172 // runoff_inflow and gw_inflow: zeroed in stepRunoff() Phase 2
1173 std::fill(ext_inflow.begin(), ext_inflow.end(), 0.0);
1174 std::fill(dwf_inflow.begin(), dwf_inflow.end(), 0.0);
1175 std::fill(rdii_inflow.begin(), rdii_inflow.end(), 0.0);
1176 std::fill(iface_inflow.begin(), iface_inflow.end(), 0.0);
1177 std::fill(iface_qual_mass.begin(), iface_qual_mass.end(), 0.0);
1178 std::fill(ext_qual_mass.begin(), ext_qual_mass.end(), 0.0);
1179 std::fill(dwf_qual_mass.begin(), dwf_qual_mass.end(), 0.0);
1180 std::fill(qual_mass_in.begin(), qual_mass_in.end(), 0.0);
1181 std::fill(qual_vol_in.begin(), qual_vol_in.end(), 0.0);
1182 }
1183};
1184
1185} /* namespace openswmm */
1186
1187#endif /* OPENSWMM_ENGINE_NODE_DATA_HPP */
Definition NodeCoupling.cpp:16
StorageShape
Storage-unit surface-area relation.
Definition NodeData.hpp:104
@ CONICAL
Elliptical cone (p1, p2 = base axes, p3 = side slope)
Definition NodeData.hpp:108
@ PYRAMIDAL
Rectangular pyramid (p1 = length, p2 = width, p3 = side slope)
Definition NodeData.hpp:110
@ PARABOLOID
Elliptical paraboloid(p1, p2 = top axes, p3 = height ≠ 0)
Definition NodeData.hpp:109
@ CYLINDRICAL
Elliptical cylinder (p1 = major axis, p2 = minor axis)
Definition NodeData.hpp:107
@ FUNCTIONAL
Area = c + a*d^b.
Definition NodeData.hpp:106
@ STORAGE
Definition LidLayerSpeciesData.hpp:56
@ WEIR
Definition LinkData.hpp:62
OutfallType
Outfall boundary condition type.
Definition NodeData.hpp:70
@ NORMAL
Definition NodeData.hpp:72
@ FREE
Definition NodeData.hpp:71
@ FIXED
Definition NodeData.hpp:73
@ TIDAL
Definition NodeData.hpp:74
NodeType
Node type codes.
Definition NodeData.hpp:59
@ JUNCTION
Definition NodeData.hpp:60
@ DIVIDER
Definition NodeData.hpp:62
@ OUTFALL
Definition NodeData.hpp:61
DividerType
Flow divider type.
Definition NodeData.hpp:82
@ CUTOFF
Definition NodeData.hpp:83
@ TABULAR
Definition NodeData.hpp:85
@ OVERFLOW_DIV
Renamed from OVERFLOW to avoid macOS math.h macro collision.
Definition NodeData.hpp:84
@ TIMESERIES
Data from an in-file [TIMESERIES].
Definition GageData.hpp:58
Structure-of-Arrays storage for all nodes.
Definition NodeData.hpp:130
std::vector< double > coupling_inflow
2D ↔ 1D coupling exchange flow at the node (project flow units).
Definition NodeData.hpp:301
std::vector< double > stat_lat_inflow_vol
Definition NodeData.hpp:669
bool coupling_tuple_temp
Definition NodeData.hpp:370
int count() const noexcept
Number of nodes.
Definition NodeData.hpp:721
std::vector< double > depth
Current water depth above invert (project length units).
Definition NodeData.hpp:227
std::vector< double > invert_elev
Invert elevation (project length units).
Definition NodeData.hpp:143
std::vector< double > ext_inflow
External (timeseries/baseline) inflows (project flow units).
Definition NodeData.hpp:269
std::vector< double > conc_old
Previous-step quality at each node.
Definition NodeData.hpp:463
std::vector< double > iface_inflow
Interface file (upstream model coupling) inflows (project flow units).
Definition NodeData.hpp:278
std::vector< double > coupling_queue
Delivery queue for the 1D↔2D junction exchange (1D units, ft³).
Definition NodeData.hpp:334
std::vector< double > qual_mass_in
Accumulated quality mass inflow rate per (node, pollutant).
Definition NodeData.hpp:379
std::vector< double > stat_vol_flooded
Total volume of water lost as overflow (project volume units).
Definition NodeData.hpp:593
std::vector< double > stat_time_courant_critical
CFL time-step critical count per node.
Definition NodeData.hpp:705
std::vector< double > old_inflow
Total inflow at the previous timestep (for output interpolation).
Definition NodeData.hpp:547
void erase_at(int idx)
Erase the node at index idx from every parallel array.
Definition NodeData.hpp:920
std::vector< double > coupling_age_vol_inflow
Definition NodeData.hpp:367
std::vector< double > hrt
Hydraulic residence time for storage nodes (seconds).
Definition NodeData.hpp:466
std::vector< double > old_depth
Depth at the previous timestep.
Definition NodeData.hpp:535
void reset_state() noexcept
Reset state variables, applying init_depth from input.
Definition NodeData.hpp:1123
std::vector< double > qual_vol_in
Accumulated volume inflow rate per node (ft3/sec).
Definition NodeData.hpp:382
std::vector< double > coupling_volume
Pending 1D↔2D exchange VOLUME for the next routing step (1D units, ft³).
Definition NodeData.hpp:316
std::vector< double > old_volume
Volume at the previous timestep.
Definition NodeData.hpp:538
std::vector< double > stat_total_outflow_vol
Definition NodeData.hpp:676
std::vector< double > user_conc_mass_flux
User-forced quality mass flux at each node (mass/sec).
Definition NodeData.hpp:477
void reserve_to(int n)
Reserve capacity for n nodes without changing count().
Definition NodeData.hpp:886
std::vector< double > coupling_temp_vol_inflow
Definition NodeData.hpp:368
std::vector< double > coupling_age_vol_queue
S4 — the tuple's age-volume and temperature-volume halves, per node (age·ft³ / °C·ft³ queued; age·ft³...
Definition NodeData.hpp:365
bool coupling_tuple_age
set by SurfaceRouter2D at initialize
Definition NodeData.hpp:369
void shrink_to_fit()
Release excess vector capacity accumulated during parsing.
Definition NodeData.hpp:1022
std::vector< double > stat_max_surcharge_height
Definition NodeData.hpp:645
std::vector< double > stat_max_overflow
Maximum reported overflow rate (project flow units).
Definition NodeData.hpp:611
std::vector< char > rpt_flag
Whether this node is included in report/output (0=no, 1=yes).
Definition NodeData.hpp:583
std::vector< double > outflow
Current total outflow from the node (project flow units).
Definition NodeData.hpp:492
void clearInflowSources() noexcept
Zero routing-phase inflow source arrays.
Definition NodeData.hpp:1171
std::vector< double > dwf_qual_mass
Per-node DWF pollutant mass-rate ADJUSTMENT (mass/sec), net of the global default: row mass (q·patter...
Definition NodeData.hpp:417
std::vector< double > overflow
Current overflow / ponded flow (project flow units).
Definition NodeData.hpp:498
std::vector< double > old_net_inflow
Net inflow from previous timestep (inflow - outflow) for averaging.
Definition NodeData.hpp:522
std::vector< double > stat_storage_max_outflow
Definition NodeData.hpp:665
std::vector< uint8_t > is_virtual
Virtual-junction flag (0 = regular node, 1 = virtual junction).
Definition NodeData.hpp:178
std::vector< double > stat_max_depth_date
Definition NodeData.hpp:629
std::vector< double > stat_max_lat_inflow
Definition NodeData.hpp:655
std::vector< double > stat_outfall_max_flow
Outfall maximum flow (project flow units).
Definition NodeData.hpp:682
std::vector< double > volume
Current water volume (project volume units).
Definition NodeData.hpp:239
int conc_n_pollutants
Number of pollutants in the quality arrays.
Definition NodeData.hpp:480
std::vector< double > iface_qual_mass
Routing interface file quality mass rate per (node, pollutant) (mass/sec).
Definition NodeData.hpp:392
std::vector< double > lat_flow
Current lateral inflow (project flow units).
Definition NodeData.hpp:245
std::vector< double > ponded_area
Ponding area at the surface (sq project length units).
Definition NodeData.hpp:167
std::vector< double > stat_total_inflow_vol
Cumulative total inflow volume at each node (ft3).
Definition NodeData.hpp:672
std::vector< double > coupling_temp_vol_queue
Definition NodeData.hpp:366
std::vector< double > sur_depth
Maximum depth allowed at the node (ponding or surcharge limit).
Definition NodeData.hpp:161
std::vector< double > crown_elev
Crown elevation — top of highest connecting conduit (project length units).
Definition NodeData.hpp:510
std::vector< double > stat_max_inflow_date
Definition NodeData.hpp:637
std::vector< double > old_lat_flow
Lateral flow at the previous timestep.
Definition NodeData.hpp:541
std::vector< double > stat_outfall_avg_flow
Outfall cumulative average flow (flow units × reporting periods).
Definition NodeData.hpp:651
std::vector< double > inflow
Current total inflow to the node (project flow units).
Definition NodeData.hpp:486
void save_state() noexcept
Snapshot current state into old-step arrays before solving.
Definition NodeData.hpp:1104
std::vector< double > stat_time_surcharged
Definition NodeData.hpp:641
std::vector< double > stat_max_depth
Maximum reported depth (project length units).
Definition NodeData.hpp:605
std::vector< double > coupling_qual_queue
S3 — species MASS queue for the 2D→1D junction drain, per (node, pollutant), 1D mass units (conc × ft...
Definition NodeData.hpp:350
std::vector< long > stat_outfall_periods
Outfall number of non-zero flow periods.
Definition NodeData.hpp:688
void resize_loads(int n_pollutants)
Resize pollutant load arrays after pollutant count is known.
Definition NodeData.hpp:984
std::vector< double > conc
Current quality concentration at each node.
Definition NodeData.hpp:460
std::vector< double > ext_qual_mass
Direct external inflow quality mass rate per (node, pollutant) (mass/sec).
Definition NodeData.hpp:406
std::vector< int > degree
Node degree — number of connecting links (+ve downstream, -ve upstream terminal).
Definition NodeData.hpp:516
std::vector< uint8_t > is_inlet
Inlet-junction flag (0 = plain node, 1 = inlet junction).
Definition NodeData.hpp:190
std::vector< double > lid_drain_qual_vol
LID drain volume inflow rate per node (ft3/sec).
Definition NodeData.hpp:436
std::vector< double > runoff_inflow
Interpolated surface runoff from subcatchments (project flow units).
Definition NodeData.hpp:263
std::vector< double > rim_depth
Rendering-only rim (ground) depth above the invert, project length units. 0 = unset.
Definition NodeData.hpp:206
std::vector< double > dwf_inflow
Dry weather flow inflows (project flow units).
Definition NodeData.hpp:272
std::vector< double > stat_time_flooded
Total duration the node was flooded (seconds).
Definition NodeData.hpp:599
std::vector< std::string > tags
Per-object tag from the INP [TAGS] section.
Definition NodeData.hpp:575
std::vector< double > lid_drain_qual_load
LID drain quality mass rate per (node, pollutant) (mass/sec).
Definition NodeData.hpp:428
std::vector< double > stat_sum_volume
Definition NodeData.hpp:625
std::vector< double > stat_sum_depth
Definition NodeData.hpp:618
std::vector< double > stat_max_rpt_depth
Definition NodeData.hpp:633
std::vector< double > init_depth
Initial water depth (project length units).
Definition NodeData.hpp:155
std::vector< double > stat_total_load
Cumulative pollutant loads at each node.
Definition NodeData.hpp:713
void resize(int n)
Resize all arrays to hold exactly n nodes.
Definition NodeData.hpp:730
std::vector< double > coupling_qual_inflow
S3 — this step's delivered 2D→1D species mass RATE per (node, pollutant) (mass/sec); read by QualityS...
Definition NodeData.hpp:353
std::vector< int > stat_non_converged_count
Count of non-converging steps per node.
Definition NodeData.hpp:696
std::vector< double > full_volume
Full volume at node (project volume units).
Definition NodeData.hpp:528
std::vector< double > stat_max_overflow_date
Date/time when maximum overflow occurred (OADate (days since 12/30/1899)).
Definition NodeData.hpp:614
std::vector< std::string > comments
Object comment from the INP file (lines with a single ';' prefix immediately above this object's data...
Definition NodeData.hpp:562
std::vector< double > losses
Node losses (evaporation + seepage) (project flow units).
Definition NodeData.hpp:504
std::vector< double > lid_drain_inflow
LID drain WATER inflow rate per node (ft3/sec) — the routing twin of lid_drain_qual_vol.
Definition NodeData.hpp:449
void grow_to(int n)
Grow all arrays to hold at least n nodes, preserving existing data.
Definition NodeData.hpp:821
std::vector< NodeType > type
Node type for each node.
Definition NodeData.hpp:137
std::vector< double > full_depth
Full depth of the node (project length units).
Definition NodeData.hpp:149
std::vector< double > stat_max_total_inflow
Definition NodeData.hpp:659
std::vector< double > rdii_inflow
RDII unit hydrograph inflows (project flow units).
Definition NodeData.hpp:275
void resize_quality(int n_pollutants)
Resize per-node quality arrays after pollutant count is known.
Definition NodeData.hpp:996
std::vector< double > head
Current water surface head (project length units = invert + depth).
Definition NodeData.hpp:233
std::vector< double > gw_inflow
Interpolated groundwater flow from subcatchments (project flow units).
Definition NodeData.hpp:266
std::vector< double > user_lat_flow
User-forced lateral inflow set via the API (project flow units).
Definition NodeData.hpp:254
int stat_n_pollutants
Definition NodeData.hpp:714