mp-units
mp-units copied to clipboard
Provide proper support for complex quantities
For example the following should be supported (as much as possible):
template<template<auto, typename> typename Q>
concept complex_operations =
requires(Q<isq::voltage_phasor[si::kilo<si::volt>], std::complex<double>> voltage_phasor,
Q<isq::electric_current_phasor[si::ampere], std::complex<double>> electric_current_phasor,
Q<isq::phase_angle[si::radian], double> phase_angle,
Q<isq::complex_power[si::kilo<si::volt> * si::ampere], std::complex<double>> complex_power,
Q<isq::apparent_power[si::kilo<si::volt> * si::ampere], double> apparent_power,
Q<isq::active_power[si::watt], double> active_power,
Q<isq::reactive_power[iec::volt_ampere_reactive_power], double> reactive_power,
Q<isq::power_factor[one], double> power_factor) {
// valid operations
{ voltage_phasor* conj(electric_current_phasor) } -> std::convertible_to<decltype(complex_power)>;
{ complex(active_power, reactive_power) } -> std::convertible_to<decltype(complex_power)>;
{ mod(complex_power) } -> std::convertible_to<decltype(apparent_power)>;
{ re(complex_power) } -> std::convertible_to<decltype(active_power)>;
{ im(complex_power) } -> std::convertible_to<decltype(reactive_power)>;
{ arg(complex_power) } -> std::convertible_to<decltype(phase_angle)>;
{ active_power / apparent_power } -> std::convertible_to<decltype(power_factor)>;
{ reactive_power.in(si::volt * si::ampere) }; // has to work according to ISO 80000
// invalid operations
requires !requires { active_power + reactive_power; };
requires !requires { complex(apparent_power, reactive_power); } -> std::convertible_to<decltype(complex_power)>; // ?
requires !requires { complex(reactive_power, active_power); } -> std::convertible_to<decltype(complex_power)>;
requires !requires { complex_power = apparent_power; };
requires !requires { complex_power = active_power; };
requires !requires { complex_power = reactive_power; };
requires !requires { active_power = complex_power; };
requires !requires { active_power = reactive_power; };
requires !requires { active_power = apparent_power; }; // ?
requires !requires { reactive_power = complex_power; };
requires !requires { reactive_power = active_power; };
requires !requires { reactive_power = apparent_power; };
requires !requires { complex_power.in(iec::volt_ampere_reactive_power); };
requires !requires { active_power.in(iec::volt_ampere_reactive_power); };
requires !requires { apparent_power.in(iec::volt_ampere_reactive_power); };
requires !requires { complex_power.in(si::watt); };
requires !requires { apparent_power.in(si::watt); };
// probably impossible to enforce
requires !requires { active_power.in(si::watt * si::ampere); };
};
static_assert(complex_operations<quantity>);