Sequoia
Loading...
Searching...
No Matches
PhysicalValuesDetails.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2024. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
14
15namespace sequoia::physics
16{
17 template<class Space>
18 struct associated_displacement_space;
19
20 template<class Space>
21 struct is_associated_displacement_space : std::false_type {};
22
23 template<class Space>
25
26 template<class Space>
27 using is_associated_displacement_space_t = is_associated_displacement_space<Space>::type;
28
29 template<class Space>
30 inline constexpr bool is_associated_displacement_space_v{is_associated_displacement_space<Space>::value};
31
32 template<class T>
33 concept physical_unit = requires {
34 typename T::validator_type;
35 };
36
37 struct no_unit_t;
38
39 template<class... Ts>
40 struct composite_space;
41
42 template<physical_unit... Ts>
43 struct composite_unit;
44
45 template<class T>
46 struct reduction;
47}
48
49namespace sequoia::meta
50{
51 template<class T, class U>
52 requires (!std::is_same_v<T, U>)
53 struct type_comparator<maths::dual<T>, U> : std::bool_constant<type_name<T>() < type_name<U>()>
54 {};
55
56 template<class T, class U>
57 requires (!std::is_same_v<T, U>) && (!physics::is_associated_displacement_space_v<T>) && (!physics::is_associated_displacement_space_v<U>)
58 struct type_comparator<T, maths::dual<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
59 {};
60
61 template<class T, class U>
62 struct type_comparator<maths::dual<T>, maths::dual<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
63 {};
64
65 template<class T, class U>
66 requires (!maths::is_dual_v<U>)
67 struct type_comparator<physics::associated_displacement_space<T>, U> : std::bool_constant<type_name<T>() < type_name<U>()>
68 {};
69
70 template<class T, class U>
71 requires (!maths::is_dual_v<T>)
72 struct type_comparator<T, physics::associated_displacement_space<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
73 {};
74
75 template<class T, class U>
76 requires (!std::is_same_v<physics::associated_displacement_space<T>, U>) && (!physics::is_associated_displacement_space_v<U>)
77 struct type_comparator<physics::associated_displacement_space<T>, maths::dual<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
78 {};
79
80 template<class T, class U>
81 requires (!std::is_same_v<T, physics::associated_displacement_space<U>>)
82 struct type_comparator<maths::dual<T>, physics::associated_displacement_space<U>> : std::bool_constant<type_name<T>() < type_name<U>()>
83 {};
84
85 template<class T, class U>
86 requires (!std::is_same_v<physics::associated_displacement_space<T>, U>)
87 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, U>
88 : std::bool_constant<type_name<T>() < type_name<U>()>
89 {};
90
91 template<class T, class U>
92 requires (!std::is_same_v<T, physics::associated_displacement_space<U>>) && (!physics::is_associated_displacement_space_v<T>)
93 struct type_comparator<T, maths::dual<physics::associated_displacement_space<U>>>
94 : std::bool_constant<type_name<T>() < type_name<U>()>
95 {};
96
97 template<class T, class U>
98 struct type_comparator<physics::associated_displacement_space<T>, physics::associated_displacement_space<U>>
99 : std::bool_constant<type_name<T>() < type_name<U>()>
100 {};
101
102 template<class T, class U>
103 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, maths::dual<physics::associated_displacement_space<U>>>
104 : std::bool_constant<type_name<T>() < type_name<U>()>
105 {};
106
107 // Ordering is T, associated_displacement_space<T>, dual<T>, dual<associated_displacement_space<T>>
108 template<class T>
109 struct type_comparator<T, maths::dual<T>> : std::true_type
110 {};
111
112 template<class T>
113 struct type_comparator<maths::dual<T>, T> : std::false_type
114 {};
115
116 template<class T>
117 struct type_comparator<T, physics::associated_displacement_space<T>> : std::true_type
118 {};
119
120 template<class T>
121 struct type_comparator<physics::associated_displacement_space<T>, T> : std::false_type
122 {};
123
124 template<class T>
125 struct type_comparator<T, maths::dual<physics::associated_displacement_space<T>>> : std::true_type
126 {};
127
128 template<class T>
129 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, T> : std::false_type
130 {};
131
132 template<class T>
133 struct type_comparator<physics::associated_displacement_space<T>, maths::dual<T>> : std::true_type
134 {};
135
136 template<class T>
137 struct type_comparator<maths::dual<T>, physics::associated_displacement_space<T>> : std::false_type
138 {};
139
140 template<class T>
141 struct type_comparator<maths::dual<T>, maths::dual<physics::associated_displacement_space<T>>> : std::true_type
142 {};
143
144 template<class T>
145 struct type_comparator<maths::dual<physics::associated_displacement_space<T>>, maths::dual<T>> : std::false_type
146 {};
147}
148
149namespace sequoia::physics::impl
150{
151 using namespace maths;
152
153 template<class T, int I>
154 struct type_counter {};
155
157 template<class...>
158 struct count_and_combine;
159
160 template<class... Ts>
161 using count_and_combine_t = count_and_combine<Ts...>::type;
162
163 template<>
164 struct count_and_combine<direct_product<>>
165 {
166 using type = direct_product<>;
167 };
168
169 template<class T>
170 struct count_and_combine<T>
171 {
172 using type = direct_product<type_counter<T, 1>>;
173 };
174
175 template<class T>
176 struct count_and_combine<direct_product<T>>
177 {
178 using type = direct_product<type_counter<T, 1>>;
179 };
180
181 template<class T, class... Ts>
182 struct count_and_combine<direct_product<T, Ts...>>
183 {
184 using type = count_and_combine_t<direct_product<Ts...>, count_and_combine_t<T>>;
185 };
186
187 template<class T, class... Us, int... Is>
188 struct count_and_combine<direct_product<T>, direct_product<type_counter<Us, Is>...>>
189 {
190 using type = count_and_combine_t<T, direct_product<type_counter<Us, Is>...>>;
191 };
192
193 template<class T, class... Ts, class... Us, int... Is>
194 requires (sizeof...(Ts) > 0)
195 struct count_and_combine<direct_product<T, Ts...>, direct_product<type_counter<Us, Is>...>>
196 {
197 using type = count_and_combine_t<direct_product<Ts...>, count_and_combine_t<T, direct_product<type_counter<Us, Is>...>>>;
198 };
199
200 template<class S, class T, int I, class... Ts, int... Is>
201 requires (!is_direct_product_v<S> && !is_dual_v<S> && !std::is_same_v<S, T> && !std::is_same_v<S, associated_displacement_space<T>>)
202 struct count_and_combine<S, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
203 {
204 using type = direct_product<type_counter<S, 1>, type_counter<T, I>, type_counter<Ts, Is>...>;
205 };
206
207 template<class S, class T, int I, class... Ts, int... Is>
208 requires (!std::is_same_v<S, T> && !is_dual_v<T> && !is_associated_displacement_space_v<S> && !is_associated_displacement_space_v<T>)
209 struct count_and_combine<dual<S>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
210 {
211 using type = direct_product<type_counter<dual<S>, 1>, type_counter<T, I>, type_counter<Ts, Is>...>;
212 };
213
214 template<class T, int I, class... Ts, int... Is>
215 struct count_and_combine<T, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
216 {
217 using type = direct_product<type_counter<T, I+1>, type_counter<Ts, Is>...>;
218 };
219
220 template<class T, int I, class... Ts, int... Is>
221 struct count_and_combine<dual<T>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
222 {
223 using type = direct_product<type_counter<T, I-1>, type_counter<Ts, Is>...>;
224 };
225
227 template<class T, int I, class... Ts, int... Is>
228 struct count_and_combine<associated_displacement_space<T>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
229 {
230 using type = direct_product<type_counter<associated_displacement_space<T>, I+1>, type_counter<Ts, Is>...>;
231 };
232
234 template<class T, int I, class... Ts, int... Is>
235 struct count_and_combine<dual<associated_displacement_space<T>>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
236 {
237 using type = direct_product<type_counter<associated_displacement_space<T>, I-1>, type_counter<Ts, Is>...>;
238 };
239
241 template<class T, int I, class... Ts, int... Is>
242 struct count_and_combine<dual<T>, direct_product<type_counter<associated_displacement_space<T>, I>, type_counter<Ts, Is>...>>
243 {
244 using type = direct_product<type_counter<associated_displacement_space<T>, I-1>, type_counter<Ts, Is>...>;
245 };
246
248 template<class T, int I, class... Ts, int... Is>
249 struct count_and_combine<dual<associated_displacement_space<T>>, direct_product<type_counter<dual<T>, I>, type_counter<Ts, Is>...>>
250 {
251 using type = direct_product<type_counter<dual<associated_displacement_space<T>>, I+1>, type_counter<Ts, Is>...>;
252 };
253
257 template<class...>
258 struct unpack;
259
260 template<class... Ts>
261 using unpack_t = unpack<Ts...>::type;
262
263 template<class T, int I>
264 requires (I > 0)
265 struct unpack<type_counter<T, I>>
266 {
267 using type = unpack_t<type_counter<T, I - 1>, direct_product<T>>;
268 };
269
270 template<class T, int I>
271 requires (I < 0)
272 struct unpack<type_counter<T, I>>
273 {
274 using type = unpack_t<type_counter<T, I + 1>, direct_product<dual<T>>>;
275 };
276
277 template<class T, int I, class... Ts>
278 requires (I > 0)
279 struct unpack<type_counter<T, I>, direct_product<Ts...>>
280 {
281 using type = unpack_t<type_counter<T, I - 1>, direct_product<T, Ts...>>;
282 };
283
284 template<class T, int I, class... Ts>
285 requires (I < 0)
286 struct unpack<type_counter<T, I>, direct_product<Ts...>>
287 {
288 using type = unpack_t<type_counter<T, I + 1>, direct_product<dual<T>, Ts...>>;
289 };
290
291 template<class T, class... Ts>
292 struct unpack<type_counter<T, 0>, direct_product<Ts...>>
293 {
294 using type = direct_product<Ts...>;
295 };
296
298 template<class...>
299 struct reduce;
300
301 template<class... Ts>
302 using reduce_t = reduce<Ts...>::type;
303
304 template<vector_space T>
305 struct reduce<direct_product<type_counter<T, 0>>>
306 {
307 using type = direct_product<euclidean_vector_space<1, commutative_ring_type_of_t<T>>>;
308 };
309
310 template<convex_space T>
311 requires (!affine_space<T> && !vector_space<T>)
312 struct reduce<direct_product<type_counter<T, 0>>>
313 {
314 using type = direct_product<euclidean_half_space<commutative_ring_type_of_t<free_module_type_of_t<T>>>>;
315 };
316
317 template<class T, class... Ts, int... Is>
318 struct reduce<direct_product<type_counter<T, 0>, type_counter<Ts, Is>...>>
319 {
320 using type = reduce_t<direct_product<type_counter<Ts, Is>...>>;
321 };
322
323 template<class T, int I>
324 requires (I != 0)
325 struct reduce<direct_product<type_counter<T, I>>>
326 {
327 using type = unpack_t<type_counter<T, I>>;
328 };
329
330 template<class T, int I, class... Ts, int... Is>
331 requires (I != 0)
332 struct reduce<direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
333 {
334 using type = reduce_t<direct_product<type_counter<Ts, Is>...>, unpack_t<type_counter<T, I>>>;
335 };
336
337 template<class T, class... Ts, int... Is, class... Us>
338 struct reduce<direct_product<type_counter<T, 0>, type_counter<Ts, Is>...>, direct_product<Us...>>
339 {
340 using type = reduce_t<direct_product<type_counter<Ts, Is>...>, direct_product<Us...>>;
341 };
342
343 template<class T, int I, class... Ts, int... Is, class... Us>
344 requires (I != 0)
345 struct reduce<direct_product<type_counter<T, I>, type_counter<Ts, Is>...>, direct_product<Us...>>
346 {
347 using type = reduce_t<direct_product<type_counter<Ts, Is>...>, unpack_t<type_counter<T, I>, direct_product<Us...>>>;
348 };
349
350 template<class... Us>
351 struct reduce<direct_product<>, direct_product<Us...>>
352 {
353 using type = direct_product<Us...>;
354 };
355
356 template<physics::physical_unit T>
357 struct reduce<direct_product<type_counter<T, 0>>>
358 {
359 using type = direct_product<physics::no_unit_t>;
360 };
361
363 template<class, class>
364 struct simplify;
365
366 template<class T, class U>
367 using simplify_t = simplify<T, U>::type;
368
369 template<class... Ts, class... Us>
370 struct simplify<direct_product<Ts...>, direct_product<Us...>>
371 {
372 using type = reduction<reduce_t<count_and_combine_t<meta::merge_t<direct_product<Ts...>, direct_product<Us...>, meta::type_comparator>>>>;
373 };
374
375 template<class T>
376 struct to_composite_space;
377
378 template<convex_space... Ts>
379 struct to_composite_space<reduction<direct_product<Ts...>>>
380 {
381 using type = composite_space<Ts...>;
382 };
383
384 template<physical_unit... Ts>
385 struct to_composite_space<reduction<direct_product<Ts...>>>
386 {
387 using type = composite_unit<Ts...>;
388 };
389
390 template<class T>
391 struct to_composite_space<reduction<direct_product<T>>>
392 {
393 using type = T;
394 };
395
396 template<class T>
397 using to_composite_space_t = to_composite_space<T>::type;
398}
399
400namespace sequoia::maths
401{
402 template<convex_space... Ts>
403 struct dual_of<physics::composite_space<Ts...>>
404 {
405 using type = physics::composite_space<dual_of_t<Ts>...>;
406 };
407
408 template<physics::physical_unit... Ts>
409 struct dual_of<physics::composite_unit<Ts...>>
410 {
411 using type = physics::composite_unit<dual_of_t<Ts>...>;
412 };
413}
Abstractions pertaining to vector spaces, affine spaces and their generalizations.
Definition: PhysicalValuesDetails.hpp:33
Primary class template for defining duals.
Definition: Spaces.hpp:896
Definition: PhysicalValues.hpp:673
Definition: PhysicalValues.hpp:99
Definition: PhysicalValues.hpp:87
Definition: PhysicalValuesDetails.hpp:21
Definition: PhysicalValues.hpp:79
Definition: PhysicalValues.hpp:93