[Numpy-discussion] F2PY and multi-dimension arrays - unexpected array size error

Backing Olof olof.backing at combitech.se
Wed Jul 1 07:30:12 EDT 2015


Hello,
the project is already successfully completed, but I thought for the completeness (and documentation) give myself an answer on what I did wrong and what the correct solution was.

I. I didn’t realise that parameter ordering was crucial. Somehow I just had forgotten this knowledge, but not matter why I did. So after some talk with my colleagues I did finally sort that out.

II. You can integrate Python and FORTRAN in two different ways: inline with Cf2py or with signature files. The Numpy and f2py documentation describes the Cf2py solution very well. But my project asked for *no* modification of the FORTRAN source files. So I had to enter the undocumented arena.

Lesson learnt: When using the signature file option f2py will effectively re-sort all the parameters in the following order:

* integer
* real
* character
* real dimension

So the real/correct parameter order will be shown inside if Python when using:

>>> print (func.___doc___)

If I only had known this in the beginning… ;)

Al the best,
Olof Backing
— 
Olof Backing
Sr Open Source Specialist

Combitech AB
Box 1004 • SE-164 21 KISTA • Sweden
Visiting address Torshamnsgatan 30C
Phn +46 8 580 861 95 • Mobile +46 73 437 61 95
olof.backing at combitech.se • www.combitech.se

> On 03 Feb 2015, at 18:51, Backing Olof <olof.backing at combitech.se> wrote:
> 
> Hi
> I am helping out with a Python and Fortran project. Let me give you some background:
> 
> * Fortran source:
> C Bergstrom FCC
> C User subroutine VUMAT
>      subroutine VUMAT(
> C Read only -
>     *     nblock, ndir, nshr, nstatev, nprops,
>     *     stepTime, dt,
>     *     props,
>     *     density, strainInc,
>     *     tempOld,
>     *     stressOld, stateOld, enerInternOld, enerInelasOld,
> C Write only -
>     *     stressNew, stateNew, enerInternNew, enerInelasNew )
> C
>      include 'vaba_param.inc'
> C
>      dimension props(nprops),
>     1     density(nblock), strainInc(nblock,ndir+nshr),
>     2     tempOld(nblock),
>     5     stressOld(nblock,ndir+nshr), stateOld(nblock,nstatev),
>     6     enerInternOld(nblock), enerInelasOld(nblock),
>     2     stressNew(nblock,ndir+nshr), stateNew(nblock,nstatev),
>     3     enerInternNew(nblock), enerInelasNew(nblock)
> 
> * Corresponding .pyf
>            integer :: nblock
>            integer :: ndir
>            integer :: nshr
>            integer :: nstatev
>            integer :: nprops
>            real :: steptime
>            real :: dt
>            real dimension(nprops) :: props
>            real dimension(nblock) :: density
>            real dimension(nblock,ndir+nshr) :: straininc
>            real dimension(nblock) :: tempold
>            real dimension(nblock,ndir+nshr) :: stressold
>            real dimension(nblock,nstatev) :: stateold
>            real dimension(nblock) :: enerinternold
>            real dimension(nblock) :: enerinelasold
>            real dimension(nblock,ndir+nshr),intent(out) :: stressnew
>            real dimension(nblock,nstatev),intent(out) :: statenew
>            real dimension(nblock),intent(out) :: enerinternnew
>            real dimension(nblock),intent(out) :: enerinelasnew
> 
> * Python source with call of Fortran routine:
>    nblock = 1
>    ndir = 3
>    nshr = 3
>    nstatev = 3
>    nprops = 11
>    stepTime = 1
>    dt = 1
>    props = np.array([10, 0.5, 1e10, 5, 1e12, 3e-6, 8e-6, 27, 2], float)
>    density = np.array([[7.8e3]], float)
>    strainInc = np.array([[1,-0.5,-0.5,0,0,0]], float)
>    tempOld = np.array([[1]], float)
>    stressOld = np.array([[1,1,1,1,1,1]], float)
>    stateOld = np.array([[1,1,1]], float)
>    enerInternOld = np.array([1], float)
>    enerInelasOld = np.array([1], float)
> 
>    stressNew = np.array([[]], float)
>    stateNew = np.array([[]], float)
>    enerInternNew = np.array([[]], float)
>    enerInelasNew = np.array([[]], float)
> 
>    stressNew, stateNew, enerInternNew, enerInelasNew = vumat(nblock, ndir, nshr, nstatev, nprops, stepTime, dt, props, density, strainInc, tempOld, stressOld, stateOld, enerInternOld, enerInelasOld)
> 
> When trying to run with Python 2.7 I get:
> olof at ubuntu:~$ ./demo.py
> unexpected array size: new_size=4, got array with arr_size=1
> Traceback (most recent call last):
>  File "./demo.py", line 33, in <module>
>    main()
>  File "./demo.py", line 30, in main
>    stressNew, stateNew, enerInternNew, enerInelasNew = vumat(nblock, ndir, nshr, nstatev, nprops, stepTime, dt, props, density, strainInc, tempOld, stressOld, stateOld, enerInternOld, enerInelasOld)
> VUMAT_Bergstrom_FCC.error: failed in converting 9th argument `stressold' of VUMAT_Bergstrom_FCC.vumat to C/Fortran array
> 
> Other stuff:
> * python 2.7.6
> * numpy/f2py 1.8.2
> * gcc/gfortran 4.8.2
> * ubuntu 14.04 LTS 32-bit
> 
> I have tried to google, read the f2py manual, fortran tutorials etc, but to no avail. I must also admit that my knowledge in python is so-so and fortran even less(!). What is the missing statement/syntax that I can’t get correct?
> 
> Your humble programmer, Olof



More information about the NumPy-Discussion mailing list