OpenSWMM Engine  6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
Loading...
Searching...
No Matches
LinkData.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
39
40#ifndef OPENSWMM_ENGINE_LINK_DATA_HPP
41#define OPENSWMM_ENGINE_LINK_DATA_HPP
42
43#include <vector>
44#include <cstdint>
45#include <string>
46#include <algorithm>
47
48namespace openswmm {
49
50// ============================================================================
51// Link type enumerations
52// ============================================================================
53
58enum class LinkType : int8_t { CONDUIT = 0, PUMP = 1, ORIFICE = 2, WEIR = 3, OUTLET = 4 };
59
92
97enum class FlowClass : int8_t {
98 DRY = 0,
99 UP_DRY = 1,
105};
106
107// ============================================================================
108// LinkData — SoA layout
109// ============================================================================
110
119struct LinkData {
120
121 // -----------------------------------------------------------------------
122 // Static connectivity — set at parse time
123 // -----------------------------------------------------------------------
124
126 std::vector<LinkType> type;
127
132 std::vector<int> node1;
133
138 std::vector<int> node2;
139
144 std::vector<double> offset1;
145
150 std::vector<double> offset2;
151
156 std::vector<double> q0;
157
162 std::vector<double> q_limit;
163
164 // -----------------------------------------------------------------------
165 // Conduit-specific properties (valid when type[i] == CONDUIT)
166 // -----------------------------------------------------------------------
167
169 std::vector<XsectShape> xsect_shape;
170
172 std::vector<double> xsect_y_full;
173
175 std::vector<double> xsect_a_full;
176
178 std::vector<double> xsect_w_max;
179
195 std::vector<double> xsect_geom1;
196 std::vector<double> xsect_geom2;
197 std::vector<double> xsect_geom3;
198 std::vector<double> xsect_geom4;
199
204 std::vector<int> xsect_curve;
205
206 // Phase 6: conduit-config fields (roughness, length, slope, mod_length,
207 // barrels, beta, rough_factor, q_full, q_max) moved to ConduitData in
208 // LinkSubtypes.hpp — the relational link side-tables are the single store.
209
214 std::vector<double> xsect_r_full;
215
220 std::vector<double> xsect_s_full;
221
226 std::vector<double> xsect_s_max;
227
232 std::vector<double> xsect_y_bot;
233
238 std::vector<double> xsect_a_bot;
239
245 std::vector<double> xsect_s_bot;
246
251 std::vector<double> xsect_r_bot;
252
257 std::vector<double> xsect_yw_max;
258
264 std::vector<int> xsect_batch_shape;
265
270 std::vector<double> setting;
271
276 std::vector<double> target_setting;
277
286 std::vector<double> time_last_set;
287
292 std::vector<int> direction;
293
294 // -----------------------------------------------------------------------
295 // Pump-specific properties (valid when type[i] == PUMP)
296 // -----------------------------------------------------------------------
297
298 // Phase 6: pump-config fields (pump_curve, pump_init_state, pump_startup,
299 // pump_shutoff, pump_curve_type) moved to PumpData in LinkSubtypes.hpp.
300 // pump_curve_name stays on base (shared with outlet/conduit-IRREGULAR).
301
303 std::vector<std::string> pump_curve_name;
304
305 // -----------------------------------------------------------------------
306 // Conduit loss coefficients
307 // -----------------------------------------------------------------------
308
309 // Phase 6: conduit loss/seep/culvert + per-step state (loss_inlet,
310 // loss_outlet, loss_avg, seep_rate, evap_loss_rate, seep_loss_rate,
311 // culvert_code, normal_flow_limited, inlet_control) moved to ConduitData.
312 // has_flap_gate and dqdh stay on base (shared / multi-owner).
313
315 std::vector<uint8_t> has_flap_gate;
316
321 std::vector<double> dqdh;
322
323 // -----------------------------------------------------------------------
324 // Weir / Orifice / Outlet — shared geometric properties
325 // -----------------------------------------------------------------------
326
327 // Phase 6: weir/orifice/outlet config (crest_height, cd, param1, param2,
328 // orate) moved to OrificeData/WeirData/OutletData in LinkSubtypes.hpp.
329
330 // -----------------------------------------------------------------------
331 // State variables — updated each timestep
332 // -----------------------------------------------------------------------
333
338 std::vector<double> flow;
339
342 std::vector<double> kw_inflow;
343
348 std::vector<double> depth;
349
354 std::vector<double> volume;
355
363 std::vector<double> slot_volume;
364
365 // Slot-storage share statistics (FV slot program R0). All stay 0.0
366 // under the dynamic-wave router. The share of a link at an instant is
367 // slot_volume/volume; the run-level share is the ratio of the two
368 // time integrals below, never an average of instantaneous ratios.
369
371 std::vector<double> stat_slot_vol_dt;
373 std::vector<double> stat_vol_dt;
375 std::vector<double> stat_peak_slot_share;
377 std::vector<double> stat_time_slot_above;
378
383 std::vector<double> froude;
384
386 std::vector<FlowClass> flow_class;
387
389 std::vector<uint8_t> is_closed;
390
391 // Phase 6: full_state (per-step up/down full bitmask) moved to ConduitData.
392
393 // -----------------------------------------------------------------------
394 // Previous-step state
395 // -----------------------------------------------------------------------
396
398 std::vector<double> old_flow;
399
401 std::vector<double> old_depth;
402
404 std::vector<double> old_volume;
405
406 // -----------------------------------------------------------------------
407 // Per-link quality state — flat 2D: [link * n_pollutants + pollutant]
408 // -----------------------------------------------------------------------
409
415 std::vector<double> conc;
416
418 std::vector<double> conc_old;
419
422
423 // -----------------------------------------------------------------------
424 // Per-object INP comment
425 // -----------------------------------------------------------------------
426
432 std::vector<std::string> comments;
433
440 std::vector<std::string> tags;
441
442 // -----------------------------------------------------------------------
443 // Report flag — per-object output filter
444 // -----------------------------------------------------------------------
445
448 std::vector<char> rpt_flag;
449
450 // -----------------------------------------------------------------------
451 // Cumulative statistics
452 // -----------------------------------------------------------------------
453
458 std::vector<double> stat_vol_flow;
459
464 std::vector<double> stat_max_flow;
465
470 std::vector<double> stat_max_veloc;
471
476 std::vector<double> stat_max_filling;
477
482 std::vector<double> stat_time_surcharged;
483
490 static constexpr int N_FLOW_CLASSES = 7;
491 std::vector<double> stat_flow_class;
492 std::vector<double> stat_norm_ltd;
493 std::vector<double> stat_inlet_ctrl;
494
497 std::vector<double> stat_max_flow_date;
498
501 std::vector<double> stat_time_full_upstream;
502
505 std::vector<double> stat_time_full_dnstream;
506
509 std::vector<double> stat_time_full_both;
510
513 std::vector<double> stat_time_capacity_limited;
514
521 std::vector<double> stat_total_load;
523
524 // -----------------------------------------------------------------------
525 // Pump utilization statistics (valid when type[i] == PUMP)
526 // -----------------------------------------------------------------------
527
529 std::vector<int> stat_pump_cycles;
530
532 std::vector<double> stat_pump_on_time;
533
535 std::vector<double> stat_pump_volume;
536
542 std::vector<double> stat_pump_energy;
543 std::vector<double>
545 std::vector<long> stat_pump_periods;
546 std::vector<double> stat_pump_off_curve_low;
547 std::vector<double> stat_pump_off_curve_high;
548
550 std::vector<bool> stat_pump_was_on;
551
559 std::vector<long> stat_flow_turns;
560
567 std::vector<int> stat_flow_turn_sign;
568
575 std::vector<double> stat_time_courant_critical;
576
577 // -----------------------------------------------------------------------
578 // Conduit time step summary ([REPORT] LINK_STEPS; accumulated only when
579 // that option is on). Durations are simulated seconds; steps are seconds.
580 // DW: the CFL step the conduit allows; FV: the local step it took.
581 // -----------------------------------------------------------------------
582
584 static constexpr int N_LSTEP_BINS = 5;
585
586 std::vector<double> stat_lstep_min;
587 std::vector<double> stat_lstep_max;
588 std::vector<double> stat_lstep_dt_time;
589 std::vector<double> stat_lstep_time;
590 std::vector<double> stat_lstep_bin_time;
591 std::vector<long> stat_conv_steps;
592 std::vector<long> stat_conv_total;
593
604 static int lstep_bin(double dt, double rs) noexcept {
605 int b = 0;
606 double edge = 0.5 * rs;
607 while (b < N_LSTEP_BINS - 1 && dt <= edge) {
608 ++b;
609 edge *= 0.5;
610 }
611 return b;
612 }
613
626 void add_lstep_sample(int j, double dt, double dur, double rs) noexcept {
627 const auto u = static_cast<std::size_t>(j);
628 if (stat_lstep_time[u] <= 0.0 || dt < stat_lstep_min[u])
629 stat_lstep_min[u] = dt;
630 if (dt > stat_lstep_max[u])
631 stat_lstep_max[u] = dt;
632 stat_lstep_dt_time[u] += dt * dur;
633 stat_lstep_time[u] += dur;
634 stat_lstep_bin_time[u * N_LSTEP_BINS + static_cast<std::size_t>(lstep_bin(dt, rs))] += dur;
635 }
636
637 // -----------------------------------------------------------------------
638 // Capacity management
639 // -----------------------------------------------------------------------
640
646 int count() const noexcept { return static_cast<int>(type.size()); }
647
660 void resize(int n) {
661 const auto un = static_cast<std::size_t>(n);
662
663 type.assign(un, LinkType::CONDUIT);
664 node1.assign(un, -1);
665 node2.assign(un, -1);
666 offset1.assign(un, 0.0);
667 offset2.assign(un, 0.0);
668 q0.assign(un, 0.0);
669 q_limit.assign(un, 0.0);
670
672 xsect_y_full.assign(un, 0.0);
673 xsect_a_full.assign(un, 0.0);
674 xsect_w_max.assign(un, 0.0);
675 xsect_geom1.assign(un, 0.0);
676 xsect_geom2.assign(un, 0.0);
677 xsect_geom3.assign(un, 0.0);
678 xsect_geom4.assign(un, 0.0);
679 xsect_curve.assign(un, -1);
680 xsect_r_full.assign(un, 0.0);
681 xsect_s_full.assign(un, 0.0);
682 xsect_s_max.assign(un, 0.0);
683 xsect_y_bot.assign(un, 0.0);
684 xsect_a_bot.assign(un, 0.0);
685 xsect_s_bot.assign(un, 0.0);
686 xsect_r_bot.assign(un, 0.0);
687 xsect_yw_max.assign(un, 0.0);
688 xsect_batch_shape.assign(un, 0);
689 setting.assign(un, 1.0);
690 target_setting.assign(un, 1.0);
691 time_last_set.assign(un, 0.0);
692 direction.assign(un, 1);
693
694 has_flap_gate.assign(un, 0);
695 dqdh.assign(un, 0.0);
696 pump_curve_name.resize(un);
697
698 flow.assign(un, 0.0);
699 kw_inflow.assign(un, 0.0);
700 depth.assign(un, 0.0);
701 volume.assign(un, 0.0);
702 slot_volume.assign(un, 0.0);
703 stat_slot_vol_dt.assign(un, 0.0);
704 stat_vol_dt.assign(un, 0.0);
705 stat_peak_slot_share.assign(un, 0.0);
706 stat_time_slot_above.assign(un, 0.0);
707 froude.assign(un, 0.0);
708 flow_class.assign(un, FlowClass::DRY);
709 is_closed.assign(un, 0);
710 old_flow.assign(un, 0.0);
711 old_depth.assign(un, 0.0);
712 old_volume.assign(un, 0.0);
713
714 comments.assign(un, std::string{});
715 tags.assign(un, std::string{});
716
717 rpt_flag.assign(un, 0);
718
719 stat_vol_flow.assign(un, 0.0);
720 stat_max_flow.assign(un, 0.0);
721 stat_max_veloc.assign(un, 0.0);
722 stat_max_filling.assign(un, 0.0);
723 stat_time_surcharged.assign(un, 0.0);
724 stat_flow_class.assign(un * N_FLOW_CLASSES, 0.0);
725 stat_norm_ltd.assign(un, 0.0);
726 stat_inlet_ctrl.assign(un, 0.0);
727 stat_max_flow_date.assign(un, 0.0);
728 stat_time_full_upstream.assign(un, 0.0);
729 stat_time_full_dnstream.assign(un, 0.0);
730 stat_time_full_both.assign(un, 0.0);
731 stat_time_capacity_limited.assign(un, 0.0);
732 stat_pump_cycles.assign(un, 0);
733 stat_pump_on_time.assign(un, 0.0);
734 stat_pump_volume.assign(un, 0.0);
735 stat_pump_energy.assign(un, 0.0);
736 stat_pump_off_curve_high.assign(un, 0.0);
737 stat_pump_off_curve_low.assign(un, 0.0);
738 stat_pump_periods.assign(un, 0.0);
739 stat_pump_sum_flow.assign(un, 0.0);
740 stat_pump_was_on.assign(un, false);
741 stat_flow_turns.assign(un, 0L);
742 stat_flow_turn_sign.assign(un, 0);
743 stat_time_courant_critical.assign(un, 0.0);
744 stat_lstep_min.assign(un, 0.0);
745 stat_lstep_max.assign(un, 0.0);
746 stat_lstep_dt_time.assign(un, 0.0);
747 stat_lstep_time.assign(un, 0.0);
748 stat_lstep_bin_time.assign(un * N_LSTEP_BINS, 0.0);
749 stat_conv_steps.assign(un, 0L);
750 stat_conv_total.assign(un, 0L);
751 }
752
762 void grow_to(int n) {
763 if (n <= count())
764 return;
765 const auto un = static_cast<std::size_t>(n);
766 auto g = [&](auto& vec, auto def) { vec.resize(un, def); };
768 g(node1, -1);
769 g(node2, -1);
770 g(offset1, 0.0);
771 g(offset2, 0.0);
772 g(q0, 0.0);
773 g(q_limit, 0.0);
775 g(xsect_y_full, 0.0);
776 g(xsect_a_full, 0.0);
777 g(xsect_w_max, 0.0);
778 g(xsect_geom1, 0.0);
779 g(xsect_geom2, 0.0);
780 g(xsect_geom3, 0.0);
781 g(xsect_geom4, 0.0);
782 g(xsect_curve, -1);
783 g(xsect_r_full, 0.0);
784 g(xsect_s_full, 0.0);
785 g(xsect_s_max, 0.0);
786 g(xsect_y_bot, 0.0);
787 g(xsect_a_bot, 0.0);
788 g(xsect_s_bot, 0.0);
789 g(xsect_r_bot, 0.0);
790 g(xsect_yw_max, 0.0);
791 g(xsect_batch_shape, 0);
792 g(setting, 1.0);
793 g(target_setting, 1.0);
794 g(time_last_set, 0.0);
795 g(direction, 1);
796 g(has_flap_gate, uint8_t{0});
797 g(dqdh, 0.0);
798 pump_curve_name.resize(un);
799 g(flow, 0.0);
800 g(depth, 0.0);
801 g(volume, 0.0);
802 g(slot_volume, 0.0);
803 g(kw_inflow, 0.0);
804 g(stat_slot_vol_dt, 0.0);
805 g(stat_vol_dt, 0.0);
806 g(stat_peak_slot_share, 0.0);
807 g(stat_time_slot_above, 0.0);
808 g(froude, 0.0);
810 g(is_closed, uint8_t{0});
811 g(old_flow, 0.0);
812 g(old_depth, 0.0);
813 g(old_volume, 0.0);
814 comments.resize(un, std::string{});
815 tags.resize(un, std::string{});
816
817 g(rpt_flag, static_cast<char>(0));
818 g(stat_vol_flow, 0.0);
819 g(stat_max_flow, 0.0);
820 g(stat_max_veloc, 0.0);
821 g(stat_max_filling, 0.0);
822 g(stat_time_surcharged, 0.0);
823 g(stat_max_flow_date, 0.0);
826 g(stat_time_full_both, 0.0);
828 g(stat_pump_cycles, 0);
829 g(stat_pump_on_time, 0.0);
830 g(stat_pump_volume, 0.0);
831 g(stat_pump_energy, 0.0);
834 g(stat_pump_periods, 0.0);
835 g(stat_pump_sum_flow, 0.0);
836 g(stat_pump_was_on, false);
837 g(stat_flow_turns, 0L);
840 g(stat_lstep_min, 0.0);
841 g(stat_lstep_max, 0.0);
842 g(stat_lstep_dt_time, 0.0);
843 g(stat_lstep_time, 0.0);
844 g(stat_conv_steps, 0L);
845 g(stat_conv_total, 0L);
846 stat_lstep_bin_time.resize(un * N_LSTEP_BINS, 0.0);
847 g(stat_norm_ltd, 0.0);
848 g(stat_inlet_ctrl, 0.0);
849 // stat_flow_class is flat 2D [n * N_FLOW_CLASSES]
850 stat_flow_class.resize(un * N_FLOW_CLASSES, 0.0);
851 // Note: conc, conc_old handled by resize_quality()
852 // Note: stat_total_load handled by resize_loads()
853 }
854
876 void reserve_to(int n) {
877 if (n <= 0)
878 return;
879 const auto un = static_cast<std::size_t>(n);
880 if (type.capacity() >= un)
881 return;
882 auto r = [&](auto& vec) { vec.reserve(un); };
883 r(type);
884 r(node1);
885 r(node2);
886 r(offset1);
887 r(offset2);
888 r(q0);
889 r(q_limit);
890 r(xsect_shape);
891 r(xsect_y_full);
892 r(xsect_a_full);
893 r(xsect_w_max);
894 r(xsect_geom1);
895 r(xsect_geom2);
896 r(xsect_geom3);
897 r(xsect_geom4);
898 r(xsect_curve);
899 r(xsect_r_full);
900 r(xsect_s_full);
901 r(xsect_s_max);
902 r(xsect_y_bot);
903 r(xsect_a_bot);
904 r(xsect_s_bot);
905 r(xsect_r_bot);
906 r(xsect_yw_max);
908 r(setting);
910 r(time_last_set);
911 r(direction);
912 r(has_flap_gate);
913 r(dqdh);
914 r(flow);
915 r(kw_inflow);
916 r(depth);
917 r(volume);
918 r(froude);
919 r(flow_class);
920 r(is_closed);
921 r(old_flow);
922 r(old_depth);
923 r(old_volume);
924 r(rpt_flag);
925 r(stat_vol_flow);
926 r(stat_max_flow);
947 r(stat_norm_ltd);
950 r(comments);
951 r(tags);
959 stat_lstep_bin_time.reserve(un * N_LSTEP_BINS);
960 }
961
973 void erase_at(int idx) {
974 const auto ui = static_cast<std::size_t>(idx);
975 auto e = [&](auto& v) {
976 if (ui < v.size())
977 v.erase(v.begin() + static_cast<std::ptrdiff_t>(idx));
978 };
979
980 e(type);
981 e(node1);
982 e(node2);
983 e(offset1);
984 e(offset2);
985 e(q0);
986 e(q_limit);
987
988 e(xsect_shape);
989 e(xsect_y_full);
990 e(xsect_a_full);
991 e(xsect_w_max);
992 e(xsect_curve);
993 e(xsect_geom1);
994 e(xsect_geom2);
995 e(xsect_geom3);
996 e(xsect_geom4);
997 e(xsect_r_full);
998 e(xsect_s_full);
999 e(xsect_s_max);
1000 e(xsect_y_bot);
1001 e(xsect_a_bot);
1002 e(xsect_s_bot);
1003 e(xsect_r_bot);
1004 e(xsect_yw_max);
1006 e(setting);
1007 e(target_setting);
1008 e(direction);
1009
1010 e(pump_curve_name);
1011
1012 e(has_flap_gate);
1013 e(dqdh);
1014
1015 e(flow);
1016 e(depth);
1017 e(volume);
1018 e(froude);
1019 e(flow_class);
1020 e(is_closed);
1021 e(kw_inflow);
1022 e(old_flow);
1023 e(old_depth);
1024 e(old_volume);
1025 e(comments);
1026 e(tags);
1027 e(rpt_flag);
1028
1029 e(stat_vol_flow);
1030 e(stat_max_flow);
1031 e(stat_max_veloc);
1034 e(stat_norm_ltd);
1035 e(stat_inlet_ctrl);
1050 e(stat_flow_turns);
1053 e(stat_lstep_min);
1054 e(stat_lstep_max);
1056 e(stat_lstep_time);
1057 e(stat_conv_steps);
1058 e(stat_conv_total);
1059 {
1060 const auto base = ui * static_cast<std::size_t>(N_LSTEP_BINS);
1061 const auto end = base + static_cast<std::size_t>(N_LSTEP_BINS);
1062 if (end <= stat_lstep_bin_time.size())
1063 stat_lstep_bin_time.erase(
1064 stat_lstep_bin_time.begin() + static_cast<std::ptrdiff_t>(base),
1065 stat_lstep_bin_time.begin() + static_cast<std::ptrdiff_t>(end));
1066 }
1067
1068 // Flat 2D: stat_flow_class [link * N_FLOW_CLASSES + class]
1069 {
1070 const auto base = ui * static_cast<std::size_t>(N_FLOW_CLASSES);
1071 const auto end = base + static_cast<std::size_t>(N_FLOW_CLASSES);
1072 if (end <= stat_flow_class.size())
1073 stat_flow_class.erase(stat_flow_class.begin() + static_cast<std::ptrdiff_t>(base),
1074 stat_flow_class.begin() + static_cast<std::ptrdiff_t>(end));
1075 }
1076
1077 // Flat 2D quality arrays: [link * np + p]
1078 if (conc_n_pollutants > 0) {
1079 const auto np = static_cast<std::size_t>(conc_n_pollutants);
1080 const auto base = ui * np;
1081 auto erase2d = [&](auto& v) {
1082 if (base + np <= v.size())
1083 v.erase(v.begin() + static_cast<std::ptrdiff_t>(base),
1084 v.begin() + static_cast<std::ptrdiff_t>(base + np));
1085 };
1086 erase2d(conc);
1087 erase2d(conc_old);
1088 }
1089
1090 // Flat 2D stat load: [link * np + p]
1091 if (stat_n_pollutants > 0) {
1092 const auto np = static_cast<std::size_t>(stat_n_pollutants);
1093 const auto base = ui * np;
1094 if (base + np <= stat_total_load.size())
1095 stat_total_load.erase(stat_total_load.begin() + static_cast<std::ptrdiff_t>(base),
1096 stat_total_load.begin() +
1097 static_cast<std::ptrdiff_t>(base + np));
1098 }
1099 }
1100
1110 void resize_loads(int n_pollutants) {
1111 stat_n_pollutants = n_pollutants;
1112 if (n_pollutants > 0) {
1113 auto total = static_cast<std::size_t>(count()) * static_cast<std::size_t>(n_pollutants);
1114 stat_total_load.assign(total, 0.0);
1115 }
1116 }
1117
1128 void resize_quality(int n_pollutants) {
1129 conc_n_pollutants = n_pollutants;
1130 if (n_pollutants > 0) {
1131 auto total = static_cast<std::size_t>(count()) * static_cast<std::size_t>(n_pollutants);
1132 conc.assign(total, 0.0);
1133 conc_old.assign(total, 0.0);
1134 }
1135 }
1136
1141 type.shrink_to_fit();
1142 node1.shrink_to_fit();
1143 node2.shrink_to_fit();
1144 offset1.shrink_to_fit();
1145 offset2.shrink_to_fit();
1146 q0.shrink_to_fit();
1147 q_limit.shrink_to_fit();
1148
1149 xsect_shape.shrink_to_fit();
1150 xsect_y_full.shrink_to_fit();
1151 xsect_a_full.shrink_to_fit();
1152 xsect_w_max.shrink_to_fit();
1153 xsect_curve.shrink_to_fit();
1154 xsect_r_full.shrink_to_fit();
1155 xsect_s_full.shrink_to_fit();
1156 xsect_s_max.shrink_to_fit();
1157 xsect_y_bot.shrink_to_fit();
1158 xsect_a_bot.shrink_to_fit();
1159 xsect_s_bot.shrink_to_fit();
1160 xsect_r_bot.shrink_to_fit();
1161 xsect_yw_max.shrink_to_fit();
1162 xsect_batch_shape.shrink_to_fit();
1163 setting.shrink_to_fit();
1164 target_setting.shrink_to_fit();
1165 direction.shrink_to_fit();
1166
1167 has_flap_gate.shrink_to_fit();
1168 dqdh.shrink_to_fit();
1169 pump_curve_name.shrink_to_fit();
1170
1171 flow.shrink_to_fit();
1172 kw_inflow.shrink_to_fit();
1173 depth.shrink_to_fit();
1174 volume.shrink_to_fit();
1175 froude.shrink_to_fit();
1176 flow_class.shrink_to_fit();
1177 is_closed.shrink_to_fit();
1178 old_flow.shrink_to_fit();
1179 old_depth.shrink_to_fit();
1180 old_volume.shrink_to_fit();
1181 conc.shrink_to_fit();
1182 conc_old.shrink_to_fit();
1183
1184 comments.shrink_to_fit();
1185 tags.shrink_to_fit();
1186
1187 rpt_flag.shrink_to_fit();
1188
1189 stat_vol_flow.shrink_to_fit();
1190 stat_max_flow.shrink_to_fit();
1191 stat_max_veloc.shrink_to_fit();
1192 stat_max_filling.shrink_to_fit();
1193 stat_time_surcharged.shrink_to_fit();
1194 stat_flow_class.shrink_to_fit();
1195 stat_norm_ltd.shrink_to_fit();
1196 stat_inlet_ctrl.shrink_to_fit();
1197 stat_max_flow_date.shrink_to_fit();
1198 stat_time_full_upstream.shrink_to_fit();
1199 stat_time_full_dnstream.shrink_to_fit();
1200 stat_time_full_both.shrink_to_fit();
1201 stat_time_capacity_limited.shrink_to_fit();
1202 stat_pump_cycles.shrink_to_fit();
1203 stat_pump_on_time.shrink_to_fit();
1204 stat_pump_volume.shrink_to_fit();
1205 stat_pump_energy.shrink_to_fit();
1206 stat_pump_off_curve_high.shrink_to_fit();
1207 stat_pump_off_curve_low.shrink_to_fit();
1208 stat_pump_periods.shrink_to_fit();
1209 stat_pump_sum_flow.shrink_to_fit();
1210 stat_pump_was_on.shrink_to_fit();
1211 stat_total_load.shrink_to_fit();
1212 }
1213
1220 void save_state() noexcept {
1223 }
1224
1231 void save_hyd_state() noexcept {
1232 std::copy(flow.begin(), flow.end(), old_flow.begin());
1233 std::copy(depth.begin(), depth.end(), old_depth.begin());
1234 std::copy(volume.begin(), volume.end(), old_volume.begin());
1235 }
1236
1238 void save_qual_state() noexcept { std::copy(conc.begin(), conc.end(), conc_old.begin()); }
1239
1248 void reset_state() noexcept {
1249 std::fill(flow.begin(), flow.end(), 0.0);
1250 std::fill(kw_inflow.begin(), kw_inflow.end(), 0.0);
1251 std::fill(depth.begin(), depth.end(), 0.0);
1252 std::fill(volume.begin(), volume.end(), 0.0);
1253 std::fill(froude.begin(), froude.end(), 0.0);
1254 std::fill(flow_class.begin(), flow_class.end(), FlowClass::DRY);
1255 std::fill(old_flow.begin(), old_flow.end(), 0.0);
1256 std::fill(old_depth.begin(), old_depth.end(), 0.0);
1257 std::fill(old_volume.begin(), old_volume.end(), 0.0);
1258 std::fill(conc.begin(), conc.end(), 0.0);
1259 std::fill(conc_old.begin(), conc_old.end(), 0.0);
1260 }
1261};
1262
1263} /* namespace openswmm */
1264
1265#endif /* OPENSWMM_ENGINE_LINK_DATA_HPP */
Definition ExchangeLaw.hpp:60
LinkType
Link type codes.
Definition LinkData.hpp:58
@ CONDUIT
Definition LinkData.hpp:58
@ PUMP
Definition LinkData.hpp:58
@ WEIR
Definition LinkData.hpp:58
@ ORIFICE
Definition LinkData.hpp:58
@ OUTLET
Definition LinkData.hpp:58
FlowClass
Link flow state.
Definition LinkData.hpp:97
@ SUPERCRITICAL
Definition LinkData.hpp:102
@ DN_CRITICAL
Definition LinkData.hpp:104
@ SUBCRITICAL
Definition LinkData.hpp:101
@ UP_CRITICAL
Definition LinkData.hpp:103
@ DRY
Definition LinkData.hpp:98
@ UP_DRY
Definition LinkData.hpp:99
@ DN_DRY
Definition LinkData.hpp:100
XsectShape
Conduit cross-section shape code.
Definition LinkData.hpp:64
@ TRIANGULAR
Definition LinkData.hpp:70
@ RECT_CLOSED
Definition LinkData.hpp:67
@ ARCH
Arch pipe.
Definition LinkData.hpp:85
@ FORCE_MAIN
Circular force main (Hazen-Williams or D-W)
Definition LinkData.hpp:88
@ RECT_OPEN
Definition LinkData.hpp:68
@ BASKETHANDLE
Definition LinkData.hpp:79
@ STREET_XSECT
Street cross-section.
Definition LinkData.hpp:89
@ SEMICIRCULAR
Definition LinkData.hpp:80
@ IRREGULAR
User-supplied shape curve.
Definition LinkData.hpp:86
@ HORIZ_ELLIPSE
Horizontal elliptical pipe.
Definition LinkData.hpp:83
@ VERT_ELLIPSE
Vertical elliptical pipe.
Definition LinkData.hpp:84
@ CUSTOM
Shape from CURVE_SHAPE table.
Definition LinkData.hpp:87
@ RECT_ROUND
Rectangular-round bottom.
Definition LinkData.hpp:82
@ EGGSHAPED
Definition LinkData.hpp:74
@ SEMIELLIPTICAL
Definition LinkData.hpp:78
@ CATENARY
Definition LinkData.hpp:77
@ CIRCULAR
Definition LinkData.hpp:65
@ TRAPEZOIDAL
Definition LinkData.hpp:69
@ MODBASKETHANDLE
Definition LinkData.hpp:73
@ HORSESHOE
Definition LinkData.hpp:75
@ DUMMY
Dummy (no geometry)
Definition LinkData.hpp:90
@ PARABOLIC
Definition LinkData.hpp:71
@ POWER
Definition LinkData.hpp:72
@ RECT_TRIANG
Rectangular-triangular bottom.
Definition LinkData.hpp:81
@ FILLED_CIRCULAR
Definition LinkData.hpp:66
@ GOTHIC
Definition LinkData.hpp:76