Fypp preprocessor generates Fortran code based on Python language. However, in some cases it is not straightforward. Read below to discover how to create higher level functions.
Let’s say our program requires to allocate an array for N supported ranks. dim is an array with the size of each rank.
allocate(var(dim(1)))
allocate(var(dim(1), dim(2)))
allocate(var(dim(1), dim(2), dim(3)))
allocate(var(dim(1), dim(2), dim(3), ...))
...
To N ranks
To make it possible We can provide to Fypp a new function to do such work:
allocate(var-place here our function-)
In the form of:
allocate(var${rankConstructor(4, “dim”)}$)
First step would be to create a pure python function:
def rankConstructor(ranks, dname):
"""
Generate allocate dimensions for fortran
genrank(4, "d") -> "(d(1),d(2),d(3),d(4))"
usage:
var(rankConstructor(4,"d"))
output:
var(d(1),d(2),d(3),d(4))
"""
# create each dimension rank name
output = [dname+"("+str(rank)+")" for rank in range(1,ranks+1)]
# concatenate array with ","
output_str = ','.join(map(str, output))
# include parenthesis
return "(" + output_str + ")"
Once it is certain it properly works, it is time to “translate” it into fypp:
#:def rankConstructor(RANKS,DNAMES)
#:set output = [DNAMES+"("+str(rank)+")" for rank in range(1,RANKS+1)]
#:set output_str = ','.join(map(str, output))
$:"(" + output_str + ")"
#:enddef rankConstructor
For every line creating a new local variable, set must be used. Finally, to return its value, use “$:” instead of using Python’s return keyword.