Line data Source code
1 : // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 : // SPDX-License-Identifier: Apache-2.0
3 :
4 : #ifndef PALACE_MODELS_PORT_EXCITATION_MANAGER_HPP
5 : #define PALACE_MODELS_PORT_EXCITATION_MANAGER_HPP
6 :
7 : #include <algorithm>
8 : #include <map>
9 : #include <vector>
10 : #include <nlohmann/json_fwd.hpp>
11 :
12 : namespace palace
13 : {
14 : class LumpedPortOperator;
15 : class WavePortOperator;
16 : class SurfaceCurrentOperator;
17 :
18 : // Small helper class to collect data of what (lumped / wave / surface) ports are
19 : // excited in driven and transient simulation, as stored in space_op;
20 : // Manages indices.
21 :
22 : enum class PortType : std::uint8_t
23 : {
24 : LumpedPort = 0,
25 : WavePort = 1,
26 : CurrentPort = 2,
27 : Undefined = 3
28 : };
29 :
30 40 : class PortExcitations
31 : {
32 : public:
33 16 : struct SingleExcitationSpec
34 : {
35 : std::vector<int> lumped_port = {};
36 : std::vector<int> wave_port = {};
37 : std::vector<int> current_port = {};
38 :
39 : // TODO: C++20 to replace this with iterator over joined range.
40 : auto FlattenPortIndices() const
41 : {
42 : std::vector<int> out;
43 : out.insert(out.end(), lumped_port.cbegin(), lumped_port.cend());
44 : out.insert(out.end(), wave_port.cbegin(), wave_port.cend());
45 : out.insert(out.end(), current_port.cbegin(), current_port.cend());
46 : return out;
47 : }
48 :
49 : // Only a single port is excited.
50 5 : std::tuple<bool, PortType, int> IsSimple() const
51 : {
52 : auto n_lumped = lumped_port.size();
53 : auto n_wave = wave_port.size();
54 : auto n_current = current_port.size();
55 :
56 5 : if (n_lumped == 1 && n_wave == 0 && n_current == 0)
57 : {
58 : return std::make_tuple(true, PortType::LumpedPort, lumped_port.at(0));
59 : }
60 0 : else if (n_lumped == 0 && n_wave == 1 && n_current == 0)
61 : {
62 : return std::make_tuple(true, PortType::WavePort, wave_port.at(0));
63 : }
64 0 : else if (n_lumped == 0 && n_wave == 0 && n_current == 1)
65 : {
66 : return std::make_tuple(true, PortType::CurrentPort, current_port.at(0));
67 : }
68 : else
69 : {
70 : return std::make_tuple(false, PortType::Undefined, 0);
71 : }
72 : }
73 : };
74 :
75 : std::map<int, SingleExcitationSpec> excitations = {};
76 :
77 : auto begin() { return excitations.begin(); }
78 : auto end() { return excitations.end(); }
79 : auto begin() const { return excitations.begin(); }
80 : auto end() const { return excitations.end(); }
81 :
82 : PortExcitations(const LumpedPortOperator &lumped_port_op,
83 : const WavePortOperator &wave_port_op,
84 : const SurfaceCurrentOperator &surf_j_op);
85 :
86 : [[nodiscard]] int MaxIdx() const
87 : {
88 : // Map is stored order by key so max key is last item.
89 : return excitations.empty() ? 0 : std::next(std::rend(excitations))->first;
90 : }
91 : [[nodiscard]] auto Size() const { return excitations.size(); }
92 : [[nodiscard]] auto Empty() const { return excitations.empty(); }
93 :
94 : [[nodiscard]] std::string FmtLog() const;
95 :
96 : // Single Simple (only 1 port per excitation) Excitation.
97 : [[nodiscard]] std::tuple<bool, int, PortType, int> IsSingleSimple() const
98 : {
99 : if (Size() == 1)
100 : {
101 : const auto &[ex_idx, ex_spec] = *excitations.begin();
102 : const auto [is_simple, port_type, port_idx] = ex_spec.IsSimple();
103 : if (is_simple)
104 : {
105 : return std::make_tuple(true, ex_idx, port_type, port_idx);
106 : }
107 : }
108 : return std::make_tuple(false, 0, PortType::Undefined, 0);
109 : }
110 :
111 : // Multiple Simple (only 1 port per excitation) Excitation.
112 5 : [[nodiscard]] bool IsMultipleSimple() const
113 : {
114 : return std::all_of(excitations.begin(), excitations.end(),
115 5 : [](const auto &ex) { return std::get<0>(ex.second.IsSimple()); });
116 : }
117 : };
118 :
119 : void to_json(nlohmann::json &j, const PortExcitations::SingleExcitationSpec &p);
120 :
121 : void from_json(const nlohmann::json &j, PortExcitations::SingleExcitationSpec &p);
122 :
123 : void to_json(nlohmann::json &j, const PortExcitations &p);
124 :
125 : void from_json(const nlohmann::json &j, PortExcitations &p);
126 :
127 : } // namespace palace
128 :
129 : #endif // PALACE_MODELS_PORT_EXCITATION_MANAGER_HPP
|