parametersfortrancffi

Defining a parameter from an input variable in a Fortran subroutine


A part of a code I have has constants defined inside the module under consideration. Here's what I am talking about:

real(RealExt), parameter :: grav_acc = 9.80665
real(RealExt), parameter :: r_gas_dry = 287.026
real(RealExt), parameter :: cp_air_dry = 1.005e+03
real(RealExt), parameter :: pi = 4.0*atan(1.0)
real(RealExt), parameter :: seconds_per_day = 8.6400e+04

I am basically trying to wrap this fortran code, and use cffi to interface it with python so that when I give inputs in python, the fortran code receives it and does stuff as required. The problem for me is not with cffi, but with the idea of parameters.

The type RealExt is defined as follows:

INTEGER, PARAMETER :: RealExt=SELECTED_REAL_KIND(15, 307)

These constants are in a subroutine; my goal is to send the values of these constants (like gravity, rotation rate of the planet etc) to this subroutine and have them treated as constants for the calculations that come later. But, as far as I have read on this site, parameter attribute requires for the values to be known at runtime. So, I can't just do

subroutine runes(g, rd, cp_rd, sec_per_day)
implicit none

real(RealExt), intent(in) :: g, rd, cp_rd, pi_, sec_per_day

real(RealExt), parameter :: grav_acc = g
real(RealExt), parameter :: r_gas_dry = rd
real(RealExt), parameter :: cp_air_dry = cp_rd
real(RealExt), parameter :: pi = pi_
real(RealExt), parameter :: seconds_per_day = sec_per_day
.
.
.

Is there a work-around for this? Can I somehow declare values passed into the subroutine as constants?

P.S: Please let me know if I have to clarify some of my doubts, if not clear enough.


Solution

  • The workaround is to change the Fortran code and make those quantities variables instead of constants. Then you can make them arguments of the subroutine. You could also make them global variables and change them in a module, but that sounds less clean.

    There is no hope for a different workaround with parameter constants, the compiler treats them very differently and does not even have to make a space in memory for them. The compiler can just put their value directly in the expressions where they are used.

    You will also have to change the way the default values are assigned, if you want some default values to be kept. E.g., using optional arguments and local copies and assigning the values in the executable section instead of the declaration lines.