Sequoia
Loading...
Searching...
No Matches
PhysicalValues.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
13
14namespace sequoia::physics
15{
16 template<physical_unit T>
17 struct is_invertible_unit : std::false_type {};
18
19 template<physical_unit T>
20 requires std::is_same_v<typename T::validator_type, std::identity>
21 || std::is_same_v<typename T::validator_type, maths::half_line_validator>
22 struct is_invertible_unit<T> : std::true_type
23 {};
24
25 template<physical_unit T>
26 using is_invertible_unit_t = is_invertible_unit<T>::type;
27
28 template<physical_unit T>
29 inline constexpr bool is_invertible_unit_v{is_invertible_unit<T>::value};
30}
31
32namespace sequoia::maths
33{
34 template<physics::physical_unit T>
35 requires physics::is_invertible_unit_v<T>
36 struct dual<T>
37 {
38 using validator_type = T::validator_type;
39 };
40
48 template<physics::physical_unit T>
49 requires (!physics::is_invertible_unit_v<T>)
50 struct dual<T>
51 {
52 using validator_type = void;
53 };
54}
55
56namespace sequoia::physics
57{
58 using namespace maths;
59
60 template<class... Ts>
62
63 template<class... Ts>
64 using reduced_validator_t = reduced_validator<Ts...>::type;
65
66 template<class T>
68 {
69 using type = T;
70 };
71
72 template<class T, class... Us>
73 struct reduced_validator<T, Us...>
74 {
75 using type = reduced_validator_t<T, reduced_validator_t<Us...>>;
76 };
77
78 struct no_unit_t
79 {
81 };
82
83 inline constexpr no_unit_t no_unit{};
84
85 template<physical_unit... Ts>
87 {
88 using validator_type = reduced_validator_t<typename Ts::validator_type...>;
89 };
90
92 template<class T>
93 struct reduction;
94
95 template<class T>
96 using reduction_t = reduction<T>::type;
97
98 template<class... Ts>
100
101 template<convex_space... Ts>
102 requires (free_module<Ts> || ...)
103 struct composite_space<Ts...>
104 {
105 using direct_product_t = direct_product<Ts...>;
107 using commutative_ring_type = commutative_ring_type_of_t<direct_product_t>;
108 constexpr static std::size_t dimension{std::ranges::max({dimension_of<Ts>...})};
109 using is_free_module = std::true_type;
110 };
111
112 template<convex_space... Ts>
113 requires (!affine_space<Ts> && ...)
114 struct composite_space<Ts...>
115 {
116 using direct_product_t = direct_product<Ts...>;
118 using free_module_type = composite_space<free_module_type_of_t<Ts>...>;
119 using is_convex_space = std::true_type;
120 };
121
122 template<physical_unit T, physical_unit U>
124 {
125 using type = impl::simplify_t<direct_product<T>, direct_product<U>>;
126 };
127
128 template<physical_unit... Ts, physical_unit U>
130 {
131 using type = impl::simplify_t<direct_product<Ts...>, direct_product<U>>;
132 };
133
134 template<physical_unit T, physical_unit... Us>
136 {
137 using type = impl::simplify_t<direct_product<Us...>, direct_product<T>>;
138 };
139
140 template<physical_unit... Ts, physical_unit... Us>
142 {
143 using type = impl::simplify_t<direct_product<Ts...>, direct_product<Us...>>;
144 };
145
146 template<convex_space T, convex_space U>
147 struct reduction<direct_product<T, U>>
148 {
149 using type = impl::simplify_t<direct_product<T>, direct_product<U>>;
150 };
151
152 template<convex_space... Ts, convex_space U>
154 {
155 using type = impl::simplify_t<direct_product<Ts...>, direct_product<U>>;
156 };
157
158 template<convex_space T, convex_space... Us>
160 {
161 using type = impl::simplify_t<direct_product<Us...>, direct_product<T>>;
162 };
163
164 template<convex_space... Ts, convex_space... Us>
166 {
167 using type = impl::simplify_t<direct_product<Ts...>, direct_product<Us...>>;
168 };
169
170 template<std::size_t D>
172
173 template<>
175 {
176 constexpr static std::size_t dimension{1};
177 };
178
179 template<std::size_t D>
180 requires (D > 1)
182 {
183 constexpr static std::size_t dimension{D};
184 };
185
187 {
188 constexpr static std::size_t dimension{2};
189 };
190
192 {
193 constexpr static std::size_t dimension{3};
194 };
195
196
197 template<free_module FreeModule, class Unit, class Convention>
199 {
200 using free_module_type = FreeModule;
201 using unit_type = Unit;
202 using convention_type = Convention;
203 };
204
205 template<class T>
206 struct reduced_validator<T, std::identity>
207 {
208 using type = std::identity;
209 };
210
211 template<class T>
212 requires (!std::is_same_v<T, std::identity>)
214 {
215 using type = std::identity;
216 };
217
218 template<>
220 {
222 };
223
224 template<convex_space ValueSpace, physical_unit Unit, class Convention>
227
228 template<convex_space ValueSpace, physical_unit Unit>
229 inline constexpr bool has_distinguished_origin{
230 free_module<ValueSpace>
231 || (!affine_space<ValueSpace> && defines_half_line_v<typename Unit::validator_type>)
232 };
233
234 template<convex_space ValueSpace, physical_unit Unit, class Origin>
235 inline constexpr bool has_consistent_origin{
236 ( has_distinguished_origin<ValueSpace, Unit> && std::is_same_v<Origin, distinguished_origin>)
237 || (!has_distinguished_origin<ValueSpace, Unit> && !std::is_same_v<Origin, distinguished_origin>)
238 };
239
240 template<convex_space ValueSpace, validator_for<ValueSpace> Validator>
241 inline constexpr bool has_consistent_validator{
242 !affine_space<ValueSpace> || std::is_same_v<Validator, std::identity>
243 };
244
245 template<convex_space ValueSpace, physical_unit Unit>
246 inline constexpr bool has_consistent_unit{
247 !is_dual_v<Unit> || vector_space<ValueSpace> || (!affine_space<ValueSpace> && is_invertible_unit_v<dual_of_t<Unit>>)
248 };
249
250 template<convex_space ValueSpace, physical_unit Unit, class Convention, class Origin, validator_for<ValueSpace> Validator>
251 requires has_consistent_unit<ValueSpace, Unit>
252 && has_consistent_validator<ValueSpace, Validator>
253 && has_consistent_origin<ValueSpace, Unit, Origin>
254 class physical_value;
255
256 template<physical_unit Unit>
258
259 template<affine_space T>
261
262 template<convex_space ValueSpace, physical_unit Unit>
264
265 template<convex_space ValueSpace, physical_unit Unit>
266 requires (!has_distinguished_origin<ValueSpace, Unit>) && (!affine_space<ValueSpace>)
267 struct to_origin_type<ValueSpace, Unit>
268 {
270 };
271
272 template<convex_space ValueSpace, physical_unit Unit>
273 using to_origin_type_t = to_origin_type<ValueSpace, Unit>::type;
274
275 template<convex_space ValueSpace, physical_unit Unit>
276 requires has_distinguished_origin<ValueSpace, Unit>
277 struct to_origin_type<ValueSpace, Unit>
278 {
279 using type = distinguished_origin;
280 };
281
282 template<convex_space ValueSpace, physical_unit Unit>
283 requires (!has_distinguished_origin<ValueSpace, Unit> && affine_space<ValueSpace>)
284 struct to_origin_type<ValueSpace, Unit>
285 {
286 using type = implicit_affine_origin<ValueSpace>;
287 };
288
289 template<convex_space ValueSpace, physical_unit Unit, class Convention, class Origin, class Validator>
290 using to_coordinates_base_type
291 = coordinates_base<
292 ValueSpace,
293 to_displacement_basis_t<ValueSpace, Unit, Convention>,
294 Origin,
295 Validator,
296 physical_value<free_module_type_of_t<ValueSpace>, Unit, Convention, distinguished_origin, std::identity>>;
297
298 template<convex_space T>
299 inline constexpr bool has_base_space_v{
300 requires { typename T::base_space; }
301 };
302
303 template<convex_space T>
305 {
306 using type = T;
307 };
308
309 template<convex_space T>
310 using to_base_space_t = to_base_space<T>::type;
311
312 template<convex_space T>
313 requires has_base_space_v<T>
315 {
316 using type = T::base_space;
317 };
318
319 template<convex_space T>
321 {
322 using type = dual<T>;
323 };
324
325 template<convex_space T>
326 requires has_base_space_v<T>
327 struct to_base_space<dual<T>>
328 {
329 using type = dual<typename T::base_space>;
330 };
331
332 template<convex_space... Ts>
334 {
335 using sorted_direct_product_t = meta::stable_sort_t<direct_product<to_base_space_t<Ts>...>, meta::type_comparator>;
336 using type = impl::to_composite_space_t<reduction<impl::reduce_t<impl::count_and_combine_t<sorted_direct_product_t>>>>;
337 };
338
339 template<convex_space T, convex_space U>
340 inline constexpr bool have_compatible_base_spaces_v{
341 has_base_space_v<T> && has_base_space_v<U> && (free_module_type_of_t<T>::dimension == free_module_type_of_t<U>::dimension) && requires {
342 typename std::common_type<typename T::base_space, typename U::base_space>::type;
343 }
344 };
345
346 template<convex_space T, convex_space U>
348
349 template<convex_space T, convex_space U>
350 using to_displacement_space_t = to_displacement_space<T, U>::type;
351
352 template<convex_space T>
354 {
355 using type = free_module_type_of_t<T>;
356 };
357
358 template<convex_space T, convex_space U>
359 requires (!std::is_same_v<T, U>) && have_compatible_base_spaces_v<T, U>
361 {
362 using type = free_module_type_of_t<std::common_type_t<typename T::base_space, typename U::base_space>>;
363 };
364
365 template<class T, class U>
367
368 template<class T, class U>
369 using physical_value_product_t = physical_value_product<T, U>::type;
370
371 template<
372 convex_space LHSValueSpace, physical_unit LHSUnit, class LHSConvention, class LHSValidator,
373 convex_space RHSValueSpace, physical_unit RHSUnit, class RHSConvention, class RHSValidator
374 >
375 requires std::common_with<LHSConvention, RHSConvention>
376 struct physical_value_product<physical_value<LHSValueSpace, LHSUnit, LHSConvention, distinguished_origin, LHSValidator>,
377 physical_value<RHSValueSpace, RHSUnit, RHSConvention, distinguished_origin, RHSValidator>>
378 {
379 using type
381 impl::to_composite_space_t<reduction_t<direct_product<LHSValueSpace, RHSValueSpace>>>,
382 impl::to_composite_space_t<reduction_t<direct_product<LHSUnit, RHSUnit>>>,
383 std::common_type_t<LHSConvention, RHSConvention>,
385 reduced_validator_t<LHSValidator, RHSValidator>
386 >;
387 };
388
389 template<
390 convex_space LHSValueSpace, physical_unit LHSUnit, class LHSConvention, class LHSValidator,
391 convex_space RHSValueSpace, physical_unit RHSUnit, class RHSConvention, class RHSValidator
392 >
393 requires std::common_with<LHSConvention, RHSConvention>
394 && ( std::is_same_v<euclidean_vector_space<1, commutative_ring_type_of_t<LHSValueSpace>>, LHSValueSpace>
395 || std::is_same_v<euclidean_half_space<commutative_ring_type_of_t<LHSValueSpace>>, LHSValueSpace>)
398 {
399 using type
401 RHSValueSpace,
402 RHSUnit,
403 std::common_type_t<LHSConvention, RHSConvention>,
405 reduced_validator_t<LHSValidator, RHSValidator>
406 >;
407 };
408
409 template<
410 convex_space LHSValueSpace, physical_unit LHSUnit, class LHSConvention, class LHSValidator,
411 convex_space RHSValueSpace, physical_unit RHSUnit, class RHSConvention, class RHSValidator
412 >
413 requires std::common_with<LHSConvention, RHSConvention>
414 && ( std::is_same_v<euclidean_vector_space<1, commutative_ring_type_of_t<RHSValueSpace>>, RHSValueSpace>
415 || std::is_same_v<euclidean_half_space<commutative_ring_type_of_t<RHSValueSpace>>, RHSValueSpace>)
416 struct physical_value_product<physical_value<LHSValueSpace, LHSUnit, LHSConvention, distinguished_origin, LHSValidator>,
417 physical_value<RHSValueSpace, RHSUnit, RHSConvention, distinguished_origin, RHSValidator>>
418 {
419 using type
420 = physical_value<
421 LHSValueSpace,
422 LHSUnit,
423 std::common_type_t<LHSConvention, RHSConvention>,
424 distinguished_origin,
425 reduced_validator_t<LHSValidator, RHSValidator>
426 >;
427 };
428
429 template<
430 convex_space ValueSpace,
431 physical_unit Unit,
432 class Convention = canonical_convention<free_module_type_of_t<ValueSpace>::dimension>,
433 class Origin = to_origin_type_t<ValueSpace, Unit>,
434 validator_for<ValueSpace> Validator = typename Unit::validator_type
435 >
436 requires has_consistent_unit<ValueSpace, Unit>
437 && has_consistent_validator<ValueSpace, Validator>
438 && has_consistent_origin<ValueSpace, Unit, Origin>
439 class physical_value final : public to_coordinates_base_type<ValueSpace, Unit, Convention, Origin, Validator>
440 {
441 public:
443 using space_type = ValueSpace;
444 using units_type = Unit;
445 using convention_type = Convention;
446 using origin_type = Origin;
447 using displacement_space_type = free_module_type_of_t<ValueSpace>;
448 using intrinsic_validator_type = Unit::validator_type;
449 using validator_type = Validator;
450 using ring_type = commutative_ring_type_of_t<ValueSpace>;
451 using value_type = ring_type;
452 using displacement_type = coordinates_type::displacement_coordinates_type;
453
454 constexpr static std::size_t dimension{displacement_space_type::dimension};
455 constexpr static std::size_t D{dimension};
456
457 constexpr static bool is_intrinsically_absolute{
458 (D == 1) && !affine_space<space_type> && defines_half_line_v<intrinsic_validator_type>
459 };
460
461 constexpr static bool is_effectively_absolute{is_intrinsically_absolute && std::is_same_v<Validator, intrinsic_validator_type>};
462 constexpr static bool has_identity_validator{coordinates_type::has_identity_validator};
463
464 template<convex_space RHSValueSpace, class RHSUnit, class RHSConvention, class RHSOrigin, class RHSValidator>
465 constexpr static bool is_composable_with{
466 std::common_with<convention_type, RHSConvention>
467 && (is_intrinsically_absolute || vector_space<space_type>)
469 };
470
471 template<convex_space RHSValueSpace, class RHSUnit, class RHSConvention, class RHSOrigin, class RHSValidator>
472 constexpr static bool is_multipicable_with{
473 std::common_with<convention_type, RHSConvention>
474 && is_composable_with<RHSValueSpace, RHSUnit, RHSConvention, RHSOrigin, RHSValidator>
476 };
477
478 template<convex_space RHSValueSpace, class RHSUnit, class RHSConvention, class RHSOrigin, class RHSValidator>
479 constexpr static bool is_divisible_with{
480 weak_field<ring_type>
481 && weak_field<commutative_ring_type_of_t<RHSValueSpace>>
482 && std::common_with<convention_type, RHSConvention>
483 && is_composable_with<RHSValueSpace, RHSUnit, RHSConvention, RHSOrigin, RHSValidator>
485 };
486
487 constexpr physical_value() = default;
488
489 constexpr physical_value(value_type val, units_type) requires (D == 1)
490 : coordinates_type{val}
491 {}
492
493 constexpr physical_value(std::span<const value_type, D> val, units_type)
494 : coordinates_type{val}
495 {}
496
497 constexpr physical_value operator-() const requires is_effectively_absolute = delete;
498
499 [[nodiscard]]
500 constexpr physical_value operator+() const
501 {
502 return physical_value{this->values(), units_type{}};
503 }
504
505 using coordinates_type::operator+=;
506
507 template<convex_space OtherValueSpace>
508 requires is_intrinsically_absolute && (std::is_base_of_v<ValueSpace, OtherValueSpace>)
509 constexpr physical_value& operator+=(const physical_value<OtherValueSpace, Unit, Convention, Origin, Validator>& other) noexcept(has_identity_validator)
510 {
511 this->apply_to_each_element(other.values(), [](value_type& lhs, value_type rhs){ lhs += rhs; });
512 return *this;
513 }
514
515 template<convex_space OtherValueSpace>
516 requires (!std::is_same_v<ValueSpace, OtherValueSpace>) && have_compatible_base_spaces_v<ValueSpace, OtherValueSpace>
517 [[nodiscard]]
518 friend constexpr auto operator+(const physical_value& lhs, const physical_value<OtherValueSpace, Unit, Convention, Origin, Validator>& rhs)
519 {
520 using physical_value_t
522 return physical_value_t{lhs.values(), units_type{}} += rhs;
523 }
524
525 [[nodiscard]]
526 constexpr physical_value operator-() const noexcept(has_identity_validator)
527 requires (!is_effectively_absolute)
528 {
529 return physical_value{utilities::to_array(this->values(), [](value_type t) { return -t; }), units_type{}};
530 }
531
532 template<class OtherValueSpace>
533 requires (!std::is_same_v<OtherValueSpace, displacement_space_type>)
534 && (std::is_same_v<ValueSpace, OtherValueSpace> || have_compatible_base_spaces_v<ValueSpace, OtherValueSpace>)
535 [[nodiscard]]
536 friend constexpr auto operator-(const physical_value& lhs, const physical_value<OtherValueSpace, Unit, Convention, Origin, Validator>& rhs)
537 noexcept(has_identity_validator)
538 {
539 using disp_space_t = to_displacement_space_t<ValueSpace, OtherValueSpace>;
540 using disp_t = to_coordinates_base_type<disp_space_t, Unit, convention_type, Origin, Validator>::displacement_coordinates_type;
541 return[&] <std::size_t... Is>(std::index_sequence<Is...>) {
542 return disp_t{std::array{(lhs.values()[Is] - rhs.values()[Is])...}, units_type{}};
543 }(std::make_index_sequence<D>{});
544 }
545
546 template<convex_space RHSValueSpace, physical_unit RHSUnit, class RHSConvention, class RHSOrigin, class RHSValidator>
547 requires is_multipicable_with<RHSValueSpace, RHSUnit, RHSConvention, RHSOrigin, RHSValidator>
548 [[nodiscard]]
549 friend constexpr auto operator*(const physical_value& lhs,
551 {
552 using physical_value_t
553 = physical_value_product_t<
556 >;
557
558 using derived_units_type = physical_value_t::units_type;
559 return physical_value_t{lhs.value() * rhs.value(), derived_units_type{}};
560 }
561
562 template<convex_space RHSValueSpace, class RHSUnit, class RHSConvention, class RHSOrigin, class RHSValidator>
563 requires is_divisible_with<RHSValueSpace, RHSUnit, RHSConvention, RHSOrigin, RHSValidator>
564 [[nodiscard]]
565 friend constexpr auto operator/(const physical_value& lhs,
567 {
568 using physical_value_t
569 = physical_value_product_t<
571 physical_value<dual_of_t<RHSValueSpace>, dual_of_t<RHSUnit>, RHSConvention, RHSOrigin, RHSValidator>
572 >;
573 using derived_units_type = physical_value_t::units_type;
574 if constexpr(dimension == 1)
575 {
576 return physical_value_t{lhs.value() / rhs.value(), derived_units_type{}};
577 }
578 else
579 {
580 return[&] <std::size_t... Is>(std::index_sequence<Is...>) {
581 return physical_value_t{std::array{(lhs.values()[Is] / rhs.value())...}, derived_units_type{}};
582 }(std::make_index_sequence<D>{});
583 }
584 }
585
586 [[nodiscard]] friend constexpr auto operator/(value_type value, const physical_value& rhs)
587 requires ((D == 1) && (is_intrinsically_absolute || vector_space<ValueSpace>))
588 {
589 using physical_value_t = physical_value<dual_of_t<ValueSpace>, dual_of_t<Unit>, convention_type, origin_type, validator_type>;
590 using derived_units_type = physical_value_t::units_type;
591 return physical_value_t{value / rhs.value(), derived_units_type{}};
592 }
593
594 // Reduce *everything* to its base space on both sides of the equation; if these are the same, allow the conversion
595 template<class LoweredValueSpace, class OtherUnit>
596 [[nodiscard]]
598 requires std::same_as<to_base_space_t<ValueSpace>, to_base_space_t<LoweredValueSpace>>
599 {
600 using physical_value_t = physical_value<to_base_space_t<LoweredValueSpace>, Unit, convention_type, origin_type, validator_type>;
601 if constexpr(dimension == 1)
602 {
603 return physical_value_t{this->value(), OtherUnit{}};
604 }
605 else
606 {
607 return [this] <std::size_t... Is>(std::index_sequence<Is...>) {
608 return physical_value_t{std::array{this->values()[Is]...}, OtherUnit{}};
609 }(std::make_index_sequence<D>{});
610 }
611 }
612 };
613
614 namespace sets::classical
615 {
616 template<class Arena>
617 struct masses
618 {
619 using arena_type = Arena;
620 };
621
622 template<class Arena>
624 {
625 using arena_type = Arena;
626 };
627
628 template<class Arena>
630 {
631 using arena_type = Arena;
632 };
633
634 template<class Arena>
635 struct times
636 {
637 using arena_type = Arena;
638 };
639
640 template<class Arena>
642 {
643 using arena_type = Arena;
644 };
645
646 template<class Arena>
648 {
649 using arena_type = Arena;
650 };
651
652 template<class Arena>
653 struct lengths
654 {
655 using arena_type = Arena;
656 };
657
658 template<class Arena>
659 struct angles
660 {
661 using arena_type = Arena;
662 };
663
664 template<class PhysicalValueSet>
666 {
667 using physical_value_set_type = PhysicalValueSet;
668 };
669 }
670
671 template<class Space>
673 {
674 constexpr static std::size_t dimension{Space::dimension};
676 using commutative_ring_type = Space::representation_type;
677 using is_free_module = std::true_type;
678 };
679
680 template<class PhysicalValueSet, arithmetic Rep, std::size_t D, class Derived>
682 {
683 constexpr static std::size_t dimension{D};
684 using set_type = PhysicalValueSet;
685 using representation_type = Rep;
687 using is_convex_space = std::true_type;
688 };
689
690 template<class PhysicalValueSet, arithmetic Rep, std::size_t D, class Derived>
692 {
693 constexpr static std::size_t dimension{D};
694 using set_type = PhysicalValueSet;
695 using representation_type = Rep;
697 using is_affine_space = std::true_type;
698 };
699
700 template<class PhysicalValueSet, arithmetic Rep, std::size_t D, class Derived>
702 {
703 constexpr static std::size_t dimension{D};
704 using set_type = PhysicalValueSet;
705 using representation_type = Rep;
706 using field_type = Rep;
707 using is_vector_space = std::true_type;
708 };
709
710 template<std::floating_point Rep, class Arena>
712 : physical_value_convex_space<sets::classical::masses<Arena>, Rep, 1, mass_space<Rep, Arena>>
713 {
714 using base_space = mass_space;
715 };
716
717 template<std::floating_point Rep, class Arena>
719 : physical_value_convex_space<sets::classical::temperatures<Arena>, Rep, 1, temperature_space<Rep, Arena>>
720 {
722 };
723
724 template<std::floating_point Rep, class Arena>
726 : physical_value_vector_space<sets::classical::electrical_currents<Arena>, Rep, 1, electrical_current_space<Rep, Arena>>
727 {
729 };
730
731 template<std::floating_point Rep, class Arena>
732 struct angular_space : physical_value_vector_space<sets::classical::angles<Arena>, Rep, 1, angular_space<Rep, Arena>>
733 {
735 };
736
737 template<arithmetic Rep, class Arena>
739 : physical_value_convex_space<sets::classical::lengths<Arena>, Rep, 1, length_space<Rep, Arena>>
740 {
741 using base_space = length_space;
742 };
743
744 template<arithmetic Rep, class Arena>
745 struct width_space : length_space<Rep, Arena>
746 {
747 };
748
749 template<arithmetic Rep, class Arena>
750 struct height_space : length_space<Rep, Arena>
751 {
752 };
753
754 template<arithmetic Rep, class Arena>
756 : physical_value_convex_space<sets::classical::time_intervals<Arena>, Rep, 1, time_interval_space<Rep, Arena>>
757 {};
758
759 template<arithmetic Rep, class Arena>
760 struct time_space : physical_value_affine_space<sets::classical::times<Arena>, Rep, 1, time_space<Rep, Arena>>
761 {};
762
763 template<std::size_t D, arithmetic Rep, class Arena>
764 struct position_space : physical_value_affine_space<sets::classical::positions<Arena>, Rep, D, position_space<D, Rep, Arena>>
765 {};
766
768
769 template<physical_unit U>
770 inline constexpr bool has_symbol_v{
771 requires {
772 { U::symbol } -> std::convertible_to<std::string_view>; }
773 };
774
775 namespace si
776 {
777 namespace units
778 {
779 struct ampere_t
780 {
781 using validator_type = std::identity;
782 constexpr static std::string_view symbol{"A"};
783 };
784
786 {
788 constexpr static std::string_view symbol{"kg"};
789 };
790
791 struct metre_t
792 {
794 constexpr static std::string_view symbol{"m"};
795 };
796
797 struct second_t
798 {
800 constexpr static std::string_view symbol{"s"};
801 };
802
803 struct kelvin_t
804 {
806 constexpr static std::string_view symbol{"K"};
807 };
808
810 {
811 using validator_type = std::identity;
812 constexpr static std::string_view symbol{"C"};
813 };
814
815 struct radian_t
816 {
817 using validator_type = std::identity;
818 constexpr static std::string_view symbol{"rad"};
819 };
820
821
823 {
825 {
826 template<std::floating_point T>
827 [[nodiscard]]
828 constexpr T operator()(const T val) const
829 {
830 if(val < T(-273.15)) throw std::domain_error{std::format("Value {} less than -273.15", val)};
831
832 return val;
833 }
834 };
835
837 constexpr static std::string_view symbol{"degC"};
838 };
839
840 inline constexpr ampere_t ampere{};
841 inline constexpr kilogram_t kilogram{};
842 inline constexpr metre_t metre{};
843 inline constexpr second_t second{};
844 inline constexpr kelvin_t kelvin{};
845 inline constexpr coulomb_t coulomb{};
846 inline constexpr radian_t radian{};
847
848 inline constexpr celsius_t celsius{};
849 }
850
851 template<std::floating_point T, class Arena=implicit_common_arena>
852 using mass = physical_value<mass_space<T, Arena>, units::kilogram_t>;
853
854 template<std::floating_point T, class Arena=implicit_common_arena>
855 using length = physical_value<length_space<T, Arena>, units::metre_t>;
856
857 template<std::floating_point T, class Arena=implicit_common_arena>
858 using time_interval = physical_value<time_interval_space<T, Arena>, units::second_t>;
859
860 template<std::floating_point T, class Arena=implicit_common_arena>
861 using temperature = physical_value<temperature_space<T, Arena>, units::kelvin_t>;
862
863 template<std::floating_point T, class Arena=implicit_common_arena>
864 using electrical_current = physical_value<electrical_current_space<T, Arena>, units::ampere_t>;
865
866 template<std::floating_point T, class Arena=implicit_common_arena>
867 using angle = physical_value<angular_space<T, Arena>, units::radian_t>;
868
869 template<std::floating_point T, class Arena=implicit_common_arena>
870 using width = physical_value<width_space<T, Arena>, units::metre_t>;
871
872 template<std::floating_point T, class Arena=implicit_common_arena>
873 using height = physical_value<height_space<T, Arena>, units::metre_t>;
874
875 template<
876 std::floating_point T,
877 class Arena=implicit_common_arena,
878 class Origin=implicit_affine_origin<time_space<T, Arena>>
879 >
880 using time = physical_value<time_space<T, Arena>, units::second_t, canonical_convention<1>, Origin, std::identity>;
881
882 template<
883 std::size_t D,
884 std::floating_point T,
885 class Arena = implicit_common_arena,
886 class Convention = canonical_convention<D>,
887 class Origin = implicit_affine_origin<position_space<D, T, Arena>>
888 >
889 using position = physical_value<position_space<D, T, Arena>, units::metre_t, Convention, Origin, std::identity>;
890 }
891
892 template<vector_space ValueSpace, physical_unit Unit, class Convention, class Origin, validator_for<ValueSpace> Validator>
893 requires (dimension_of<ValueSpace> == 1)
894 [[nodiscard]]
895 constexpr physical_value<ValueSpace, Unit, Convention, Origin, Validator> abs(physical_value<ValueSpace, Unit, Convention, Origin, Validator> q)
896 {
897 return {std::abs(q.value()), Unit{}};
898 }
899
900 template<std::floating_point T, class Arena=implicit_common_arena>
901 [[nodiscard]]
902 constexpr T sin(physical_value<angular_space<T, Arena>, si::units::radian_t> theta)
903 {
904 return std::sin(theta.value());
905 }
906
907 template<std::floating_point T, class Arena=implicit_common_arena>
908 [[nodiscard]]
909 constexpr T cos(physical_value<angular_space<T, Arena>, si::units::radian_t> theta)
910 {
911 return std::cos(theta.value());
912 }
913
914 template<std::floating_point T, class Arena=implicit_common_arena>
915 [[nodiscard]]
916 constexpr T tan(physical_value<angular_space<T, Arena>, si::units::radian_t> theta)
917 {
918 return std::tan(theta.value());
919 }
920
921 template<class Arena=implicit_common_arena, std::floating_point T>
922 [[nodiscard]]
923 constexpr physical_value<angular_space<T, Arena>, si::units::radian_t> asin(T x)
924 {
925 return {std::asin(x), si::units::radian};
926 }
927
928 template<class Arena=implicit_common_arena, std::floating_point T>
929 [[nodiscard]]
930 constexpr physical_value<angular_space<T, Arena>, si::units::radian_t> acos(T x)
931 {
932 return {std::acos(x), si::units::radian};
933 }
934
935 template<class Arena=implicit_common_arena, std::floating_point T>
936 [[nodiscard]]
937 constexpr physical_value<angular_space<T, Arena>, si::units::radian_t> atan(T x)
938 {
939 return {std::atan(x), si::units::radian};
940 }
941
942 template<
943 convex_space ValueSpace,
944 physical_unit Unit,
945 validator_for<ValueSpace> Validator=typename Unit::validator_type
946 >
947 requires has_consistent_validator<ValueSpace, Validator>
948 using quantity = physical_value<ValueSpace, Unit, canonical_convention<1>, to_origin_type_t<ValueSpace, Unit>, Validator>;
949}
950
951template<
955>
956struct std::formatter<sequoia::physics::quantity<ValueSpace, Unit, Validator>>
957{
958 constexpr auto parse(auto& ctx)
959 {
960 return ctx.begin();
961 }
962
963 auto format(const sequoia::physics::quantity<ValueSpace, Unit, Validator>& q, auto& ctx) const
964 {
965 if constexpr(sequoia::physics::has_symbol_v<Unit>)
966 return std::format_to(ctx.out(), "{} {}", q.value(), Unit::symbol);
967 else
968 return std::format_to(ctx.out(), "{}", q.value());
969 }
970};
971
Class designed for inheritance by concerete coordinate types.
Definition: Spaces.hpp:1076
Definition: PhysicalValues.hpp:440
concept for convex spaces
Definition: Spaces.hpp:517
concept to check if a validator is compatible with a convex space.
Definition: Spaces.hpp:676
Definition: PhysicalValuesDetails.hpp:33
Definition: Spaces.hpp:774
Definition: Spaces.hpp:763
Type to indicate a distinguished origin, relevant for free modules.
Definition: Spaces.hpp:1010
Specialization for units, such as degrees Celsius, for which the corresponding quantity cannot be inv...
Definition: PhysicalValues.hpp:37
Primary class template for defining duals.
Definition: Spaces.hpp:896
A validator the the half line.
Definition: Spaces.hpp:703
Definition: PhysicalValues.hpp:733
Definition: PhysicalValues.hpp:673
Definition: PhysicalValues.hpp:171
Definition: PhysicalValues.hpp:99
Definition: PhysicalValues.hpp:87
Definition: PhysicalValues.hpp:727
Definition: PhysicalValues.hpp:751
Definition: PhysicalValues.hpp:260
Definition: PhysicalValues.hpp:767
Definition: PhysicalValues.hpp:17
Definition: PhysicalValues.hpp:192
Definition: PhysicalValues.hpp:740
Definition: PhysicalValues.hpp:713
Definition: PhysicalValues.hpp:79
Definition: PhysicalValues.hpp:692
Definition: PhysicalValues.hpp:682
Definition: PhysicalValues.hpp:199
Definition: PhysicalValues.hpp:366
Definition: PhysicalValues.hpp:702
Definition: PhysicalValues.hpp:765
Definition: PhysicalValues.hpp:61
Definition: PhysicalValues.hpp:93
Definition: PhysicalValues.hpp:660
Definition: PhysicalValues.hpp:666
Definition: PhysicalValues.hpp:654
Definition: PhysicalValues.hpp:618
Definition: PhysicalValues.hpp:648
Definition: PhysicalValues.hpp:624
Definition: PhysicalValues.hpp:642
Definition: PhysicalValues.hpp:636
Definition: PhysicalValues.hpp:780
Definition: PhysicalValues.hpp:825
Definition: PhysicalValues.hpp:823
Definition: PhysicalValues.hpp:810
Definition: PhysicalValues.hpp:804
Definition: PhysicalValues.hpp:786
Definition: PhysicalValues.hpp:792
Definition: PhysicalValues.hpp:816
Definition: PhysicalValues.hpp:798
Definition: PhysicalValues.hpp:720
Definition: PhysicalValues.hpp:757
Definition: PhysicalValues.hpp:761
Definition: PhysicalValues.hpp:305
Definition: PhysicalValues.hpp:347
Definition: PhysicalValues.hpp:263
Definition: PhysicalValues.hpp:257
Definition: PhysicalValues.hpp:746
Definition: PhysicalValues.hpp:187