I am using Unyt module for python and found unexpected, resp. "unintuitive" results.
In simple code I tried to brake down problem.
What I am trying to achieve:
a = 23\*kN/m
b = N/m
c = a/b = (23\*kN/m) / (N/m) = 23000 #dimensionless
I have found solution, which is giving me desired results, I just doubt if the approach is correct.
Code:
import unyt as u
from unyt import m, kN, N
a = 23*kN/m
b = N/m
c = a/b
print(f"{type(a) = }")
print(f"{type(b) = }")
print(f"{type(c) = } \n")
print(f"{c = } \n")
# Expected 'unyt_quantity(23000, 'dimensionless')', got 'unyt_quantity(23, 'kN/N')'
# Well technically true
print(f"{c.units = } \n")
# Expected 'dimensionless', got 'kN/N' - technically true
print(f"{c.units.simplify() = }") # Expected 1000, got 1000
print(f"{c = } \n")
# Expected 'unyt_quantity(23000, 'dimensionless')', got 'unyt_quantity(23, '1000')'
# After .simplify() units get obviously altered permanently
# from 'unyt_quantity(23000, 'kN/N') to 'unyt_quantity(23, '1000')
print(f"{c*c.units.simplify() = } \n")
# Not intuitive result, but after logic above, it is actualy:
# 23 * unit(1000) * unit(1000) = 23*unit(1000000)
print(f"{c.v*c.units.simplify() = } \n")
# Again, results are ok, but not expected from math/intuitive point of view
# >>> c.v*c.units.simplify() = unyt_quantity(23, '1000')
print(f"{float(str(c.units.simplify()))*c.v = }")
# This is giving results I am searching for, but feels more as workaround,
# rather than correct approach
"""
Expected math approach:
c = a / b
c = (23 * kN/m) / (N/m)
c = (23 * 1000*N/m) / (N/m)
c = 23000 * (N/m) / (N/m)
c = 23000 * 1/1
c = 23000
"""
Output:
type(a) = <class 'unyt.array.unyt_quantity'>
type(b) = <class 'unyt.unit_object.Unit'>
type(c) = <class 'unyt.array.unyt_quantity'>
c = unyt_quantity(23, 'kN/N')
c.units = kN/N
c.units.simplify() = 1000
c = unyt_quantity(23, '1000')
c*c.units.simplify() = unyt_quantity(23, '1000000')
c.v*c.units.simplify() = unyt_quantity(23, '1000')
float(str(c.units.simplify()))*c.v = 23000.0
If I use float(str(c.units.simplify()))*c.v, it will give me solution I am searching for, but I doubt that it is correct approach.
Also I do already understand, that c.units.simplify() is resulting in 1000 as unit and not number, therefor, any number multiplication is result of "number '1000'" and not "number×1000".
If there is someone, who understand better way, I would be more than happy for such help.
As far as I understand, the problem is, that variable b = N/m is considered as <class 'unyt.unit_object.Unit'> and not <class 'unyt.array.unyt_quantity'>.
Therefore, c = a/b resulting in 23 kN/N seems unexpected, but is indeed correct.
Rewriting code to:
or
will result in 23000 dimensionless.
If we use afterwards:
It will give desired result of 23000.
To fully answer the question, best approach is to ensure that same <class 'unyt.array.unyt_quantity'> classes are used for math computing and not being confused with <class 'unyt.unit_object.Unit'>.