Should elemental functions accept vector arguments?

Hi everyone,

Elemental functions seem to only accept scalar arguments, and with good reason.

However, what do you think of also supporting vector arguments?

In many cases, we have large arrays of vector data that could benefit from elemental procedures.

For example, here is a small code that converts flow variables in a CFD solver from “conservative” form to “primitive” form. These are called state vectors, and have 5 elements each, to store data for density, velocity, pressure, and energy.

It would be useful to do elemental operations on large arrays of this kind of data, though such operations are done very rarely, in my code, so I don’t have any strong opinion on whether such a feature would be useful in Fortran.

Will such elemental functions that accept vector arguments, be useful to others?

Thanks

I’ve encountered this exact same problem before in my CFD codes. The only ways around it are to either embed the csv array in a derived type and then allocate an array of that type that maps to each cell or vertex in your grid or have separate global arrays for each conservation variable. Unfortunately, I think the array of arrays approach you are forced to adopt will not run as fast as just passing a pure array. Both approaches force you to type more characters and/or lines of code than the way you want to do it.

This example seems to scream for csv and psv derived data types, e.g.:

  type csv_t
    real :: rho, urho, vrho, wrho, erho
  end type

  type psv_t
    real :: rho, u, v, w, p
  end type

Then write an elemental function to accept a csv_t item, and return a psv_t item, e.g.:

  elemental function convert_csv_to_psv (csv) result (res)
    type(csv_t), intent(in) :: csv
    type(psv_t) :: res

    res%rho = csv%rho
    res%u   = csv%urho
    res%v   = csv%vrho/csv%rho
    res%w   = csv%wrho/csv%rho
    res%p   = (1.4-1.0) * (csv%erho-(csv%rho/2.0) * (res%u**2 + res%v**2 + res%w))

  end function

Using associate can simplify access to the individual data elements to help clarify the code:

  elemental function convert_csv_to_psv (csv) result (res)
    type(csv_t), intent(in) :: csv
    type(psv_t) :: res

    associate (rho=>csv%rho, urho=>csv%urho, vrho=>csv%vrho, wrho=>csv%wrho, erho=>csv%erho)
      res%rho = rho
      res%u   = urho/rho
      res%v   = vrho/rho
      res%w   = wrho/rho
      res%p   = (1.4-1.0)*(erho-(rho/2.0)*(res%u**2 + res%v**2 +res%w**2))
    end associate

  end function
1 Like

I suggested three years ago that elemental functions be allowed to have a mix of scalar and array arguments. They would only be elemental in the scalar arguments. I think your use case is different.