Fortran: Using Arrays in a Python way: derived types, Iteration over derived type

Viewed 61

I am currently trying to get to know Fortran in more detail. In the process, i am trying to implement an algorithm, which i already implemented using python. I have a small array, that looks something like this:

small_array = some_class(a, b, [x,y,z])

With s small arrays, a medium one is created.

medium_array = [small_array_1, small_array_2, ...]

With m medium arrays, a big array is created.

big_array = [medium_array_1, medium_array_2, ...]

I played around with derived-types in fortran, but this way I will only get the needed functionality in a way more difficult way.

What I would like to do is get the number of medium_array in the big_array and the number of small_arrays in the medium_array. I tried using Extent(...) but this won't work with derived types. I would also like to access those derive type (or however this can be done) in an standard array way like e.g. big_array(1,1,:) in order to access all small_arrays of the first big_array and middle_array.

Is there anything to do this in a better way?

EDIT: Here is what I am trying to define in Fortran (Python code):

H1_pg1a = primitive_gaussian(some values..) # These will be derive types in Fortran i suppose, in python these are implemented as class
H1_pg1b = primitive_gaussian(some values..)
H1_pg2a = primitive_gaussian(some values..)

H2_pg1a = primitive_gaussian(some values..)
H2_pg1b = primitive_gaussian(some values..)
H2_pg2a = primitive_gaussian(some values..)

H1_1s = [H1_pg1a, H1_pg1b] # These will be lists of derive types
H1_2s = [H1_pg2a]
H2_1s = [H2_pg1a, H2_pg1b]
H2_2s = [H2_pg2a]

molecule = [H1_1s, H1_2s, H2_1s, H2_2s] # These will be lists of lists of derive types

What I than need to do is get some info about the molecule:

nbasis = len(molecule)

and this will be implemented something like this:

   for i in range(nbasis):  # iteration über spalten
    for j in range(nbasis):  # iteraion über zeilen

        nprimitives_i = len(molecule[i])
        nprimitives_j = len(molecule[j])

        for k in range(nprimitives_i):
            for l in range(nprimitives_j):
...

I would like to then access the values of the class or derived types something like this

molecule[i][k].some_value

I started to implement primitive_gaussian as a derive type, and then define another derive type for the lists of derive type and for the lists of list of derive type. By doing this, i can only access the values with molecule%H1_1s&H1_pg1a%some_value, which I cannot iterate over.

1 Answers

Fortran and Python have very different ways of handling arrays-of-arrays.

The python snippet

a = [1, 2]
b = [3, 4]
c = [a, b]

will result in a structure like

c = [[1, 2], [3, 4]]

But the superficially similar Fortran snippet

integer, allocatable :: a(:)
integer, allocatable :: b(:)
integer, allocatable :: c(:)

a = [1, 2]
b = [3, 4]
c = [a, b]

will instead result in a structure like

c = [1, 2, 3, 4]

i.e. the result of [a, b] in Fortran is a flattened array containing the contents of a and b, where the result of [a, b] in Python is an array containing a and b as separate objects.

If you want an array-of-arrays in Fortran, you will either have to use a multi-dimensional array, or to explicitly define wrapper types for each sub-array type.

Related