forked from mpusz/mp-units
refactor: scalar and complex renamed to real_scalar and complex_scalar respectively + concepts refactoring + electromagnetism fixes
This commit is contained in:
@@ -93,7 +93,6 @@ if(NOT ${projectPrefix}API_FREESTANDING)
|
||||
include/mp-units/bits/requires_hosted.h
|
||||
include/mp-units/ext/format.h
|
||||
include/mp-units/cartesian_vector.h
|
||||
include/mp-units/complex.h
|
||||
include/mp-units/format.h
|
||||
include/mp-units/math.h
|
||||
include/mp-units/ostream.h
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
//
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/framework/customization_points.h>
|
||||
#include <mp-units/framework/representation_concepts.h>
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <mp-units/bits/fmt.h>
|
||||
@@ -46,7 +47,7 @@ import std;
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
MP_UNITS_EXPORT template<typename T = double>
|
||||
MP_UNITS_EXPORT template<detail::Scalar T = double>
|
||||
class cartesian_vector {
|
||||
public:
|
||||
// public members required to satisfy structural type requirements :-(
|
||||
@@ -101,7 +102,12 @@ public:
|
||||
[[nodiscard]] constexpr T magnitude() const
|
||||
requires treat_as_floating_point<T>
|
||||
{
|
||||
return std::hypot(_coordinates_[0], _coordinates_[1], _coordinates_[2]);
|
||||
using namespace std;
|
||||
if constexpr (detail::ComplexScalar<T>)
|
||||
return hypot(mp_units::modulus(_coordinates_[0]), mp_units::modulus(_coordinates_[1]),
|
||||
mp_units::modulus(_coordinates_[2]));
|
||||
else
|
||||
return hypot(_coordinates_[0], _coordinates_[1], _coordinates_[2]);
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr cartesian_vector unit() const
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2018 Mateusz Pusz
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mp-units/bits/requires_hosted.h>
|
||||
//
|
||||
#include <mp-units/bits/module_macros.h>
|
||||
#include <mp-units/framework/representation_concepts.h>
|
||||
|
||||
#ifndef MP_UNITS_IN_MODULE_INTERFACE
|
||||
#ifdef MP_UNITS_IMPORT_STD
|
||||
import std;
|
||||
#else
|
||||
#include <complex>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
template<typename T>
|
||||
constexpr bool disable_scalar<std::complex<T>> = true;
|
||||
|
||||
} // namespace mp_units
|
||||
@@ -29,7 +29,6 @@
|
||||
|
||||
#if MP_UNITS_HOSTED
|
||||
#include <mp-units/cartesian_vector.h>
|
||||
#include <mp-units/complex.h>
|
||||
#include <mp-units/format.h>
|
||||
#include <mp-units/math.h>
|
||||
#include <mp-units/ostream.h>
|
||||
|
||||
@@ -116,12 +116,6 @@ template<QuantitySpec QS, detail::WeakUnitOf<QS{}> U>
|
||||
return reference<QS, U>{};
|
||||
}
|
||||
|
||||
// TODO revise the note in the below comment
|
||||
/**
|
||||
* @brief Returns the most restrictive character from the list
|
||||
*
|
||||
* @note `vector * vector` returns vector (not tensor)
|
||||
*/
|
||||
template<std::same_as<quantity_character>... Ts>
|
||||
[[nodiscard]] consteval quantity_character common_quantity_character(Ts... args)
|
||||
{
|
||||
@@ -133,13 +127,10 @@ template<typename... Qs1, typename... Qs2>
|
||||
const type_list<Qs2...>&)
|
||||
{
|
||||
constexpr quantity_character num =
|
||||
detail::common_quantity_character(quantity_character::scalar, expr_type<Qs1>::character...);
|
||||
detail::common_quantity_character(quantity_character::real_scalar, expr_type<Qs1>::character...);
|
||||
constexpr quantity_character den =
|
||||
detail::common_quantity_character(quantity_character::scalar, expr_type<Qs2>::character...);
|
||||
if constexpr (num == den)
|
||||
return quantity_character::scalar;
|
||||
else
|
||||
return detail::common_quantity_character(num, den);
|
||||
detail::common_quantity_character(quantity_character::real_scalar, expr_type<Qs2>::character...);
|
||||
return detail::max(num, den);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,7 +282,7 @@ MP_UNITS_EXPORT_END
|
||||
*
|
||||
* This quantity serves as a root/kind for a new hierarchy of quantities of the same kind.
|
||||
*
|
||||
* Base quantities have scalar character by default.
|
||||
* Base quantities have real scalar character by default.
|
||||
*
|
||||
* User should derive a strong type from this class template rather than use it directly in the source code.
|
||||
* For example:
|
||||
@@ -312,7 +303,7 @@ MP_UNITS_EXPORT_END
|
||||
* errors. Having them of the same names improves user experience and somehow blurs those separate domains.
|
||||
*
|
||||
* @tparam BaseDimension base dimension for which a base quantity is being defined
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be real scalar
|
||||
*/
|
||||
#if MP_UNITS_API_NO_CRTP
|
||||
template<detail::BaseDimension auto Dim, detail::QSProperty auto... Args>
|
||||
@@ -323,7 +314,8 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
||||
#endif
|
||||
using _base_type_ = quantity_spec;
|
||||
static constexpr detail::BaseDimension auto dimension = Dim;
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(quantity_character::scalar);
|
||||
static constexpr quantity_character character =
|
||||
detail::quantity_character_init<Args...>(quantity_character::real_scalar);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -334,7 +326,7 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
||||
*
|
||||
* This quantity serves as a root/kind for a new hierarchy of quantities of the same kind.
|
||||
*
|
||||
* Such quantities by default derive the character from the derived quantity definition.
|
||||
* Such quantities obtain the character from the derived quantity equation.
|
||||
*
|
||||
* User should derive a strong type from this class template rather than use it directly in the source code.
|
||||
* For example:
|
||||
@@ -342,10 +334,8 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
||||
* @code{.cpp}
|
||||
* inline constexpr struct area final : quantity_spec<pow<2>(length)> {} area;
|
||||
* inline constexpr struct volume final : quantity_spec<pow<3>(length)> {} volume;
|
||||
* inline constexpr struct velocity final : quantity_spec<displacement / duration> {} velocity;
|
||||
* inline constexpr struct speed final : quantity_spec<length / time> {} speed;
|
||||
* inline constexpr struct force final : quantity_spec<mass * acceleration, quantity_character::vector> {} force;
|
||||
* inline constexpr struct power final : quantity_spec<force * velocity, quantity_character::scalar> {} power;
|
||||
* inline constexpr struct velocity final : quantity_spec<displacement / duration> {} velocity; // vector
|
||||
* inline constexpr struct force final : quantity_spec<mass * acceleration> {} force; // vector
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -354,7 +344,7 @@ struct quantity_spec<Self, Dim, Args...> : detail::quantity_spec_interface<Self>
|
||||
* errors. Having them of the same names improves user experience and somehow blurs those separate domains.
|
||||
*
|
||||
* @tparam Eq quantity equation specification of a derived quantity
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be real scalar
|
||||
*/
|
||||
#if MP_UNITS_API_NO_CRTP
|
||||
template<detail::DerivedQuantitySpec auto Eq, detail::QSProperty auto... Args>
|
||||
@@ -366,6 +356,9 @@ struct quantity_spec<Self, Eq, Args...> : detail::quantity_spec_interface<Self>
|
||||
using _base_type_ = quantity_spec;
|
||||
static constexpr auto _equation_ = Eq;
|
||||
static constexpr Dimension auto dimension = Eq.dimension;
|
||||
|
||||
// TODO static_assert that character property is not passed in Args
|
||||
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character);
|
||||
};
|
||||
|
||||
@@ -387,7 +380,8 @@ struct propagate_equation<Q, true> {
|
||||
* Quantities of the same kind form a hierarchy. This specialization adds new leaf to such a tree which
|
||||
* can later be used as a parent by other quantities.
|
||||
*
|
||||
* The character of those quantities by default is derived from the parent quantity.
|
||||
* The character of those quantities by default is derived from the parent quantity but can be overriden
|
||||
* by explicitly passing a property.
|
||||
*
|
||||
* User should derive a strong type from this class template rather than use it directly in the source code.
|
||||
* For example:
|
||||
@@ -397,6 +391,8 @@ struct propagate_equation<Q, true> {
|
||||
* inline constexpr struct height final : quantity_spec<length> {} height;
|
||||
* inline constexpr struct diameter final : quantity_spec<width> {} diameter;
|
||||
* inline constexpr struct displacement final : quantity_spec<length, quantity_character::vector> {} displacement;
|
||||
* inline constexpr struct voltage_phasor final : quantity_spec<voltage, quantity_character::complex_scalar) {}
|
||||
* voltage_phasor;
|
||||
* @endcode
|
||||
*
|
||||
* @note A common convention in this library is to assign the same name for a type and an object of this type.
|
||||
@@ -405,7 +401,7 @@ struct propagate_equation<Q, true> {
|
||||
* errors. Having them of the same names improves user experience and somehow blurs those separate domains.
|
||||
*
|
||||
* @tparam Q quantity specification of a parent quantity
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be real scalar
|
||||
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
||||
*/
|
||||
#if MP_UNITS_API_NO_CRTP
|
||||
@@ -445,7 +441,7 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
|
||||
* can later be used as a parent by other quantities. Additionally, this defintion adds additional
|
||||
* constraints on the derived quantity's equation.
|
||||
*
|
||||
* The character of those quantities by default is derived from the parent quantity.
|
||||
* Such quantities obtain the character from the derived quantity equation.
|
||||
*
|
||||
* User should derive a strong type from this class template rather than use it directly in the source code.
|
||||
* For example:
|
||||
@@ -463,8 +459,8 @@ struct quantity_spec<Self, QS, Args...> : detail::propagate_equation<QS>, detail
|
||||
* errors. Having them of the same names improves user experience and somehow blurs those separate domains.
|
||||
*
|
||||
* @tparam Q quantity specification of a parent quantity
|
||||
* @tparam Args optionally a value of a `quantity_character` in case the base quantity should not be scalar
|
||||
* or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
||||
* @tparam Args optionally a value of `quantity_character` in case the base quantity should not
|
||||
* be real scalar or `is_kind` in case the quantity starts a new hierarchy tree of a kind
|
||||
*/
|
||||
// clang-format on
|
||||
#if MP_UNITS_API_NO_CRTP
|
||||
@@ -481,6 +477,9 @@ struct quantity_spec<Self, QS, Eq, Args...> : detail::quantity_spec_interface<Se
|
||||
static constexpr auto _parent_ = QS;
|
||||
static constexpr auto _equation_ = Eq;
|
||||
static constexpr Dimension auto dimension = _parent_.dimension;
|
||||
|
||||
// TODO static_assert that character property is not passed in Args
|
||||
|
||||
static constexpr quantity_character character = detail::quantity_character_init<Args...>(Eq.character);
|
||||
};
|
||||
|
||||
|
||||
@@ -41,34 +41,6 @@ import std;
|
||||
|
||||
namespace mp_units {
|
||||
|
||||
/**
|
||||
* @brief Quantity character
|
||||
*
|
||||
* Scalars, vectors and tensors are mathematical objects that can be used to
|
||||
* denote certain physical quantities and their values. They are as such
|
||||
* independent of the particular choice of a coordinate system, whereas
|
||||
* each scalar component of a vector or a tensor and each component vector and
|
||||
* component tensor depend on that choice.
|
||||
*
|
||||
* A scalar is a physical quantity that has magnitude but no direction.
|
||||
*
|
||||
* A complex is a physical quantity that is represented with a complex number.
|
||||
*
|
||||
* Vectors are physical quantities that possess both magnitude and direction
|
||||
* and whose operations obey the axioms of a vector space.
|
||||
*
|
||||
* Tensors can be used to describe more general physical quantities.
|
||||
* For example, the Cauchy stress tensor possess magnitude, direction,
|
||||
* and orientation qualities.
|
||||
*/
|
||||
MP_UNITS_EXPORT enum class quantity_character : std::int8_t { scalar, complex, vector, tensor };
|
||||
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
constexpr bool disable_scalar = false;
|
||||
|
||||
template<>
|
||||
MP_UNITS_INLINE constexpr bool disable_scalar<bool> = true;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
@@ -82,23 +54,44 @@ concept ScalableWith = requires(const T v, const S s) {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept Scalar = (!disable_scalar<T>) &&
|
||||
requires(const T a, const T b) {
|
||||
{ -a } -> std::common_with<T>;
|
||||
{ a + b } -> std::common_with<T>;
|
||||
{ a - b } -> std::common_with<T>;
|
||||
} && ScalableWith<T, T>
|
||||
#if MP_UNITS_COMP_GCC != 12 && !defined(MP_UNITS_XCODE15_HACKS)
|
||||
&& WeaklyRegular<T>
|
||||
#endif
|
||||
;
|
||||
concept Addable = requires(const T a, const T b) {
|
||||
{ -a } -> std::common_with<T>;
|
||||
{ a + b } -> std::common_with<T>;
|
||||
{ a - b } -> std::common_with<T>;
|
||||
};
|
||||
|
||||
namespace real_impl {
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* @brief Quantity character
|
||||
*
|
||||
* Scalars, vectors and tensors are mathematical objects that can be used to
|
||||
* denote certain physical quantities and their values. They are as such
|
||||
* independent of the particular choice of a coordinate system, whereas
|
||||
* each scalar component of a vector or a tensor and each component vector and
|
||||
* component tensor depend on that choice.
|
||||
*
|
||||
* A scalar is a physical quantity that has magnitude but no direction. It might
|
||||
* be a real or complex number which affects which operations are allowed on a quantity.
|
||||
*
|
||||
* Vectors are physical quantities that possess both magnitude and direction
|
||||
* and whose operations obey the axioms of a vector space.
|
||||
*
|
||||
* Tensors can be used to describe more general physical quantities.
|
||||
* For example, the Cauchy stress tensor possess magnitude, direction,
|
||||
* and orientation qualities.
|
||||
*/
|
||||
MP_UNITS_EXPORT enum class quantity_character : std::int8_t { real_scalar, complex_scalar, vector, tensor };
|
||||
|
||||
/////////////// COMPLEX SCALAR ///////////////
|
||||
|
||||
namespace detail::real_impl {
|
||||
|
||||
void real() = delete; // poison pill
|
||||
|
||||
struct real_t {
|
||||
[[nodiscard]] constexpr Scalar auto operator()(const WeaklyRegular auto& clx) const
|
||||
// TODO how to constrain the return with RealScalar?
|
||||
[[nodiscard]] constexpr auto operator()(const WeaklyRegular auto& clx) const
|
||||
requires requires { clx.real(); } || requires { real(clx); }
|
||||
{
|
||||
if constexpr (requires { clx.real(); })
|
||||
@@ -108,9 +101,7 @@ struct real_t {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace real_impl
|
||||
|
||||
} // namespace detail
|
||||
} // namespace detail::real_impl
|
||||
|
||||
inline namespace cpo {
|
||||
|
||||
@@ -123,7 +114,8 @@ namespace detail::imag_impl {
|
||||
void imag() = delete; // poison pill
|
||||
|
||||
struct imag_t {
|
||||
[[nodiscard]] constexpr Scalar auto operator()(const WeaklyRegular auto& clx) const
|
||||
// TODO how to constrain the return with RealScalar?
|
||||
[[nodiscard]] constexpr auto operator()(const WeaklyRegular auto& clx) const
|
||||
requires requires { clx.imag(); } || requires { imag(clx); }
|
||||
{
|
||||
if constexpr (requires { clx.imag(); })
|
||||
@@ -147,7 +139,8 @@ void modulus() = delete; // poison pill
|
||||
void abs() = delete; // poison pill
|
||||
|
||||
struct modulus_t {
|
||||
[[nodiscard]] constexpr Scalar auto operator()(const WeaklyRegular auto& clx) const
|
||||
// TODO how to constrain the return with RealScalar?
|
||||
[[nodiscard]] constexpr auto operator()(const WeaklyRegular auto& clx) const
|
||||
requires requires { clx.modulus(); } || requires { modulus(clx); } || requires { clx.abs(); } ||
|
||||
requires { abs(clx); }
|
||||
{
|
||||
@@ -155,7 +148,7 @@ struct modulus_t {
|
||||
return clx.modulus();
|
||||
else if constexpr (requires { modulus(clx); })
|
||||
return modulus(clx);
|
||||
// `std` made a precedence of using `abs` for modulo on `std::complex`
|
||||
// `std` made a precedence of using `abs` for modulus on `std::complex`
|
||||
else if constexpr (requires { clx.abs(); })
|
||||
return clx.abs();
|
||||
else if constexpr (requires { abs(clx); })
|
||||
@@ -171,30 +164,55 @@ MP_UNITS_EXPORT inline constexpr ::mp_units::detail::modulus_impl::modulus_t mod
|
||||
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
concept ComplexScalar =
|
||||
// TODO should the below be provided?
|
||||
// (!disable_complex<T>) &&
|
||||
Addable<T> && ScalableWith<T, T> &&
|
||||
requires(const T v, const T& ref) {
|
||||
::mp_units::real(v);
|
||||
::mp_units::imag(v);
|
||||
::mp_units::modulus(v);
|
||||
requires ScalableWith<T, decltype(::mp_units::modulus(v))>;
|
||||
requires std::constructible_from<T, decltype(::mp_units::real(ref)), decltype(::mp_units::imag(ref))>;
|
||||
}
|
||||
#ifndef MP_UNITS_XCODE15_HACKS
|
||||
&& WeaklyRegular<T>
|
||||
#endif
|
||||
;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/////////////// REAL SCALAR ///////////////
|
||||
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
constexpr bool disable_complex = false;
|
||||
constexpr bool disable_real = false;
|
||||
|
||||
template<>
|
||||
MP_UNITS_INLINE constexpr bool disable_real<bool> = true;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
concept Complex = (!disable_complex<T>) &&
|
||||
requires(const T a, const T b, const T& c) {
|
||||
{ -a } -> std::common_with<T>;
|
||||
{ a + b } -> std::common_with<T>;
|
||||
{ a - b } -> std::common_with<T>;
|
||||
{ a* b } -> std::common_with<T>;
|
||||
{ a / b } -> std::common_with<T>;
|
||||
::mp_units::real(a);
|
||||
::mp_units::imag(a);
|
||||
::mp_units::modulus(a);
|
||||
requires ScalableWith<T, decltype(::mp_units::modulus(a))>;
|
||||
requires std::constructible_from<T, decltype(::mp_units::real(c)), decltype(::mp_units::imag(c))>;
|
||||
}
|
||||
#ifndef MP_UNITS_XCODE15_HACKS
|
||||
&& WeaklyRegular<T>
|
||||
concept RealScalar =
|
||||
(!disable_real<T>) && Addable<T> && ScalableWith<T, T> && std::totally_ordered<T> && (!ComplexScalar<T>)
|
||||
#if MP_UNITS_COMP_GCC != 12 && !defined(MP_UNITS_XCODE15_HACKS)
|
||||
&& WeaklyRegular<T>
|
||||
#endif
|
||||
;
|
||||
namespace magnitude_impl {
|
||||
|
||||
template<typename T>
|
||||
concept Scalar = RealScalar<T> || ComplexScalar<T>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
/////////////// VECTOR ///////////////
|
||||
|
||||
namespace detail::magnitude_impl {
|
||||
|
||||
void magnitude() = delete; // poison pill
|
||||
void abs() = delete; // poison pill
|
||||
@@ -203,32 +221,29 @@ struct magnitude_t {
|
||||
template<WeaklyRegular T>
|
||||
[[nodiscard]] constexpr Scalar auto operator()(const T& vec) const
|
||||
requires requires { vec.magnitude(); } || requires { magnitude(vec); } ||
|
||||
(Scalar<T> &&
|
||||
(requires { vec.abs(); } || requires { abs(vec); } || (std::is_arithmetic_v<T> && (!is_same_v<T, bool>))))
|
||||
(RealScalar<T> && (std::is_arithmetic_v<T> || requires { vec.abs(); } || requires { abs(vec); }))
|
||||
{
|
||||
if constexpr (requires { vec.magnitude(); })
|
||||
return vec.magnitude();
|
||||
else if constexpr (requires { magnitude(vec); })
|
||||
return magnitude(vec);
|
||||
// allow scalar types to represent one dimensional vector quantities
|
||||
if constexpr (Scalar<T>) {
|
||||
if constexpr (requires { vec.abs(); })
|
||||
return vec.abs();
|
||||
else if constexpr (requires { abs(vec); })
|
||||
return abs(vec);
|
||||
else if constexpr (std::is_arithmetic_v<T> && (!is_same_v<T, bool>))
|
||||
// allow real types to represent one dimensional vector quantities
|
||||
if constexpr (RealScalar<T>) {
|
||||
if constexpr (std::is_arithmetic_v<T>)
|
||||
#if MP_UNITS_HOSTED || __cpp_lib_freestanding_cstdlib >= 202306L
|
||||
return std::abs(vec);
|
||||
#else
|
||||
return vec >= 0 ? vec : -vec;
|
||||
#endif
|
||||
else if constexpr (requires { vec.abs(); })
|
||||
return vec.abs();
|
||||
else if constexpr (requires { abs(vec); })
|
||||
return abs(vec);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace magnitude_impl
|
||||
|
||||
} // namespace detail
|
||||
} // namespace detail::magnitude_impl
|
||||
|
||||
inline namespace cpo {
|
||||
|
||||
@@ -236,22 +251,15 @@ MP_UNITS_EXPORT inline constexpr ::mp_units::detail::magnitude_impl::magnitude_t
|
||||
|
||||
}
|
||||
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
constexpr bool disable_vector = false;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
concept Vector = (!disable_vector<T>) &&
|
||||
requires(const T a, const T b) {
|
||||
{ -a } -> std::common_with<T>;
|
||||
{ a + b } -> std::common_with<T>;
|
||||
{ a - b } -> std::common_with<T>;
|
||||
::mp_units::magnitude(a);
|
||||
requires ScalableWith<T, decltype(::mp_units::magnitude(a))>;
|
||||
concept Vector = Addable<T> &&
|
||||
requires(const T v) {
|
||||
::mp_units::magnitude(v);
|
||||
requires ScalableWith<T, decltype(::mp_units::magnitude(v))>;
|
||||
// TODO should we also check for the below (e.g., when `size() > 1` or `2`)
|
||||
// ::mp_units::zero_vector<T>();
|
||||
// ::mp_units::unit_vector(a);
|
||||
// ::mp_units::scalar_product(a, b);
|
||||
// ::mp_units::vector_product(a, b);
|
||||
// ::mp_units::tensor_product(a, b);
|
||||
@@ -263,11 +271,11 @@ concept Vector = (!disable_vector<T>) &&
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/////////////// TENSOR ///////////////
|
||||
|
||||
// MP_UNITS_EXPORT template<typename T>
|
||||
// constexpr bool disable_tensor = false;
|
||||
|
||||
namespace detail {
|
||||
|
||||
// TODO provide when some actual operations will be required
|
||||
// template<typename T>
|
||||
// concept Tensor = (!disable_tensor<T>) && WeaklyRegular<T> && requires(const T a, const T b) {
|
||||
@@ -276,25 +284,33 @@ namespace detail {
|
||||
// ::mp_units::scalar_product(a, b);
|
||||
// };
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
constexpr bool is_quantity = false;
|
||||
|
||||
template<typename T>
|
||||
using scaling_factor_type_t = conditional<treat_as_floating_point<T>, long double, std::intmax_t>;
|
||||
|
||||
// TODO how can we use `(!Quantity<T>)` below?
|
||||
// TODO replace the below and above with the logic from #615 when available
|
||||
template<typename T>
|
||||
concept ScalarRepresentation = (!is_quantity<T>) && Scalar<T> && requires(const T v, const scaling_factor_type_t<T> f) {
|
||||
// scaling
|
||||
concept ScalableByFactor = requires(const T v, const scaling_factor_type_t<T> f) {
|
||||
{ v* f } -> std::common_with<T>;
|
||||
{ f* v } -> std::common_with<T>;
|
||||
{ v / f } -> std::common_with<T>;
|
||||
};
|
||||
|
||||
// TODO how can we use `(!Quantity<T>)` below?
|
||||
template<typename T>
|
||||
concept ComplexRepresentation =
|
||||
(!is_quantity<T>) && Complex<T> && requires(const T v, const scaling_factor_type_t<T> f) {
|
||||
// scaling
|
||||
concept NotQuantity = (!is_quantity<T>);
|
||||
|
||||
template<typename T>
|
||||
concept RealScalarRepresentation = NotQuantity<T> && RealScalar<T> && ScalableByFactor<T>;
|
||||
|
||||
template<typename T>
|
||||
concept ComplexScalarRepresentation =
|
||||
NotQuantity<T> && ComplexScalar<T> && requires(const T v, const scaling_factor_type_t<T> f) {
|
||||
// TODO The below conversion to `T` is an exception compared to other representation types
|
||||
// `std::complex<T>` * `U` do not work, but `std::complex<T>` is convertible from `U`
|
||||
// Maybe expose this as a customization point?
|
||||
@@ -304,30 +320,29 @@ concept ComplexRepresentation =
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
concept VectorRepresentation = (!is_quantity<T>) && Vector<T> && requires(const T v, const scaling_factor_type_t<T> f) {
|
||||
// scaling
|
||||
{ v* f } -> std::common_with<T>;
|
||||
{ f* v } -> std::common_with<T>;
|
||||
{ v / f } -> std::common_with<T>;
|
||||
};
|
||||
concept ScalarRepresentation = RealScalarRepresentation<T> || ComplexScalarRepresentation<T>;
|
||||
|
||||
template<typename T>
|
||||
concept VectorRepresentation = NotQuantity<T> && Vector<T> && ScalableByFactor<T>;
|
||||
|
||||
// template<typename T>
|
||||
// concept TensorRepresentation = (!is_quantity<T>) && Tensor<T>;
|
||||
// concept TensorRepresentation = NotQuantity<T> && Tensor<T>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
MP_UNITS_EXPORT template<typename T>
|
||||
concept Representation = detail::ScalarRepresentation<T> || detail::ComplexRepresentation<T> ||
|
||||
detail::VectorRepresentation<T>; // || detail::TensorRepresentation<T>;
|
||||
concept Representation =
|
||||
detail::ScalarRepresentation<T> || detail::VectorRepresentation<T>; // || detail::TensorRepresentation<T>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, quantity_character Ch>
|
||||
concept IsOfCharacter =
|
||||
(Ch == quantity_character::scalar && Scalar<T>) || (Ch == quantity_character::complex && Complex<T>) ||
|
||||
(Ch == quantity_character::real_scalar && RealScalar<T>) ||
|
||||
(Ch == quantity_character::complex_scalar && ComplexScalar<T>) ||
|
||||
(Ch == quantity_character::vector && Vector<T>); // || (Ch == quantity_character::tensor && Tensor<T>);
|
||||
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
MP_UNITS_EXPORT template<typename T, auto V>
|
||||
concept RepresentationOf =
|
||||
|
||||
@@ -54,8 +54,8 @@ QUANTITY_SPEC(electric_current_density, electric_charge_density* velocity);
|
||||
QUANTITY_SPEC(linear_electric_current_density, surface_density_of_electric_charge* velocity); // vector
|
||||
QUANTITY_SPEC(electric_field_strength, force / electric_charge); // vector
|
||||
QUANTITY_SPEC(electric_potential, electric_field_strength* length,
|
||||
quantity_character::scalar); // TODO what is a correct equation here?
|
||||
QUANTITY_SPEC(electric_potential_difference, electric_potential, quantity_character::scalar);
|
||||
quantity_character::real_scalar); // TODO what is a correct equation here?
|
||||
QUANTITY_SPEC(electric_potential_difference, electric_potential, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(voltage, electric_potential);
|
||||
inline constexpr auto electric_tension = voltage;
|
||||
QUANTITY_SPEC(induced_voltage, voltage); // TODO what is a correct equation here?
|
||||
@@ -73,19 +73,20 @@ inline constexpr auto light_speed_in_vacuum = speed_of_light_in_vacuum;
|
||||
inline constexpr auto luminal_speed = speed_of_light_in_vacuum;
|
||||
QUANTITY_SPEC(electric_constant, inverse(magnetic_constant* pow<2>(speed_of_light_in_vacuum)));
|
||||
inline constexpr auto permittivity_of_vacuum = electric_constant;
|
||||
QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::scalar);
|
||||
QUANTITY_SPEC(permittivity, electric_flux_density / electric_field_strength, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(relative_permittivity, dimensionless, permittivity / electric_constant);
|
||||
QUANTITY_SPEC(electric_susceptibility, dimensionless,
|
||||
electric_polarization / electric_constant / electric_field_strength, quantity_character::scalar);
|
||||
QUANTITY_SPEC(electric_flux, electric_flux_density* area, quantity_character::scalar);
|
||||
electric_polarization / electric_constant / electric_field_strength, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(electric_flux, electric_flux_density* area, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(displacement_current_density, electric_flux_density / time); // vector
|
||||
QUANTITY_SPEC(displacement_current, electric_current, displacement_current_density* area, quantity_character::scalar);
|
||||
QUANTITY_SPEC(displacement_current, electric_current, displacement_current_density* area,
|
||||
quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(total_current, electric_current);
|
||||
QUANTITY_SPEC(total_current_density, electric_current_density); // vector
|
||||
QUANTITY_SPEC(magnetic_flux, magnetic_flux_density* area, quantity_character::scalar);
|
||||
QUANTITY_SPEC(magnetic_flux, magnetic_flux_density* area, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(magnetic_vector_potential,
|
||||
magnetic_flux_density* length); // vector // TODO what is a correct equation here?
|
||||
QUANTITY_SPEC(protoflux, magnetic_vector_potential* displacement, quantity_character::scalar);
|
||||
QUANTITY_SPEC(protoflux, magnetic_vector_potential* displacement, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(linked_magnetic_flux, magnetic_flux);
|
||||
QUANTITY_SPEC(total_magnetic_flux, magnetic_flux);
|
||||
QUANTITY_SPEC(magnetic_moment, electric_current* area, quantity_character::vector);
|
||||
@@ -93,23 +94,24 @@ inline constexpr auto magnetic_area_moment = magnetic_moment;
|
||||
QUANTITY_SPEC(magnetization, magnetic_moment / volume); // vector
|
||||
QUANTITY_SPEC(magnetic_field_strength, magnetization); // vector
|
||||
inline constexpr auto magnetizing_field = magnetic_field_strength;
|
||||
QUANTITY_SPEC(permeability, magnetic_flux_density / magnetic_field_strength, quantity_character::scalar);
|
||||
QUANTITY_SPEC(permeability, magnetic_flux_density / magnetic_field_strength, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(relative_permeability, dimensionless, permeability / magnetic_constant);
|
||||
QUANTITY_SPEC(magnetic_susceptibility, dimensionless, magnetization / magnetic_field_strength,
|
||||
quantity_character::scalar);
|
||||
quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(magnetic_polarization, magnetic_constant* magnetization); // vector
|
||||
QUANTITY_SPEC(magnetic_dipole_moment, magnetic_constant* magnetic_moment); // vector
|
||||
QUANTITY_SPEC(coercivity, magnetic_field_strength, quantity_character::scalar);
|
||||
QUANTITY_SPEC(coercivity, magnetic_field_strength, quantity_character::real_scalar);
|
||||
inline constexpr auto coercive_field_strength = coercivity;
|
||||
QUANTITY_SPEC(electromagnetic_energy_density, electric_field_strength* electric_flux_density,
|
||||
quantity_character::scalar);
|
||||
quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(Poynting_vector, electric_field_strength* magnetic_field_strength); // vector
|
||||
QUANTITY_SPEC(source_voltage, voltage);
|
||||
inline constexpr auto source_tension = source_voltage;
|
||||
QUANTITY_SPEC(magnetic_potential, electric_current); // TODO what is a correct equation here?
|
||||
QUANTITY_SPEC(magnetic_tension, electric_current, magnetic_field_strength* position_vector, quantity_character::scalar);
|
||||
QUANTITY_SPEC(magnetic_tension, electric_current, magnetic_field_strength* position_vector,
|
||||
quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(magnetomotive_force, electric_current, magnetic_field_strength* position_vector,
|
||||
quantity_character::scalar);
|
||||
quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(number_of_turns_in_a_winding, dimensionless);
|
||||
QUANTITY_SPEC(reluctance, magnetic_tension / magnetic_flux);
|
||||
QUANTITY_SPEC(permeance, inverse(reluctance));
|
||||
@@ -118,15 +120,15 @@ inline constexpr auto self_inductance = inductance;
|
||||
QUANTITY_SPEC(mutual_inductance, protoflux / electric_current);
|
||||
QUANTITY_SPEC(coupling_factor, dimensionless, mutual_inductance / pow<1, 2>(pow<2>(self_inductance)));
|
||||
QUANTITY_SPEC(leakage_factor, dimensionless, pow<2>(coupling_factor));
|
||||
QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::scalar);
|
||||
QUANTITY_SPEC(conductivity, electric_current_density / electric_field_strength, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(resistivity, inverse(conductivity));
|
||||
QUANTITY_SPEC(electromagnetism_power, power, voltage* electric_current); // different name than in ISQ
|
||||
inline constexpr auto instantaneous_power = electromagnetism_power;
|
||||
QUANTITY_SPEC(resistance, voltage / electric_current);
|
||||
QUANTITY_SPEC(conductance, inverse(resistance));
|
||||
QUANTITY_SPEC(phase_difference, phase_angle);
|
||||
QUANTITY_SPEC(electric_current_phasor, electric_current, quantity_character::complex);
|
||||
QUANTITY_SPEC(voltage_phasor, voltage, quantity_character::complex);
|
||||
QUANTITY_SPEC(electric_current_phasor, electric_current, quantity_character::complex_scalar);
|
||||
QUANTITY_SPEC(voltage_phasor, voltage, quantity_character::complex_scalar);
|
||||
inline constexpr auto electric_tension_phasor = voltage_phasor;
|
||||
QUANTITY_SPEC(impedance, voltage_phasor / electric_current_phasor); // complex
|
||||
inline constexpr auto complex_impedance = impedance; // complex
|
||||
@@ -134,23 +136,23 @@ QUANTITY_SPEC(impedance_of_vacuum, impedance); // comple
|
||||
inline constexpr auto wave_impedance_in_vacuum = impedance_of_vacuum; // complex
|
||||
QUANTITY_SPEC(
|
||||
resistance_to_alternating_current, impedance,
|
||||
quantity_character::scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity)
|
||||
QUANTITY_SPEC(reactance, impedance, quantity_character::scalar);
|
||||
QUANTITY_SPEC(apparent_impedance, impedance, quantity_character::scalar);
|
||||
quantity_character::real_scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity)
|
||||
QUANTITY_SPEC(reactance, impedance, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(apparent_impedance, impedance, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(admittance, inverse(impedance)); // complex
|
||||
inline constexpr auto complex_admittance = admittance; // complex
|
||||
QUANTITY_SPEC(admittance_of_vacuum, admittance, inverse(impedance_of_vacuum)); // complex
|
||||
QUANTITY_SPEC(
|
||||
conductance_for_alternating_current, conductance,
|
||||
quantity_character::scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity)
|
||||
QUANTITY_SPEC(susceptance, admittance);
|
||||
QUANTITY_SPEC(apparent_admittance, admittance, quantity_character::scalar);
|
||||
quantity_character::real_scalar); // called resistance in the latest ISQ (we use the old name to avoid ambiguity)
|
||||
QUANTITY_SPEC(susceptance, admittance, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(apparent_admittance, admittance, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(quality_factor, dimensionless, reactance / resistance);
|
||||
QUANTITY_SPEC(loss_factor, dimensionless, inverse(quality_factor));
|
||||
QUANTITY_SPEC(loss_angle, angular_measure);
|
||||
QUANTITY_SPEC(active_power, isq::power, inverse(period) * (instantaneous_power * time));
|
||||
QUANTITY_SPEC(complex_power, voltage_phasor* electric_current_phasor); // complex // separate kind
|
||||
QUANTITY_SPEC(apparent_power, complex_power, quantity_character::scalar);
|
||||
QUANTITY_SPEC(apparent_power, complex_power, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(power_factor, dimensionless, active_power / apparent_power);
|
||||
QUANTITY_SPEC(reactive_power, isq::mass* pow<2>(isq::length) / pow<3>(isq::time)); // separate kind
|
||||
QUANTITY_SPEC(non_active_power, pow<1, 2>(pow<2>(apparent_power))); // separate kind
|
||||
|
||||
@@ -60,16 +60,16 @@ QUANTITY_SPEC(impulse, force* time); // vector
|
||||
QUANTITY_SPEC(angular_momentum, position_vector* momentum); // vector
|
||||
QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor);
|
||||
QUANTITY_SPEC(moment_of_force, position_vector* force); // vector
|
||||
QUANTITY_SPEC(torque, moment_of_force, quantity_character::scalar);
|
||||
QUANTITY_SPEC(torque, moment_of_force, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector
|
||||
QUANTITY_SPEC(pressure, force / area, quantity_character::scalar);
|
||||
QUANTITY_SPEC(pressure, force / area, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(gauge_pressure, pressure);
|
||||
QUANTITY_SPEC(stress, pressure, quantity_character::tensor);
|
||||
QUANTITY_SPEC(normal_stress, pressure, quantity_character::scalar);
|
||||
QUANTITY_SPEC(shear_stress, pressure, quantity_character::scalar);
|
||||
QUANTITY_SPEC(normal_stress, pressure, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(shear_stress, pressure, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(strain, dimensionless, quantity_character::tensor);
|
||||
QUANTITY_SPEC(relative_linear_strain, length / length);
|
||||
QUANTITY_SPEC(shear_strain, dimensionless, displacement / thickness, quantity_character::scalar);
|
||||
QUANTITY_SPEC(shear_strain, dimensionless, displacement / thickness, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(relative_volume_strain, volume / volume);
|
||||
QUANTITY_SPEC(Poisson_number, dimensionless, width / length);
|
||||
QUANTITY_SPEC(modulus_of_elasticity, normal_stress / relative_linear_strain);
|
||||
@@ -82,30 +82,32 @@ QUANTITY_SPEC(compressibility, inverse(volume) * (volume / pressure));
|
||||
QUANTITY_SPEC(second_axial_moment_of_area, pow<2>(radial_distance) * area);
|
||||
QUANTITY_SPEC(second_polar_moment_of_area, pow<2>(radial_distance) * area);
|
||||
QUANTITY_SPEC(section_modulus, second_axial_moment_of_area / radial_distance);
|
||||
QUANTITY_SPEC(static_friction_coefficient, dimensionless, static_friction_force / force, quantity_character::scalar);
|
||||
QUANTITY_SPEC(static_friction_coefficient, dimensionless, static_friction_force / force,
|
||||
quantity_character::real_scalar);
|
||||
inline constexpr auto static_friction_factor = static_friction_coefficient;
|
||||
inline constexpr auto coefficient_of_static_friction = static_friction_coefficient;
|
||||
QUANTITY_SPEC(kinetic_friction_factor, dimensionless, kinetic_friction_force / force, quantity_character::scalar);
|
||||
QUANTITY_SPEC(kinetic_friction_factor, dimensionless, kinetic_friction_force / force, quantity_character::real_scalar);
|
||||
inline constexpr auto dynamic_friction_factor = kinetic_friction_factor;
|
||||
QUANTITY_SPEC(rolling_resistance_factor, force / force, quantity_character::scalar);
|
||||
QUANTITY_SPEC(rolling_resistance_factor, force / force, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(drag_coefficient, dimensionless, drag_force / (mass_density * pow<2>(speed) * area),
|
||||
quantity_character::scalar);
|
||||
quantity_character::real_scalar);
|
||||
inline constexpr auto drag_factor = drag_coefficient;
|
||||
QUANTITY_SPEC(dynamic_viscosity, shear_stress* length / velocity, quantity_character::scalar);
|
||||
QUANTITY_SPEC(dynamic_viscosity, shear_stress* length / velocity, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(kinematic_viscosity, dynamic_viscosity / mass_density);
|
||||
QUANTITY_SPEC(surface_tension, force / length, quantity_character::scalar); // TODO what is a correct equation here?
|
||||
QUANTITY_SPEC(power, mass* pow<2>(length) / pow<3>(time)); // not in ISO 80000
|
||||
QUANTITY_SPEC(mechanical_power, power, force* velocity, quantity_character::scalar);
|
||||
QUANTITY_SPEC(surface_tension, force / length,
|
||||
quantity_character::real_scalar); // TODO what is a correct equation here?
|
||||
QUANTITY_SPEC(power, mass* pow<2>(length) / pow<3>(time)); // not in ISO 80000
|
||||
QUANTITY_SPEC(mechanical_power, power, force* velocity, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(mechanical_energy, energy); // differs from ISO 80000
|
||||
QUANTITY_SPEC(potential_energy, mechanical_energy); // differs from ISO 80000
|
||||
QUANTITY_SPEC(kinetic_energy, mechanical_energy, mass* pow<2>(speed)); // differs from ISO 80000
|
||||
QUANTITY_SPEC(mechanical_work, force* displacement, quantity_character::scalar);
|
||||
QUANTITY_SPEC(mechanical_work, force* displacement, quantity_character::real_scalar);
|
||||
inline constexpr auto work = mechanical_work;
|
||||
QUANTITY_SPEC(mechanical_efficiency, mechanical_power / mechanical_power);
|
||||
QUANTITY_SPEC(mass_flow, mass_density* velocity); // vector
|
||||
QUANTITY_SPEC(mass_flow_rate, mass_flow* area, quantity_character::scalar);
|
||||
QUANTITY_SPEC(mass_flow_rate, mass_flow* area, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(mass_change_rate, mass / time);
|
||||
QUANTITY_SPEC(volume_flow_rate, velocity* area, quantity_character::scalar);
|
||||
QUANTITY_SPEC(volume_flow_rate, velocity* area, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(action, energy* time);
|
||||
|
||||
} // namespace mp_units::isq
|
||||
|
||||
@@ -57,7 +57,7 @@ QUANTITY_SPEC(propagation_coefficient, cotes_angle_constant / length);
|
||||
QUANTITY_SPEC(angular_momentum, position_vector* momentum / cotes_angle_constant); // vector
|
||||
QUANTITY_SPEC(moment_of_inertia, angular_momentum / angular_velocity, quantity_character::tensor);
|
||||
QUANTITY_SPEC(moment_of_force, position_vector* force / cotes_angle_constant); // vector
|
||||
QUANTITY_SPEC(torque, moment_of_force, quantity_character::scalar);
|
||||
QUANTITY_SPEC(torque, moment_of_force, quantity_character::real_scalar);
|
||||
QUANTITY_SPEC(angular_impulse, moment_of_force* time); // vector
|
||||
QUANTITY_SPEC(loss_angle, angular_measure);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user