connorferster / forallpeople

Python SI units library: your 'daily driver' for calculations.
Apache License 2.0
295 stars 39 forks source link

incorrect transformation of quantities #80

Open asteqast opened 1 year ago

asteqast commented 1 year ago

Hi,

Was happy to discover Handcalcs + forallpeople, which are very useful in engineering. Tried to solve a simple problem in structural dynamics, and got into trouble. Was trying to display mass in tonnes instead of Mg (I know it is according SI, but for practical reasons just have to display it in tonnes). Added "tonnes" to json, but was getting wrong results. Below are a few calculations that lead to weird results, reproduced with the original "structural" environment.

Everything is fine when SI units are used:

import forallpeople
forallpeople.environment('structural', top_level=True)

K = (500e3*N_m)
M = 20000*kg
omega_n = (K / M)**0.5 
A = 1*m * omega_n**2
display(A)
display(A.repr)

25.000 m⋅s-2.0 'Physical(value=25.0, dimensions=Dimensions(kg=0.0, m=1.0, s=-2.0, A=0.0, cd=0.0, K=0.0, mol=0.0), factor=1, precision=3, prefixed=)'

However, when the first quantity is transformed to imperial units (kip/ft):

K = (500e3*N_m).to("kip_ft")
M = 20000*kg
omega_n = (K / M)**0.5 
A = 1*m * omega_n**2
display(A)
display(A.repr)

364847.573 m⋅s-2.0 'Physical(value=25.0, dimensions=Dimensions(kg=0.0, m=1.0, s=-2.0, A=0.0, cd=0.0, K=0.0, mol=0.0), factor=1.4594e+04, precision=3, prefixed=)'

The problem seems to happen due to the way the scaling factor for unit transformation is computed. The units of the result are correct in both case (m/s2), and the .value property is the same (25 m/s2), but in the second case the result shown is wrong, as it is affected by the .factor property.

Also came upon the following strange behaviour when defining custom units (tonnes):

    "t": {
        "Dimension": [1,0,0,0,0,0,0],
        "Symbol": "t",
        "Factor": "0.001"},
    "tt": {
        "Dimension": [1,0,0,0,0,0,0],
        "Factor": "0.001"},

The only difference between the two is that "Symbol" is missing from the second one. The .value properties of the obtained Physicals are though different: t.repr

'Physical(value=1000.0, dimensions=Dimensions(kg=1, m=0, s=0, A=0, cd=0, K=0, mol=0), factor=0.001, precision=3, prefixed=)'

tt.repr

'Physical(value=1.0, dimensions=Dimensions(kg=1, m=0, s=0, A=0, cd=0, K=0, mol=0), factor=0.001, precision=3, prefixed=)'

This does not look like the intended behaviour. Not sure it is related to the issue above.

Thanks

thisisapple commented 1 month ago

I have a similar issue. The correct result for x_3 should be 234 lbf. The conversion is wrong from the library.


a = 6 * si.inch

f = 13 * si.psi

x_3 = 0.5 * a**2 * f

print(f'f = {f}')
print(f'a = {a}')
print(f'x_3 = {x_3}')

image