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 : count_and_combine<direct_product<Ts...>, count_and_combine_t<T>>
184 {};
185
186 template<class T, class... Us, int... Is>
187 struct count_and_combine<direct_product<T>, direct_product<type_counter<Us, Is>...>>
188 : count_and_combine<T, direct_product<type_counter<Us, Is>...>>
189 {};
190
191 template<class T, class... Ts, class... Us, int... Is>
192 requires (sizeof...(Ts) > 0)
193 struct count_and_combine<direct_product<T, Ts...>, direct_product<type_counter<Us, Is>...>>
194 : count_and_combine<direct_product<Ts...>, count_and_combine_t<T, direct_product<type_counter<Us, Is>...>>>
195 {};
196
197 template<class S, class T, int I, class... Ts, int... Is>
198 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>>)
199 struct count_and_combine<S, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
200 {
201 using type = direct_product<type_counter<S, 1>, type_counter<T, I>, type_counter<Ts, Is>...>;
202 };
203
204 template<class S, class T, int I, class... Ts, int... Is>
205 requires (!std::is_same_v<S, T> && !is_dual_v<T> && !is_associated_displacement_space_v<S> && !is_associated_displacement_space_v<T>)
206 struct count_and_combine<dual<S>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
207 {
208 using type = direct_product<type_counter<dual<S>, 1>, type_counter<T, I>, type_counter<Ts, Is>...>;
209 };
210
211 template<class T, int I, class... Ts, int... Is>
212 struct count_and_combine<T, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
213 {
214 using type = direct_product<type_counter<T, I+1>, type_counter<Ts, Is>...>;
215 };
216
217 template<class T, int I, class... Ts, int... Is>
218 struct count_and_combine<dual<T>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
219 {
220 using type = direct_product<type_counter<T, I-1>, type_counter<Ts, Is>...>;
221 };
222
224 template<class T, int I, class... Ts, int... Is>
225 struct count_and_combine<associated_displacement_space<T>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
226 {
227 using type = direct_product<type_counter<associated_displacement_space<T>, I+1>, type_counter<Ts, Is>...>;
228 };
229
231 template<class T, int I, class... Ts, int... Is>
232 struct count_and_combine<dual<associated_displacement_space<T>>, direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
233 {
234 using type = direct_product<type_counter<associated_displacement_space<T>, I-1>, type_counter<Ts, Is>...>;
235 };
236
238 template<class T, int I, class... Ts, int... Is>
239 struct count_and_combine<dual<T>, direct_product<type_counter<associated_displacement_space<T>, I>, type_counter<Ts, Is>...>>
240 {
241 using type = direct_product<type_counter<associated_displacement_space<T>, I-1>, type_counter<Ts, Is>...>;
242 };
243
245 template<class T, int I, class... Ts, int... Is>
246 struct count_and_combine<dual<associated_displacement_space<T>>, direct_product<type_counter<dual<T>, I>, type_counter<Ts, Is>...>>
247 {
248 using type = direct_product<type_counter<dual<associated_displacement_space<T>>, I+1>, type_counter<Ts, Is>...>;
249 };
250
254 template<class...>
255 struct unpack {};
256
257 template<class... Ts>
258 using unpack_t = unpack<Ts...>::type;
259
260 template<class T, int I>
261 requires (I > 0)
262 struct unpack<type_counter<T, I>> : unpack<type_counter<T, I - 1>, direct_product<T>>
263 {};
264
265 template<class T, int I>
266 requires (I < 0)
267 struct unpack<type_counter<T, I>> : unpack<type_counter<T, I + 1>, direct_product<dual<T>>>
268 {};
269
270 template<class T, int I, class... Ts>
271 requires (I > 0)
272 struct unpack<type_counter<T, I>, direct_product<Ts...>> : unpack<type_counter<T, I - 1>, direct_product<T, Ts...>>
273 {};
274
275 template<class T, int I, class... Ts>
276 requires (I < 0)
277 struct unpack<type_counter<T, I>, direct_product<Ts...>> : unpack<type_counter<T, I + 1>, direct_product<dual<T>, Ts...>>
278 {};
279
280 template<class T, class... Ts>
281 struct unpack<type_counter<T, 0>, direct_product<Ts...>>
282 {
283 using type = direct_product<Ts...>;
284 };
285
287 template<class...>
288 struct reduce;
289
290 template<class... Ts>
291 using reduce_t = reduce<Ts...>::type;
292
293 template<vector_space T>
294 struct reduce<direct_product<type_counter<T, 0>>>
295 {
296 using arena_type = T::arena_type;
297 using type = direct_product<euclidean_vector_space<commutative_ring_type_of_t<T>, 1, arena_type>>;
298 };
299
300 template<convex_space T>
301 requires (!affine_space<T> && !vector_space<T>)
302 struct reduce<direct_product<type_counter<T, 0>>>
303 {
304 using arena_type = T::arena_type;
305 using type = direct_product<euclidean_half_space<commutative_ring_type_of_t<free_module_type_of_t<T>>, arena_type>>;
306 };
307
308 template<class T, class... Ts, int... Is>
309 struct reduce<direct_product<type_counter<T, 0>, type_counter<Ts, Is>...>>
310 : reduce<direct_product<type_counter<Ts, Is>...>>
311 {};
312
313 template<class T, int I>
314 requires (I != 0)
315 struct reduce<direct_product<type_counter<T, I>>>
316 {
317 using type = unpack_t<type_counter<T, I>>;
318 };
319
320 template<class T, int I, class... Ts, int... Is>
321 requires (I != 0)
322 struct reduce<direct_product<type_counter<T, I>, type_counter<Ts, Is>...>>
323 : reduce<direct_product<type_counter<Ts, Is>...>, unpack_t<type_counter<T, I>>>
324 {};
325
326 template<class T, class... Ts, int... Is, class... Us>
327 struct reduce<direct_product<type_counter<T, 0>, type_counter<Ts, Is>...>, direct_product<Us...>>
328 : reduce<direct_product<type_counter<Ts, Is>...>, direct_product<Us...>>
329 {};
330
331 template<class T, int I, class... Ts, int... Is, class... Us>
332 requires (I != 0)
333 struct reduce<direct_product<type_counter<T, I>, type_counter<Ts, Is>...>, direct_product<Us...>>
334 : reduce<direct_product<type_counter<Ts, Is>...>, unpack_t<type_counter<T, I>, direct_product<Us...>>>
335 {};
336
337 template<class... Us>
338 struct reduce<direct_product<>, direct_product<Us...>>
339 {
340 using type = direct_product<Us...>;
341 };
342
343 template<physics::physical_unit T>
344 struct reduce<direct_product<type_counter<T, 0>>>
345 {
346 using type = direct_product<physics::no_unit_t>;
347 };
348
350 template<class, class>
351 struct simplify;
352
353 template<class T, class U>
354 using simplify_t = simplify<T, U>::type;
355
356 template<class... Ts, class... Us>
357 struct simplify<direct_product<Ts...>, direct_product<Us...>>
358 {
359 using type = reduction<reduce_t<count_and_combine_t<meta::merge_t<direct_product<Ts...>, direct_product<Us...>, meta::type_comparator>>>>;
360 };
361
362 template<class T>
363 struct to_composite_space;
364
365 template<convex_space... Ts>
366 struct to_composite_space<reduction<direct_product<Ts...>>>
367 {
368 using type = composite_space<Ts...>;
369 };
370
371 template<physical_unit... Ts>
372 struct to_composite_space<reduction<direct_product<Ts...>>>
373 {
374 using type = composite_unit<Ts...>;
375 };
376
377 template<class T>
378 struct to_composite_space<reduction<direct_product<T>>>
379 {
380 using type = T;
381 };
382
383 template<class T>
384 using to_composite_space_t = to_composite_space<T>::type;
385}
386
387namespace sequoia::maths
388{
389 template<convex_space... Ts>
390 struct dual_of<physics::composite_space<Ts...>>
391 {
392 using type = physics::composite_space<dual_of_t<Ts>...>;
393 };
394
395 template<physics::physical_unit... Ts>
396 struct dual_of<physics::composite_unit<Ts...>>
397 {
398 using type = physics::composite_unit<dual_of_t<Ts>...>;
399 };
400}
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:690
Definition: PhysicalValues.hpp:131
Definition: PhysicalValues.hpp:87
Definition: PhysicalValuesDetails.hpp:21
Definition: PhysicalValues.hpp:79
Definition: PhysicalValues.hpp:125