Line data Source code
1 : #ifndef UNIT_TEST_H
2 : #define UNIT_TEST_H
3 :
4 : #include "Util/Util.H"
5 : #include "Unit.H"
6 : #include <stdexcept>
7 :
8 : namespace UnitTest
9 : {
10 2 : int Equivalence(int verbose = 0)
11 : {
12 :
13 : std::vector<std::pair<std::string,std::string>> unit_tests = {
14 :
15 : // Length
16 : {"1_m", "1000_mm"},
17 : {"1_m", "1e9_nm"},
18 : {"1_cm", "10_mm"},
19 : {"1_km", "1000_m"},
20 : {"1_in", "0.0254_m"},
21 : {"1_ft", "0.3048_m"},
22 :
23 : // Area
24 : {"1_m^2", "1e6_mm^2"},
25 : {"1_cm^2", "100_mm^2"},
26 :
27 : // Volume
28 : {"1_m^3", "1e9_mm^3"},
29 : {"1_cm^3", "1000_mm^3"},
30 : {"1_L", "1e-3_m^3"},
31 : {"1_mL", "1e-6_m^3"},
32 : {"1_cc", "1e-6_m^3"},
33 :
34 : // Time
35 : {"1_s", "1000_ms"},
36 : {"1_s", "1e9_ns"},
37 : {"1_min", "60_s"},
38 : {"1_hr", "3600_s"},
39 :
40 : // Mass
41 : {"1_kg", "1000_g"},
42 : {"1_g", "1000_mg"},
43 : {"1_tonne", "1000_kg"},
44 : {"1_lb", "0.45359237_kg"},
45 : {"1_oz", "0.0283495_kg"},
46 :
47 : // Force
48 : {"1_N", "1_kg*m/s^2"},
49 : {"1_kN", "1000_N"},
50 : {"1_lbf", "4.44822162_N"},
51 :
52 : // Pressure
53 : {"1_Pa", "1_N/m^2"},
54 : {"1_kPa", "1000_Pa"},
55 : {"1_MPa", "1e6_Pa"},
56 : {"1_bar", "1e5_Pa"},
57 : {"1_psi", "6894.76_Pa"},
58 :
59 : // Energy
60 : {"1_J", "1_N*m"},
61 : {"1_mJ", "1e-3_J"},
62 : {"1_kJ", "1e3_J"},
63 : {"1_eV", "1.602176634e-19_J"},
64 :
65 : // Power
66 : {"1_W", "1_J/s"},
67 : {"1_kW", "1e3_W"},
68 : {"1_MW", "1e6_W"},
69 :
70 : // Mobility / Phase-field (example)
71 : {"1_m/Pa/s", "1e+3_mm/kPa/ms"},
72 : {"1_m^3/J/s", "1e+9_mm^3/kJ/ms"},
73 : {"1_m^3/Pa/s", "1e+9_mm^3/kPa/ms"},
74 :
75 : // Thermal
76 : {"1_W/m/K", "1e3_mW/m/K"}, // thermal conductivity
77 : {"1_m^2/s", "1e6_mm^2/s"}, // diffusivity
78 :
79 : // Velocity / Kinematics
80 : {"1_m/s", "1e3_mm/s"},
81 : {"1_m/s^2", "1e3_mm/s^2"},
82 : {"1_km/hr", "0.27777778_m/s"},
83 :
84 : // Frequency
85 : {"1_Hz", "1/s"},
86 : {"1_kHz", "1e3_Hz"},
87 : {"1_MHz", "1e6_Hz"},
88 :
89 : // Charge / Current
90 : {"1_C", "1_A*s"},
91 : {"1_mAh", "3.6_C"},
92 : {"1_A", "1_C/s"},
93 :
94 : // Pressure/Stress alternative forms
95 : {"1_Pa", "1_N/m^2"},
96 : {"1_N/m^2", "1_kg/m/s^2"},
97 :
98 : // Force / Energy conversions
99 : {"1_J", "1_kg*m^2/s^2"},
100 : {"1_N", "1_kg*m/s^2"},
101 :
102 : // Phase-field driving forces
103 : {"1_J/m^3", "1_Pa"}, // energy density = stress
104 : {"1_N/m^2", "1_Pa"},
105 :
106 : // Example: mobility, dimensionally correct
107 : {"1E-12_m/Pa/s", "1E-9_mm/kPa/ms"},
108 : {"1E-15_m^3/J/s", "1E-15_mm^3/J/ms"},
109 :
110 122 : };
111 :
112 :
113 2 : int fails = 0;
114 120 : for (auto unit_test : unit_tests)
115 : {
116 118 : Unit a=Unit::Less(), b = Unit::Less();
117 : try
118 : {
119 118 : a = Unit::Parse(unit_test.first);
120 : }
121 0 : catch(std::runtime_error &e)
122 : {
123 0 : if (verbose)
124 : {
125 0 : Util::Message(INFO,"Error parsing ", unit_test.first);
126 0 : Util::Message(INFO,e.what());
127 : }
128 0 : fails++;
129 0 : continue;
130 0 : }
131 : try
132 : {
133 118 : b = Unit::Parse(unit_test.second);
134 : }
135 0 : catch(std::runtime_error &e)
136 : {
137 0 : if (verbose)
138 : {
139 0 : Util::Message(INFO,"Error parsing ", unit_test.second);
140 0 : Util::Message(INFO,e.what());
141 : }
142 0 : fails++;
143 0 : continue;
144 0 : }
145 :
146 118 : if (! a.isType(b))
147 : {
148 0 : if (verbose)
149 : {
150 0 : Unit::Parse(unit_test.first,true);
151 0 : Unit::Parse(unit_test.second,true);
152 0 : Util::Message(INFO,unit_test.first," different type than ",unit_test.second);
153 0 : Util::Message(INFO," ",unit_test.first," ==> ",a);
154 0 : Util::Message(INFO," ",unit_test.second," ==> ",b);
155 : }
156 0 : fails++;
157 0 : continue;
158 : }
159 118 : if (fabs(a.normalized_value()-b.normalized_value()) > 1E-8)
160 : {
161 0 : if (verbose)
162 : {
163 0 : Unit::Parse(unit_test.first,true);
164 0 : Unit::Parse(unit_test.second,true);
165 0 : Util::Message(INFO,unit_test.first," resolved value does not match ",unit_test.second);
166 0 : Util::Message(INFO," ",unit_test.first," ==> ",a);
167 0 : Util::Message(INFO," ",unit_test.second," ==> ",b);
168 : }
169 0 : fails++;
170 0 : continue;
171 : }
172 118 : }
173 :
174 2 : return fails;
175 4 : }
176 : }
177 :
178 : #endif
|