Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency with converting units #259

Open
ArneSpang opened this issue Feb 25, 2025 · 5 comments
Open

Inconsistency with converting units #259

ArneSpang opened this issue Feb 25, 2025 · 5 comments

Comments

@ArneSpang
Copy link
Contributor

I am not sure if this is a concern of GeoParams or Unitful, but I think that this behavior is a bit silly:

using GeoParams
a = 1*MPa
b = 5e5*Pa
c = 0.5*MPa

julia> a+b
1.5e6 kg m^-1.0 s^-2.0 <-- recognizes the units as same and reduces to SI

julia> a+c
1.5 MPa <-- recognizes the units as same and doesn't reduce to SI

julia> a/b
2.0e-6 MPa Pa^-1.0 <-- does not recognize units as same and does not cancel them

julia> a/c
2.0 <-- works

julia> uconvert(NoUnits, a/b)
2.0 <-- works but requires you to know the unit before

julia> a*b
500000.0 Pa MPa <-- does not recognize units as same and does not combine them

julia> a*c
0.5 MPa^2.0 <-- works

julia> uconvert(u"MPa^2", a*b)
0.5 MPa^2.0 <-- works but requires you to know the unit before

Same thing happens if b is in J/m^3 which is equivalent to Pa

@albert-de-montserrat
Copy link
Member

albert-de-montserrat commented Feb 25, 2025

Thanks for reporting! I will take a better look, but some of this issues may actually come from Unitful.

julia> a*b
500000.0 Pa MPa

This is worrying...

@ArneSpang
Copy link
Contributor Author

I can add another example, maybe this helps to understand whats going on

using GeoParams
E = 500kJ/mol
V = 15cm^3/mol
P = 2000MPa
R = 8.314J/mol/K
T = 800K

julia> (E + P*V)/(R*T)
79.68486889583835 kg m^2.0 J^-1.0 s^-2.0 <-- this should all cancel

julia> exp((E + P*V)/(R*T))
4.0429544897502273e34 <-- exponential seems to force the resolution of the units

@Iddingsite
Copy link
Collaborator

Commenting on that, as I remember having the same problem some years ago. It is an issue coming from Unitful, which doesn't convert automatically when the units are different, when things can cancel. The reasonning behind that behaviour, is that for some units, you don't want the units to cancel out by default. For instance, if you have somehow a unit of kg / Pa, it is often useful to keep like that, than to have m s^2 output.
So:

using GeoParams
a = 2kg
b = 1Pa
julia> a / b
2.0 kg Pa⁻¹·⁰

whereas

using GeoParams
a = 2kg
b = 1kg/m/s^-2
julia> a / b
2.0 m s⁻²·⁰

because the same units are used.

Now, the problem is that there is no default parameter you could modify to change that behaviour (see for instance PainterQubits/Unitful.jl#373). So the common practice to work around that is to use upreferred()when you want to force it (see for example https://discourse.julialang.org/t/make-unitful-simplify-expressions-like-1-m-1m-to-a-unitless-value-by-default/71866/9). In this case, you don´t need to know the units of interest, like with uconvert().

So, in your case:

using GeoParams
E = 500kJ/mol
V = 15cm^3/mol
P = 2000MPa
R = 8.314J/mol/K
T = 800K

julia> (E + P*V)/(R*T) |> upreferred
79.68486889583835

The drawback of that, it that it converts to the units preferred, which is by default SI. So your Pa will be converted to kg/m/s^-2 even if you want it to keep showing up as Pa.

The reason why exp((E + P*V)/(R*T)) is automatically without unit, is because the exponential operation is by default dimensionless, as it is defined as a power series ($e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!}$). So it has to return something dimensionless.

@ArneSpang
Copy link
Contributor Author

@Iddingsite that is some useful insight. This is why I posted the example with the exponential. To see if we find something that forces simplification of units. upreferred() seems to be that. exp probably calls NoUnits internally.

@Iddingsite
Copy link
Collaborator

Yes, your guess is correct concerning the exp (and the equivalent functions for log). The relevant lines in Unitful are here:

https://github.com/PainterQubits/Unitful.jl/blob/d869c3614969186ae21f9029216eadaf99e3e5c8/src/quantities.jl#L424-L426

for f in (:exp, :exp10, :exp2, :expm1, :log, :log10, :log1p, :log2)
    @eval ($f)(x::DimensionlessQuantity) = ($f)(uconvert(NoUnits, x))
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants