SymbolicML / DynamicQuantities.jl

Efficient and type-stable physical quantities in Julia
https://symbolicml.org/DynamicQuantities.jl/dev/
Apache License 2.0
132 stars 17 forks source link

What is the recommended way of dealing with non-SI units? #52

Closed klaff closed 11 months ago

klaff commented 1 year ago

For example, if one wants to be able to use miles/hour, we can do mile = 5280 * 12 * 0.0254u"m" followed by 60 * mile/u"hr" or because the latter is clumsy, maybe we use mph = mile/u"hr" after which we can use mph.

Is there thought about whether the user should be allowed to register new units which could then be used within the u"..." strings?

MilesCranmer commented 1 year ago

If you only wish to avoid converting to SI, one option is to use symbolic units: https://github.com/SymbolicML/DynamicQuantities.jl#symbolic-units.

You can also define custom dimensions structs: https://github.com/SymbolicML/DynamicQuantities.jl/blob/87e1eb3d0d4c139ed94a563e2fae3cababc5e512/test/unittests.jl#L444-L448

which you could set the default unit system to something else rather than SI.

However, to just register a unit, it's probably safer to just define your own @u_str macro with the different units you would like to make available in the same scope eval is executed.

While you could technically do DynamicQuantities.Units.eval(:(const mph = ...)) for every unit, which would make them available to uparse, this is not at all a safe or robust approach. Globally registering units like this is dangerous so I would recommend the former strategies.

klaff commented 1 year ago

I'm happy to have all the calculations happen in SI and actually prefer to do so. I'm just looking for the cleanest way to convert things on the way in and on the way out. For example, in a previous life I did a lot of DC motor work, and the input units around torque and inertia can be pretty strange. But even for the output, no human (that I know of) thinks in radians/second, so that has to get converted to RPM (which is not of course SI).

P.S. I was happy to see the clever support for fractional powers, as one of my tests for a unit system is if it can handle the motor constant which is in dimensions of torque per sqrt(power).

MilesCranmer commented 1 year ago

Cool! Okay so once https://github.com/SymbolicML/DynamicQuantities.jl/pull/48 merges, we should be good to go if its just conversion. Then you could do, for example,

0.5u"1/s" |> as_u("1/min")

which would display it in symbolic dimensions of 1/minute. But we're still discussing the API over in that PR.

Cheers, Miles

P.S. I was happy to see the clever support for fractional powers, as one of my tests for a unit system is if it can handle the motor constant which is in dimensions of torque per sqrt(power).

Awesome, I am glad to hear it has found a use-case!

klaff commented 1 year ago

Thank you for the pointer to that discussion. I think that will probably cover my questions.

MilesCranmer commented 11 months ago

Closed with #48

MilesCranmer commented 10 months ago

@klaff FYI we just added mi, ft, and inch.