C++ Logo

std-proposals

Advanced search

Re: [std-proposals] On the standardization of mp-units P3045R1

From: Mateusz Pusz <mateusz.pusz_at_[hidden]>
Date: Wed, 19 Jun 2024 13:45:18 +0200
While writing the answer to Ville, I realized that there is one more issue.
We will have to write:

quantity_point qp(20 * rel_deg_C);
std::cout << qp.in(rel_deg_F).quantity_from_zero();

Which might be confusing for scaling quantity_point. Also, we will need to
add `rel_` to Kelvins and all its prefixes for the same reason as in the
other email.

śr., 19 cze 2024 o 13:26 Sebastian Wittmeier via Std-Proposals <
std-proposals_at_[hidden]> napisał(a):

> For the specific heat capacity, rel_deg_C is correct anyway, as it is not
> related to the absolute temperature, is it?
>
>
>
>
>
> For the ideal gas law, R, however, is more problematic:
>
>
>
> auto R = 8.314 * N * m / (rel_deg_C * mol)
>
>
>
> All or all except one unit have to be quantity points. But they are all
> quantities.
>
> But one cannot (with the current library) calculate with quantity points.
>
>
>
> That is an error, which was in mp-units before.
>
>
>
> I find it less problematic at the formulas than when defining the input
> value, because beginners would rather define values than formulas. Formulas
> are hopefully tested at least with one set of values.
>
> And if an absolute temperature is provided as an input with type quantity
> point then the code for the formula has to deal with it by converting back
> to a relative temperature (e.g. relative to T0)..
>
>
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Mateusz Pusz <mateusz.pusz_at_[hidden]>
> *Gesendet:* Mi 19.06.2024 13:01
> *Betreff:* Re: [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
> *CC:* Sebastian Wittmeier <wittmeier_at_[hidden]>;
> Hi Sebastian,
>
> You are right, and that is actually a really good idea! :-)
> Sure, we can do that.
>
> The only downside I see is that we will have to write something like the
> below for the specific heat capacity or similar units:
>
> quantity<J / (kg * rel_deg_C)> specific_heat_capacity = 42 * J / (kg *
> rel_deg_C);
>
> śr., 19 cze 2024 o 12:24 Sebastian Wittmeier via Std-Proposals <
> std-proposals_at_[hidden]> napisał(a):
>
> Hi Mateusz,
>
>
>
> If I understand correctly, the library introduces types and objects for
> the units of the same name.
>
>
>
> If one makes an exception from this rule for °C:
>
> - The type is called `deg_C`
>
> - The object is called `rel_deg_C`
>
> - (+ the same for Fahrenheit)
>
>
>
> Then
>
>
>
> auto t20 = (20 * rel_deg_C)
>
> is a quantity of 20°C temperature difference and of type `quantity<deg_C,
> int>`
>
>
>
> auto at20a = quantity_point qp1(t20)
>
> or
>
> auto at20b = zeroth_degree_Celsius + t20
>
>
>
> are quantity points of 20°C absolute temperature and of type
> quantity_point<deg_C, ice_point, int>
>
>
>
> Then we do not need 2 units or 2 types
>
> As far as I understand the same name was used for simplicity and better
> compiler error messages, should still be similar enough and clear enough
>
> The internal type makes sense both for quantity and quantity point
>
> We keep full genericity and no actual special casing for temperature
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Mateusz Pusz <mateusz.pusz_at_[hidden]>
> *Gesendet:* Mi 19.06.2024 08:35
> *Betreff:* Re: [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
> *CC:* Sebastian Wittmeier <wittmeier_at_[hidden]>;
> Unfortunately, there are some other issues here as well. If we introduce
> two independent units like rel_deg_C and abs_deg_C we will have to make
> them somehow aware of each other and support this in the framework. Let's
> see the following code:
>
> quantity_point qp1(20 * rel_deg_C); // should instantiate
> quantity_point<abs_deg_C, ice_point, int>
> quantity_point qp2(15 * rel_deg_C); // should instantiate
> quantity_point<abs_deg_C, ice_point, int>
> quantity q = qp1 - qp2; // should instantiate quantity<rel_deg_C, int>
>
> wt., 18 cze 2024 o 21:44 Sebastian Wittmeier via Std-Proposals <
> std-proposals_at_[hidden]> napisał(a):
>
> Ok, than really use two units: rel_deg_C and abs_deg_C.
>
>
>
> quantity_point(...).in(abs_deg_C) would be accepted
> quantity_point(...).in(rel_deg_C) would not
>
>
>
> So no longer confusing.
>
>
>
> Similar for all other usages: The one making sense works.
>
> The one not making sense is not accepted.
>
>
>
>
>
> Why special-case temperature compared to other units?
>
> ============================================
>
> temperatures are used very often as quantity point,
>
> the quantity point has a general physical meaning (as the reference is
> defined),
>
> and the reference point is != 0 (at least for °C and °F unlike K).
>
>
>
> What about generic code?
>
> ====================
>
> Generic code should be able to access quantity and quantity point in an
> identical (but possibly more verbose) way for all units, temperature and
> others
>
>
>
> What about possible other units similar to temperature?
>
> ============================================
>
> Perhaps the library should allow this same special-casing for user-defined
> units, too.
>
>
>
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Mateusz Pusz <mateusz.pusz_at_[hidden]>
> *Gesendet:* Di 18.06.2024 16:56
> *Betreff:* Re: [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
> *CC:* Sebastian Wittmeier <wittmeier_at_[hidden]>;
> Unfortunately, this is not that easy. Let's see this example:
>
> quantity_point temp(300. * K);
> std::cout << temp.in(deg_C).quantity_from_zero() << " " << temp.in(deg_F).quantity_from_zero()
> << "\n";
>
>
> This prints:
>
> 26.85 °C 80.33 °F
>
> Using `rel_deg_C` and `rel_deg_F` would be confusing here.
>
> Best
>
> Mat
>
> wt., 18 cze 2024 o 16:49 Sebastian Wittmeier via Std-Proposals <
> std-proposals_at_[hidden]> napisał(a):
>
> Then just change deg_C to rel_deg_C to prevent misuse
>
> so
>
>
>
> 23 * rel_deg_C
>
>
>
> would work for a temperature difference and
>
>
>
> quantity_point(28.0 * rel_deg_C)
>
>
>
> would be needed for the absolute temperature of 301K.
>
> One can always later on define a nicer-looking shortcut for the second one.
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Mateusz Pusz <mateusz.pusz_at_[hidden]>
> *Gesendet:* Di 18.06.2024 16:37
> *Betreff:* Re: [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
> *CC:* Sebastian Wittmeier <wittmeier_at_[hidden]>;
> `deg_C` is just a symbol for the `si::degree_Celsius` unit. We could
> consider not providing Celsius and Fahrenheit units at all, but this would
> make many users unhappy. Degree Celsius is one of the official SI units (
> https://en.wikipedia.org/wiki/International_System_of_Units#Derived_units),
> and not providing support for it would be problematic.
>
> The affine space abstraction is the best solution for the temperature
> problem according to our knowledge and experience:
> - when we state that today is 4 degree Celsius warmer than yesterday we
> mean the `quantity`
> - when we state that today temperature is 23 degree Celsius we mean the
> `quantity_point`
>
> To prevent errors and to be consistent with maths, quantity_point does not
> multiply and divide with other units. We can only add or subtract an offset
> from it or subtract another point to get a quantity.
> Multiply syntax (e.g., 23 * deg_C) always results in a quantity and not a
> quantity_point.
>
> For the sake of correctness, we could add a dirty hack to the generic
> framework that would disable the multiply syntax for temperatures only.
> With this, the user would always have to write something like this:
>
> quantity_point temperature(quantity(28.0, deg_C)); //
> zeroth_degree_Celsius point origin provided by default here
> quantity temperature_delta(3.0, deg_C);
>
>
> But I am not sure if this would be better.
>
> Best
>
> Mat
>
> wt., 18 cze 2024 o 16:18 Sebastian Wittmeier via Std-Proposals <
> std-proposals_at_[hidden]> napisał(a):
>
> Hi Mateusz,
>
>
>
> how about the (in one of the messages by me today) suggested
>
>
>
> rel_deg_C is a quantity
>
>
>
> vs.
>
>
>
> abs_deg_C is a quantity_point
>
>
>
> ?
>
>
>
> That would prevent bugs, which are easy to introduce for temperature by
> making that distinction explicit.
>
>
>
>
>
> Or alternative spellings: deg_rel_C / deg_C_rel
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Mateusz Pusz via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Di 18.06.2024 15:54
> *Betreff:* Re: [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
> *CC:* Mateusz Pusz <mateusz.pusz_at_[hidden]>; Chip Hogg <chogg_at_[hidden]>;
> Johel Ernesto Guerrero Peña <johelegp_at_[hidden]>; Anthony Williams <
> anthony_at_[hidden]>;
> Hi,
>
> Tiago, some time has passed since your last complaint about the same
> problem. We invited you to our internal meeting, listened to your concerns,
> and discussed how we can improve here. As you know, the answer was not
> found at the meeting. Additionally, you stated that you don't want to work
> to contribute to our proposal and repository and that you will come back
> with a better interface soon. More info can be found here:
> https://github.com/mpusz/mp-units/discussions/552. Did you manage to find
> a better solution to this problem? If so we are open to rediscuss your
> solution whenever you are ready.
>
> For all other participants of this mailing list, here is a correct
> solution:
>
> #include <mp-units/ostream.h>
> #include <mp-units/systems/si.h>
> #include <iostream>
>
> using namespace mp_units;
>
> inline constexpr struct atmospheric_pressure final : named_unit<"atm",
> mag<101'325> * si::pascal> {} atmospheric_pressure;
>
> int main()
> {
> using namespace mp_units::si::unit_symbols;
>
> quantity Volume = 1.0 * m3;
> quantity_point Temperature(28.0 * deg_C);
> quantity n_ = 0.04401 * kg / mol;
> quantity R_boltzman = 8.314 * N * m / (K * mol);
> quantity mass = 40.0 * kg;
> quantity Pressure = R_boltzman * Temperature.in(K).quantity_from_zero()
> * mass / n_ / Volume;
> std::cout << Pressure.in(Pa) << "(" <<
> Pressure.in(atmospheric_pressure) << ")\n";
> }
> https://godbolt.org/z/E8bf51hKG
>
> Temperatures are tricky, and there is no good default here. People often
> mean either a point or a difference, depending on the context. In case
> anyone has an idea on how to improve, we are open to feedback.
>
> Best
>
> Mat
>
> wt., 18 cze 2024 o 15:30 Sebastian Wittmeier via Std-Proposals <
> std-proposals_at_[hidden]> napisał(a):
>
> How about the following scales? Are they also an issue?
>
>
>
>
>
> - Time (Calendar) relative to either anno domini or Unix time?
> - Position Coordinate relative to Greenwich?
> - Electric Potential relative to earth potential?
> - pH, pKa, pKb scales relative to a neutrality of 7?
> - Decibels, phon and sone relative to threshold of human hearing?
> - Pressure (hydraulic or blood) relative to atmospheric pressure?
> - Altitude relative to sea level?
>
> -> For pressure and altitude there are lots of other scales, e.g. used
> in aviation
> - Richter scale relative to detectable earthquakes?
> - Beaufort relative to calm wind instead of zero wind?
> - Borg physical exertion not starting at zero?
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
> wt., 18 cze 2024 o 15:44 Tiago Freire via Std-Proposals <
> std-proposals_at_[hidden]> napisał(a):
>
> I understand what the problem is, that is why I’m bringing it forward.
>
> My concerned is that I haven’t written any code that anyone wouldn’t have
> written and got the wrong answer.
>
>
>
> > An absolute value in the paper is a quantity_point, a possibly relative
> value is a quantity.
>
>
>
> Which is a perspective, not convinced that it is the right thing. But That
> also poses the question, volume is also an absolute value, so is the mass,
> pressure, etc..
>
>
>
> Which means that the right way to write it would be this:
>
> ```
>
> quantity_point Volume {1.0 * m*m*m};
>
> quantity_point Temperature {si::ice_point + 28.0 * deg_C};
>
> quantity_point n_{0.04401 * kg / mol};
>
> quantity R_boltzman = 8.314 * N * m / (K * mol);
>
> quantity_point mass {40.0 * kg};
>
> quantity_point P = R_boltzman * Temperature * mass / n_ / Volume;
>
> std::cout << Pressure << std::endl;
>
> ```
>
>
>
> But this doesn’t compile because quantity_point can’t math.
>
> In order to get it to compile you would have to do this instead:
>
> ```
>
> quantity_point Pressure = quantity_point{0.0*Pa} + R_boltzman *
> (Temperature - mp_units::si::absolute_zero) * (mass -
> quantity_point{0.0*kg}) / (n_ - quantity_point{0.0*kg / mol}) / (Volume -
> quantity_point{0.0* m*m*m});
>
> ```
>
> Which doesn’t even module the problem properly because the values in
> PV=nRT are supposed to be absolute values, not deltas.
>
>
>
> Hence it raises the question, doing what it seems obvious is the wrong
> thing (thus questionably safe), and doing the right thing is kind of hard
> (thus questionably user-friendly). But that what is expected as the correct
> way to use it.
>
>
>
>
>
> *From:* Std-Proposals <std-proposals-bounces_at_[hidden]> *On Behalf
> Of *Sebastian Wittmeier via Std-Proposals
> *Sent:* Tuesday, June 18, 2024 15:03
> *To:* std-proposals_at_[hidden]
> *Cc:* Sebastian Wittmeier <wittmeier_at_[hidden]>
> *Subject:* Re: [std-proposals] On the standardization of mp-units P3045R1
>
>
>
> You are specifically talking about
>
>
>
>
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3045r1.html#potential-surprises-while-working-with-temperatures
>
>
>
>
>
> Discussing the difficulty, when to use a difference in temperature or an
> absolute temperature.
>
>
>
> An absolute value in the paper is a quantity_point, a possibly relative
> value is a quantity.
>
>
>
>
>
> If I understand correctly, in the current paper to initialize and use
> absolute temperatures
>
>
>
> quantity_point qp2 = (isq::Celsius_temperature(28.0 * deg_C)).in(K)
>
> and
>
> qp2.quantity_from_zero()
>
>
>
>
>
> would have to be used instead of
>
>
>
> quantity Temperature = (28.0 * deg_C).in(K);
>
>
>
> The paper also says
>
>
>
> "We have added the Celsius temperature quantity type for completeness and
> to gain more experience with it. Still, maybe a good decision would be to
> skip it in the standardization process not to confuse users."
>
>
>
>
>
>
>
>
>
>
>
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Sebastian Wittmeier <wittmeier_at_[hidden]>
> *Gesendet:* Di 18.06.2024 14:42
> *Betreff:* AW: [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
>
> Hi Tiago,
>
> where does this difference of 11x come from?
>
> The temperature with 28°C vs. 301K?
>
>
> -----Ursprüngliche Nachricht-----
> *Von:* Tiago Freire via Std-Proposals <std-proposals_at_[hidden]>
> *Gesendet:* Di 18.06.2024 14:28
> *Betreff:* [std-proposals] On the standardization of mp-units P3045R1
> *An:* std-proposals_at_[hidden];
> *CC:* Tiago Freire <tmiguelf_at_[hidden]>;
>
> Hi, I will be participating in St. Louis.
>
> And one of the papers that interested me was P3045R1, unfortunately I may
> or may not be on time to participate in this particular session.
>
>
>
> There’s this question that I would like an answer too, and I wonder if
> there is anyone who will be attending St. Louis who would be willing to
> make this question on my behalf:
>
>
>
>
>
>
>
> A lab worker puts in 40Kg of dry ice into a 1 cubic meter pressure tank
> rated for 10atm, they then vacuum the tank and seal it.
>
> As the CO2 warms up to room temperature (which at a specific date was
> 28°C) it evaporates, and eventually following the ideal gas law:
>
> PV=nRT
>
>
>
> Is this setup dangerous?
>
>
>
> Using mp-units (with the exact same design as the one being proposed for
> standardization) to solve this problem:
>
>
>
> ```
>
> quantity Volume = 1.0 * m*m*m;
>
> quantity Temperature = (28.0 * deg_C).in(K);
>
> quantity n_ = 0.04401 * kg / mol;
>
> quantity R_boltzman = 8.314 * N * m / (K * mol);
>
> quantity mass = 40.0 * kg;
>
> quantity Pressure = R_boltzman * Temperature * mass / n_ / Volume;
>
> std::cout << Pressure << std::endl;
>
> ```
>
>
>
> We get the following result:
>
> `211581 N/m2`
>
> (=211.581kPa = 2,09 atm)
>
> But the correct answer is actually: 2275.629kPa = 22.5 atm
>
> (11 time s higher than what mp-units calculated)
>
>
>
> How is this considered a design feature and not a bug? (note that other
> similar libraries don’t have this problem)
>
> And how do the authors think this design choice impacts on safety and
> user-friendliness?
>
>
>
>
>
> Thanks.
>
>
>
>
>
> -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2024-06-19 11:45:34