# Computations with units (meters, seconds, ...)

**URL:** <https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383>\
**Category:** Poll\
**Created:** [June 12, 2021, 11:35am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383 "2021-06-12T11:35:22Z")\
**Posts on this page:** 20\
**Page:** 2

<div class="post-metadata">

**Author:** ![PeterSimon](https://avatars.discourse-cdn.com/v4/letter/p/958977/32.png) [@PeterSimon](https://fortran-lang.discourse.group/u/PeterSimon)\
**Post date:** [July 5, 2021, 9:53pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/22 "2021-07-05T21:53:33Z")

</div>

I suggest that you also check out the Julia package [Unitful.jl](https://github.com/PainterQubits/Unitful.jl) which is the defacto standard package for unit support in Julia. It accommodates both SI and arbitrary units, and supports arithmetic involving quantities with different units, dimensional analysis, etc.

---

<div class="post-metadata">

**Author:** ![R\_cubed](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/r_cubed/32/263_2.png) [@R\_cubed](https://fortran-lang.discourse.group/u/R_cubed)\
**Post date:** [July 5, 2021, 10:44pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/23 "2021-07-05T22:44:58Z")

</div>

Just to add to the list of languages that considers this problem, I’ve seen units of measure included in F#.

> **[Units of Measure - F#](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/units-of-measure)**
>
> Learn how floating point and signed integer values in F# can have associated units of measure, which are typically used to indicate length, volume, and mass.

---

<div class="post-metadata">

**Author:** ![arclight](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/arclight/32/430_2.png) [@arclight](https://fortran-lang.discourse.group/u/arclight)\
**Post date:** [July 6, 2021, 1:50pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/24 "2021-07-06T13:50:33Z")

</div>

Identifying the use cases up front is critical if only so people can identify which unit issue they’re trying to resolve. An issue to consider is how solutions for one use case interact with or preclude the solutions of others. For example, would native dimensioned types simplify writing contracts?

This is a much needed effort to clarify what we mean when we say Fortran should handle units. If this was an easy problem, someone would have sorted it out by now…

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 6, 2021, 5:30pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/26 "2021-07-06T17:30:45Z")

</div>

As @pmk said, I also always assumed this would be part of the Fortran language, and the compiler checks this at compile time with no runtime overhead. It would be an extension to the type system in a way. I like this idea at this general level. I don’t know after syntax is developed and all corner cases handled, if it will be straightforward in the compiler and easy to use for the user. But we should try to implement a prototype in a compiler and play with it.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 6, 2021, 5:53pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/28 "2021-07-06T17:53:09Z")

</div>

I agree with @certik and @pmk above.

As a practicing engineer and scientist, already have an inhouse, proprietary, and also user-friendly library solution that is workable. The same situation applies to many other teams and products, particularly in the commercial domains. Thus there is little to no interest in anything different i.e., unless it’s part of the Fortran language and is also **compile-time** in nature.

In another [**thread**](https://fortran-lang.discourse.group/t/user-defined-functions-in-constant-expressions/1509/2), I am trying to encourage Fortran standard-bearers and its Community to start envisioning enhanced **compile-time** functionality.

Along the same vein, I encourage anyone interested in the topic of this thread to see this [**paper**](https://www.stroustrup.com/sac10-constexpr.pdf) by Dos Reis and Stroustrup. See how their **vision** for enhanced `constant expression` support as well as compile-time computing and reduced or zero runtime overheads is enabled as well as illustrated by a scientific use case, the one involving physical quantities and unit-of-measure conversions.

Fortran needs the same kind of visionary thinking and practitionary zeal as those shown by Dos Reis and Stroustrup et al. for other languages. Unfortunately so much of the thinking around Fortran is relentlessly clouded and hampered by a focus on costs rather than better **for** mula **tran** slation that consequently helps advance science, technology, engineering, etc. whose benefits to life and the planet are immeasurably positive.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 6, 2021, 6:12pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/30 "2021-07-06T18:12:43Z")

</div>

> [@pmk](#):
>
> real, intent (in), units (kg\*m/s\*\*2) :: force

I would hope instead that anything which becomes part of the language will be more fundamental and the notional syntax can be illustrated as

```Fortran
real, physical_quantity(dimension="LMT-2") :: some_force ! or some such representation of dimension of quantities

```

and later when conversions can be introduced, it may include

```Fortran
real, physical_quantity(dimension="LMT-2",unit="N") :: some_force

```

c.f. [International System of Quantities - Wikipedia](https://en.wikipedia.org/wiki/International_System_of_Quantities#Base_quantities)

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 6, 2021, 7:03pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/32 "2021-07-06T19:03:11Z")

</div>

> [@pmk](#):
>
> We should draft a design and prototype it. Something that makes units look like regular multiplication and division would be readable and straightforward to check at compilation; conversions can follow.

Let’s do that.

> [@pmk](#):
>
> real, intent (in), units (kg\*m/s\*\*2) :: force

Maybe `unit` instead of `units`, but that’s minor.

Here is a more developed proposal:

- [“Physical” or “Engineering” Units of Measure · Issue #50 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/50)

This might be enough details to prototype. At this level, these are only used in semantic checking, no code generation will change. One would have to store them in the `mod` files. But I think that’s it.

What are some good use cases for units? I don’t have too many right now, but once we have a prototype, people will play with it and create some nice use cases hopefully.

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 6, 2021, 7:24pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/33 "2021-07-06T19:24:23Z")

</div>

Here is an example to work out:

```fortran
    function laplace(N, Niter, dx, dy) result(u)
    integer, intent(in) :: N, Niter
    real(dp), intent(in) :: dx, dy
    real(dp) :: u(N,N)
    integer :: i
    u(1,:) = 1
    u(2:,:) = 0
    do i = 1, Niter
        u(2:N-1,2:N-1) = ((u(3:,2:N-1) + u(:N-2,2:N-1))*dy**2 + &
            (u(2:N-1,3:) + u(2:N-1,:N-2))*dx**2) / (2*(dx**2 + dy**2))
    end do
    end function

```

The `u` is a scalar physical quantity, say it’s a temperature, so units will be Kelvin [K]. Here is how it could look like with `units`:

```fortran
    function laplace(N, Niter, dx, dy) result(u)
    use iso_fortran_units, only: m, K
    integer, intent(in) :: N, Niter
    real(dp), unit(m), intent(in) :: dx, dy
    real(dp), unit(K) :: u(N,N)
    integer :: i
    u(1,:) = 1
    u(2:,:) = 0
    do i = 1, Niter
        u(2:N-1,2:N-1) = ((u(3:,2:N-1) + u(:N-2,2:N-1))*dy**2 + &
            (u(2:N-1,3:) + u(2:N-1,:N-2))*dx**2) / (2*(dx**2 + dy**2))
    end do
    end function

```

I can already see some questions:

- This would work with any units, the array `u` does not have to be a temperature, it could be an electrostatic potential, or something else. The code would not change otherwise.

- The same with `dx`, perhaps they can be in `mm` instead of `m` (I think the spacing of `u` must change accordingly, but nothing in this could would change otherwise).

A few ways to generalize:

- One can set `dx` as unit of length, but can be any unit.

- the unit of `u` can be inferred from the caller (so this becomes a “templated” or a “generic” function in a sense), since `u` can really be any unit. Alternatively, we can replace `real(dp), unit(K) :: u(N,N)` with `real(dp), unit(*) :: u(N,N)` or something like that. It would still be a strictly a compile time check.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 6, 2021, 7:57pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/34 "2021-07-06T19:57:53Z")

</div>

> [@certik](#):
>
> I can already see some questions:
> 
> - This would work with any units, the array `u` does not have to be a temperature, it could be an electrostatic potential, or something else. The code would not change otherwise.
> - The same with `dx` , perhaps they can be in `mm` instead of `m` (I think the spacing of `u` must change accordingly, but nothing in this could would change otherwise).
> 
> A few ways to generalize:
> 
> - One can set `dx` as unit of length, but can be any unit.

@certik et al.,

Please see [upthread](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/30):

To point out the very obvious to you, length (L) and temperature (\theta) are two of the seven basic quantities and one would hope Fortran language would first recognize the dimensionality of the physical nature of variables and constants in code including in your `Laplace` function example with your illustrative Fortran syntax with the dummy argument definition.

And that units, whether it be `m`, `ft`, etc. or `K`, `F`, etc., would follow the dimensional characterization and which would ultimately help with compile-time inclusion of conversion constants, as needed.

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 6, 2021, 8:05pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/35 "2021-07-06T20:05:27Z")

</div>

> [@Arjen](#):
>
> … I would like to know your ideas on this topic. …

@Arjen, unsure if anyone pointed out a long-standing proposal for Fortran by @vsnyder : [https://github.com/j3-fortran/fortran\_proposals/files/3776442/wishlist.pdf](https://github.com/j3-fortran/fortran_proposals/files/3776442/wishlist.pdf)  
[“Physical” or “Engineering” Units of Measure · Issue #50 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/50#issue-513026229)

(apologies if this is a duplicate post)

---

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [July 7, 2021, 12:52am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/36 "2021-07-07T00:52:45Z")

</div>

See this comment by @vsnyder about the background of his “units” proposal:

- [“Physical” or “Engineering” Units of Measure · Issue #50 · j3-fortran/fortran\_proposals · GitHub](https://github.com/j3-fortran/fortran_proposals/issues/50#issuecomment-875144685)

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [July 7, 2021, 6:14am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/37 "2021-07-07T06:14:00Z")

</div>

FWIW, I have read a number of the descriptions referred to here, including the proposal by @vsnyder. Thank you for al lthe reactions. I hope Brad and I can come with a draft paper before my holidays (in a few weeks’ time), so that you can see what - in my perosnal view - complicates matters. In this I agree with @arclight that it is far from clear and that a solution is therefore not trivial, despite all the efforts.

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [July 7, 2021, 6:14am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/38 "2021-07-07T06:14:56Z")

</div>

And I realise this is a gargantuan cliffhanger (is that the right word?)

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [July 7, 2021, 1:23pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/39 "2021-07-07T13:23:39Z")

</div>

Okay, I have created [a repository](https://github.com/arjenmarkus/handling-units) for this paper. Right now, there is only the raw text, but Brad will add the CI stuff to turn the Latex source into a PDF. It is all very “green” and we have just discuss some of the almost philosophical aspects of the topic. But the outcome was a list of concrete actions.

---

<div class="post-metadata">

**Author:** ![everythingfunctional](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/everythingfunctional/32/176_2.png) [@everythingfunctional](https://fortran-lang.discourse.group/u/everythingfunctional)\
**Post date:** [July 7, 2021, 3:34pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/40 "2021-07-07T15:34:07Z")

</div>

I’ve gotten the CI set up so you can preview the pdf of the paper [here](https://github.com/arjenmarkus/handling-units/blob/previews/main/handling_units_dimensions.pdf).

As @Arjen mentioned, we discussed some of the “philosophical” aspects, which I will give a brief overview of in terms of some vague requirements.

1. A solution should be less strict than having variables declared with specific units for two reasons:  
a. A program ought to be able to work with user input in any units (i.e. a variable declared in meters likely couldn’t read user input in feet)  
b. A library ought not to restrict its users to specific units (i.e. a program to solve the convection equation on domain specified in cm couldn’t make use of a solver library written to only work on miles)
2. A solution should be more strict than tracking the powers of fundamental units at run time. This is to prevent the point the error is reported from diverging from the place a mistake is made. I.e. perhaps the library you’re using needs an acceleration, but you gave it `distance_traveled / time_taken`, you may not see an error reported until trying to output a force but the value is missing an extra second in the denominator. Good luck tracing that bug down.

Our next steps are to put more “meat” into our use cases and examples, and express the resulting “requirements” in an easier to understand way. We’re still open to input from everybody as we continue working.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [September 24, 2021, 11:42am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/41 "2021-09-24T11:42:19Z")

</div>

Have you looked into C++ unit libraries? There appear to be quite a few (list sourced from the LLNL/units README file):

- [LLNL/units](https://github.com/LLNL/units) - A library that provides runtime unit values
- [boost units](https://www.boost.org/doc/libs/1_69_0/doc/html/boost_units.html) - Zero-overhead dimensional analysis and unit/quantity manipulation and conversion in C++
- [Units](https://github.com/nholthaus/units) - A compile-time, header-only, dimensional analysis library built on `C++14` with no dependencies.
- [Units](https://github.com/VincentDucharme/Units) - Another compile time library
- [PhysUnits-CT](https://github.com/martinmoene/PhysUnits-CT-Cpp11) - A C++ library for compile-time dimensional analysis and unit/quantity manipulation and conversion.
- [PhysUnits-RT](https://github.com/martinmoene/PhysUnits-RT) - A C++ library for run-time dimensional analysis and unit/quantity manipulation and conversion.
- [Libunits](https://sourceforge.net/projects/libunits/) - The ultimate shared library to do calculations(!) and conversions with any units! Includes all SI and pseudo SI units and thousands of US, Imperial and other units.
- [unitscpp](http://code.google.com/p/unitscpp/) - A lightweight C++ library for physical calculation with units.
- [mpusz/units](https://github.com/mpusz/units) - A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation.
- [bernedom/SI](https://github.com/bernedom/SI) - A header only C++ library that provides type safety and user defined literals for handling physical values defined in the International System of Units

I guess that more than one of these libraries are linked with proposals to the C++ standards comittee (e.g. [P1935R0 A C++ Approach to Physical Units](https://mpusz.github.io/wg21-papers/papers/1935R0_a_cpp_approach_to_physical_units.html)). Since C++ shares both programming paradigms and userspace with Fortran, I think it’s important to keep an eye out on what they’re doing.

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [September 24, 2021, 11:49am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/42 "2021-09-24T11:49:00Z")

</div>

We have not made an exhaustive search for them, but at least we have seen mp-units, as well as libraries in Rust, Nim, Ada and other languages. But it is well worth looking into these. Thanks for these references. That does not change much in our observation that seldom attention is paid to the usage patterns: whether a particular approach supports it or not. (See our paper at [https://github.com/arjenmarkus/handling-units.)](https://github.com/arjenmarkus/handling-units.))

---

<div class="post-metadata">

**Author:** ![Jcollins](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jcollins/32/540_2.png) [@Jcollins](https://fortran-lang.discourse.group/u/Jcollins)\
**Post date:** [September 27, 2021, 11:07am UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/43 "2021-09-27T11:07:27Z")

</div>

@Beliavsky : SimCon has a project for [Automatic Analysis of Physical Units and Dimensions](http://www.simconglobal.com/units_and_dimensions.html). I don’t know if anything is ready for use.  
I am afraid not yet. We have looked at two approaches:  
i. Static analysis of the code, inferring the relationships between the units of objects. The user does not need to specify any units, but may do so. The first step is to identify the separate lives of symbols - see: [http://simconglobal.com/farrimond\_and\_collins\_2007\_dimensional\_inference\_using\_symbol\_lives.pdf](http://simconglobal.com/farrimond_and_collins_2007_dimensional_inference_using_symbol_lives.pdf) . That step is done within fpt, but we still have work to do in propagating the inferences of units.

ii. Dynamic analysis. We replace all real declarations with declarations of derived types and attach units information to the types. We then apply the inference rules whenever an operation is performed. The first step is to make the replacement and to overload the operators and intrinsic functions. That we have done, again within fpt. What we haven’t yet done is to implement the routines which propagate the inferences. The advantage of this approach is that it handles array elements (which may have different units) and automatically handles sub-program interfaces.

If anyone would like to take part in a collaborative project we would be happy to do this.

Best wishes,

John

---

<div class="post-metadata">

**Author:** ![Arjen](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@Arjen](https://fortran-lang.discourse.group/u/Arjen)\
**Post date:** [September 27, 2021, 3:33pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/44 "2021-09-27T15:33:11Z")

</div>

The static analysis has the advantage of not influencing the performance, whereas the second most probably does influence it. That said, the dynamic analysis allows for, as you say, array elements to have different units.  
How can we experiment with this feature? I feel pretty strongly about the topic 🙂

---

<div class="post-metadata">

**Author:** ![Jcollins](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/jcollins/32/540_2.png) [@Jcollins](https://fortran-lang.discourse.group/u/Jcollins)\
**Post date:** [September 28, 2021, 3:10pm UTC](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383/45 "2021-09-28T15:10:28Z")

</div>

The easy case to start with is the dynamic analysis. The work in fpt is already done (although there could be problems if the original program uses implied EQUIVALENCE in COMMON blocks). The fpt process is described at [fpt Reference: EMULATE REAL ARITHMETIC](http://simconglobal.com/fpt_ref_emulate_real_arithmetic.html) . What is needed next is the set of routines to implement the overloads of operators and intrinsics, and the handlers to propagate the units inferences. For the first cases we tried, the overload routines were generated by a set of Fortran programs which I will make available. We would need to change these to call the routines which handle the propagation of the units inferences. And we would need to write those routines. These routines already exist inside fpt to handle the static analysis case, and when I have time I shall try to extract them (as @Arjen knows I am a little busy at the moment). These are actually quite simple. +, - and = imply that the units are the same, \* and / imply relationships between the units and so on.

The static case requires more work within the internals of fpt (or writing an alternative to fpt). We have not done this yet because of pressure of other work, but I would very much like to return to it.

[Previous page](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383.md?page=1)

[Next page](https://fortran-lang.discourse.group/t/computations-with-units-meters-seconds/1383.md?page=3)
