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_UTILS_UNITS_HPP
5 : #define PALACE_UTILS_UNITS_HPP
6 :
7 : #include <algorithm>
8 : #include <array>
9 : #include <vector>
10 :
11 : #include "utils/constants.hpp"
12 :
13 : namespace palace
14 : {
15 :
16 : class Units
17 : {
18 : // Mesh unit length from config["Model"]["L0"] in [m]. Sets length of mesh coordinate.
19 : double L0_m;
20 :
21 : // Characteristic reference length [m] and time [ns] for (non)dimensionalization.
22 : // Note: In input, config["Model"]["Lc"] is measured in units of L0; here Lc_m is in [m].
23 : double Lc_m; // [m]
24 : double tc_ns; // [ns]
25 :
26 : // Characteristic reference magnetic field strength Hc² = 1 / (Zc * Lc²) A/m (with Ec =
27 : // Hc Zc). Yields Pc = Hc² Zc Lc² = 1 W. Precompute.
28 : double Hc;
29 :
30 : public:
31 : Units(double L0_, double Lc_)
32 67 : : L0_m(L0_), Lc_m(Lc_), tc_ns(1.0e9 * Lc_m / electromagnetics::c0_),
33 41 : Hc(1.0 / std::sqrt(electromagnetics::Z0_ * Lc_m * Lc_m)) {};
34 :
35 : // Return the mesh scaling factor in units L0 x [m] for mesh IO.
36 210 : double GetMeshLengthRelativeScale() const { return Lc_m / L0_m; }
37 :
38 : // Redimensionalize values for output. Outputs which depend on the fields assume a
39 : // characteristic reference magnetic field strength Hc such that Pc = 1 W, where Pc is the
40 : // characteristic reference power.
41 : enum class ValueType : std::uint8_t
42 : {
43 : TIME, // [ns]
44 : FREQUENCY, // [GHz]
45 : LENGTH, // [m]
46 : IMPEDANCE, // [Ω]
47 : INDUCTANCE, // [H] = [Ωs]
48 : CAPACITANCE, // [F] = [s/Ω]
49 : CONDUCTIVITY, // [S/m]
50 : VOLTAGE, // [V]
51 : CURRENT, // [A]
52 : POWER, // [W]
53 : ENERGY, // [J]
54 : FIELD_E, // [V/m]
55 : FIELD_D, // [C/m²] = [A⋅s/m²]
56 : FIELD_H, // [A/m]
57 : FIELD_B // [Wb/m²] = [V⋅s/m²]
58 : };
59 :
60 : // Helper class to essentially allow static_assert(false) in constexpr if branch.
61 : // static_assert(false) fixed as defect report for C++23 (P2593).
62 : template <ValueType T>
63 : struct always_false : std::false_type
64 : {
65 : };
66 :
67 : template <ValueType unit>
68 : double GetScaleFactor() const
69 : {
70 : if constexpr (unit == ValueType::TIME)
71 : {
72 29 : return tc_ns; // [ns]
73 : }
74 : else if constexpr (unit == ValueType::FREQUENCY)
75 : {
76 132 : return 1.0 / (2.0 * M_PI * tc_ns); // [GHz/rad]
77 : }
78 : else if constexpr (unit == ValueType::LENGTH)
79 : {
80 17280060 : return Lc_m; // [m]
81 : }
82 : else if constexpr (unit == ValueType::IMPEDANCE)
83 : {
84 : return electromagnetics::Z0_; // [Ω]
85 : }
86 : else if constexpr (unit == ValueType::INDUCTANCE)
87 : {
88 56 : return electromagnetics::mu0_ * Lc_m; // [H]
89 : }
90 : else if constexpr (unit == ValueType::CAPACITANCE)
91 : {
92 60 : return electromagnetics::epsilon0_ * Lc_m; // [F]
93 : }
94 : else if constexpr (unit == ValueType::CONDUCTIVITY)
95 : {
96 26 : return 1.0 / (electromagnetics::Z0_ * Lc_m); // [S/m]
97 : }
98 : else if constexpr (unit == ValueType::VOLTAGE)
99 : {
100 6168 : return Hc * electromagnetics::Z0_ * Lc_m; // [V]
101 : }
102 : else if constexpr (unit == ValueType::CURRENT)
103 : {
104 40 : return Hc * Lc_m; // [A]
105 : }
106 : else if constexpr (unit == ValueType::POWER)
107 : {
108 34 : return Hc * Hc * electromagnetics::Z0_ * Lc_m * Lc_m; // [W]
109 : }
110 : else if constexpr (unit == ValueType::ENERGY)
111 : {
112 106 : return Hc * Hc * electromagnetics::Z0_ * Lc_m * Lc_m * tc_ns; // [J]
113 : }
114 : else if constexpr (unit == ValueType::FIELD_E)
115 : {
116 8640026 : return Hc * electromagnetics::Z0_; // [V/m]
117 : }
118 : else if constexpr (unit == ValueType::FIELD_D)
119 : {
120 : return electromagnetics::epsilon0_ * Hc * electromagnetics::Z0_; // [C/m²]
121 : }
122 : else if constexpr (unit == ValueType::FIELD_H)
123 : {
124 : return Hc; // [A/m]
125 : }
126 : else if constexpr (unit == ValueType::FIELD_B)
127 : {
128 8640010 : return electromagnetics::mu0_ * Hc; // [Wb/m²]
129 : }
130 : else
131 : {
132 : static_assert(always_false<unit>::value, "ValueType unkown");
133 : }
134 : }
135 :
136 : template <ValueType unit, typename T>
137 : auto Dimensionalize(T value) const
138 : {
139 17280220 : return value * GetScaleFactor<unit>();
140 : }
141 :
142 : template <ValueType unit, typename T, std::size_t N>
143 : auto Dimensionalize(const std::array<T, N> &value) const
144 : {
145 2052 : auto out = value;
146 : std::transform(out.begin(), out.end(), out.begin(),
147 : [this](T v) { return Dimensionalize<unit>(v); });
148 : return out;
149 : }
150 :
151 : template <ValueType unit, typename T>
152 22 : auto Dimensionalize(const std::vector<T> &value) const
153 : {
154 22 : auto out = value;
155 : std::transform(out.begin(), out.end(), out.begin(),
156 : [this](T v) { return Dimensionalize<unit>(v); });
157 22 : return out;
158 : }
159 :
160 : template <ValueType unit, typename T>
161 : auto Nondimensionalize(T value) const
162 : {
163 27 : return value / GetScaleFactor<unit>();
164 : }
165 :
166 : template <ValueType unit, typename T, std::size_t N>
167 : auto Nondimensionalize(const std::array<T, N> &value) const
168 : {
169 0 : auto out = value;
170 : std::transform(out.begin(), out.end(), out.begin(),
171 : [this](T v) { return Nondimensionalize<unit>(v); });
172 : return out;
173 : }
174 :
175 : template <ValueType unit, typename T>
176 14 : auto Nondimensionalize(const std::vector<T> &value) const
177 : {
178 14 : auto out = value;
179 12 : std::transform(out.begin(), out.end(), out.begin(),
180 0 : [this](T v) { return Nondimensionalize<unit>(v); });
181 14 : return out;
182 : }
183 : };
184 :
185 : } // namespace palace
186 :
187 : #endif // PALACE_UTILS_UNITS_HPP
|