Fortran Call Errors - fortran

In my Fortran code, I have the commands:
CALL EXPECTATION(X, 0.5D0*SIGMAZ, Z_EXPECTATION)
WRITE(1,*) T, Z_EXPECTATION
CALL EXPECTATION(X, 0.5D0*SIGMAY, Y_EXPECTATION)
WRITE(4,*) T, Y_EXPECTATION
for which I get the errors:
Error: Symbol ‘sigmay’ at (1) has no IMPLICIT type
Error: Symbol ‘sigmaz’ at (1) has no IMPLICIT type
But I get no error for a similar command:
CALL EXPECTATION(X, 0.5D0*SIGMAX, X_EXPECTATION)
WRITE(3,*) T, X_EXPECTATION
What could be the issue? I am calling the variables from the same subroutine and I have defined them to be
COMPLEX*16, DIMENSION(2,2) :: SIGMAX, SIGMAY SIGMAZ

You forgot a comma in the declaration between SIGMAY and SIGMAZ. Since Fortran doesn't care about whitespaces, it created only two complex variables: SIGMAX and SIGMAYSIGMAZ.
Just add the comma and your code should compile fine.

Related

Multi dimensional integration with quadpack results in recursive call to nonrecursive procedure 'dqage'

I am attempting to perform a 2D integral numerically using the quadpack double library. Since this website does not have a Latex engine integrated I attach a picture with the math.
I also attach below my implementation of this operation in the test_module module.
module test_module
use f90_kind ! defines dp
use physconst ! defines pi
use global_variables ! defines the variables for quadpack
use csv_file ! allows me to write to a csv file
implicit none
real(dp) :: a, b, c ! parameters I want to set
contains
real(dp) function multi_val_func(theta)
real(dp), intent(in) :: theta
multi_val_func = exp(theta**2 + c*theta)
end function multi_val_func
real(dp) function theta_integral(phi)
real(dp), intent(in) :: phi
c = phi*(a+b)
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = 2.0E0_dp*pi
call dqage(multi_val_func, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
theta_integral = res
end function theta_integral
subroutine phi_integral(final_result)
real(dp),intent(out) :: final_result
a = 1.0E0_dp
b = 1.0E0_dp
! Quadpack variables
epsabs = 1.0E-14_dp
epsrel = 0.0E0_dp
key = 6
ilow = 0.0E0_dp
ihigh = pi
call dqage(theta_integral, ilow, ihigh, epsabs, epsrel, key, limit, &
res, abserr, neval, ier, alist, blist, rlist, elist, iord, last)
final_result = res
print *, final_result
end subroutine phi_integral
end module test_module
In the main file I define the result variable and thereafter call phi_integral(result). I compile this code using the following makefile
FFLAGS = -O0 -fcheck=all -ffree-line-length-none
debug:
gfortran -c $(FFLAGS) $(srcdir)/f90_kind.f90
gfortran -c $(FFLAGS) $(srcdir)/physconst.f90
gfortran -c $(FFLAGS) $(srcdir)/global_variables.f90
gfortran -c $(FFLAGS) $(extlib_qp)/quadpack_double.f90
gfortran -c $(FFLAGS) $(extlib_csv)/csv_file.f90
gfortran -c $(FFLAGS) $(srcdir)/multi_var_integration.f90
gfortran -c $(FFLAGS) $(srcdir)/main.f90
gfortran *.o -o debug -lblas -llapack
rm -f *.o *.mod
The code compiles but when I run it I receive the following error:
Fortran runtime error: Recursive call to nonrecursive procedure 'dqage'
Error termination. Backtrace:
#0 0x103a28d3d
#1 0x103a299f5
#2 0x103a29fd6
#3 0x1039f94b6
#4 0x1039dee59
#5 0x1039fad68
#6 0x1039f9948
#7 0x1039dec7d
#8 0x1039def61
#9 0x1039defa3
Any suggestion for dealing with this is greatly appreciated.
Not every subroutine or function in Fortran is re-entrant or, as Fortran calls it, "recursive". Before Fortran 2018 a subroutine that can be called, when already inside itself (even if indirectly) must be marked by the recursive attribute.
Even if a subroutine is marked that way, it may not work as expected if it contains static (saved) data or if it uses global (common blocks, module) variables.
I cannot immediately see any such static data used in http://www.netlib.no/netlib/quadpack/dqage.f so it might actually work after adding recursive.
However, as francescalus pointed out, you should be better off with a dedicated 2d quadrature library.
The theta integral can be done via the error function erf. See wolfram alpha.
The result of that is a function of one variable phi which can be evaluated via quadpack. Thus, you don't need a multidimensional integral routine after all.

f2py on module with allocatable string

I have written a very simple module (test.f90)
module tt
implicit none
character(:),allocatable :: hh
contains
subroutine test()
implicit none
integer :: i
end subroutine
end module tt
I want now to wrap it into an object for Python using f2py.
I use the following commands:
gfortran-9 -c test.f90 -Wall
f2py -m g -c test.f90
But I obtain the following errors. These errors seems to be correlated with the allocatable string and I am currently not able to find a solution to remove it.
/var/folders/fg/53phbn8n6nd3vrhm3sh_36w40000gn/T/tmpjtueazku/src.macosx-10.7-x86_64-3.6/g-f2pywrappers2.f90:25:17:
25 | allocate(d(s(1)))
| 1
Error: Shape specification for allocatable scalar at (1)
/var/folders/fg/53phbn8n6nd3vrhm3sh_36w40000gn/T/tmpjtueazku/src.macosx-10.7-x86_64-3.6/g-f2pywrappers2.f90:16:22:
16 | if ((size(d,i).ne.s(i)).and.(s(i).ge.0)) then
| 1
Error: 'array' argument of 'size' intrinsic at (1) must be an array
/var/folders/fg/53phbn8n6nd3vrhm3sh_36w40000gn/T/tmpjtueazku/src.macosx-10.7-x86_64-3.6/g-f2pywrappers2.f90:29:24:
29 | s(i) = size(d,i)
| 1
Error: 'array' argument of 'size' intrinsic at (1) must be an array

Passing function to arguments ifort vs gfortran

I'm experiencing a problem since I'm trying to run my fortran code with ifort, which was previously compiled with gfortran. One of my code's functions is using an other function as an argument, as shown below. Compiling the code with gfortran/ifort do not generate any errors.
module mod_rk4_2
implicit none
contains
!rk4 temporal scheme
function rk4(f,dt,func) result(f_new)
double precision, dimension(:,:), intent(in) :: f
double precision, intent(in) :: dt
double precision, dimension(size(f,1),size(f,2)) :: f_new
double precision, dimension(:,:), allocatable :: k1, k2, k3, k4
interface
function func(f) result(res)
double precision, dimension(:,:), intent(in) :: f
double precision, dimension(size(f,1),size(f,2)) :: res
end function func
end interface
allocate(k1(size(f,1),size(f,2)),k2(size(f,1),size(f,2)),k3(size(f,1),size(f,2)),k4(size(f,1),size(f,2)))
k1=func(f)
k2=func(f+dt*k1/2)
k3=func(f+dt*k2/2)
k4=func(f+dt*k3)
f_new=f+dt/6*(k1+2*k2+2*k3+k4)
deallocate(k1,k2,k3,k4)
end function rk4
end module mod_rk4_2
Running the code compiled with gfortran is fine, but when compiled with ifort, the code crashes at the first call of the forementioned function, with a stack overflow error message. Any ideas ?
forrtl: severe (170): Program Exception - stack overflow
Image PC Routine Line Source
main 00007FF779CCAE38 Unknown Unknown Unknown
main 00007FF779C564E0 Unknown Unknown Unknown
main 00007FF779CCAC02 Unknown Unknown Unknown
main 00007FF779CCB04C Unknown Unknown Unknown
KERNEL32.DLL 00007FF9D8EC1FE4 Unknown Unknown Unknown
ntdll.dll 00007FF9D99BEFC1 Unknown Unknown Unknown

How to call Fortran dll with function as argument in C

I use VS2013 and Intel Visual Fortran, then make a dll from Fortran code.
In Fortran subroutine, it has 3 arguments, "fa" for passing a function, "a" for passing an array, "b" for passing a number. But it doesn't work when I call it in VC++.
Update:
Well... program above is chaotic, so I remodify program below. I create a fortran dll that it can pass an array to sum its elements and call a c function.
module callctest
use, intrinsic :: iso_c_binding
implicit none
private
public callcfun
contains
subroutine callcfun(a,b) bind(C,name = "callcfun")
!DEC$ ATTRIBUTES DLLEXPORT :: callcfun
implicit none
real(c_double), dimension(*):: a !receive an array from c
type(c_funptr), value :: b ! receive a c function
real, parameter::pi=3.14159
integer :: i
real :: sum = 0.0
do i = 1,3 ! sum the array elements
sum = sum+a(i)
end do
write(*,*) 'total',sum
return
end subroutine callcfun
end module callctest
And c code that it call fortran subroutine:
#include "stdafx.h"
#include <iostream>
using namespace std;
extern "C" {
void callcfun( double[], void(f)(int)); //
}
void sayhello(int a){
cout << "Hi! fortran " <<a<< endl;
}
int main(){
double a[] = { 10.0, 50, 3.0 };
callcfun(a, sayhello(50));
system("pause");
return 0;
}
In c program, function "sayhello" print words "Hi! fortran" and an integer, I want to call sayhello functionby calling "callcfun( array, function )" which is written by fortran.
It works when I call "callcfun( array, function )" in c program if function
like "sayhello" only print "Hi! fortran". But I add an int argument for sayhello function so that it print words "Hi! fortran" and an integer argument. Function "callcfun" doesn't execute successfully.
Error list:
Error 1 error C2664: 'void callcfun(double [],void (__cdecl *)(int))' : cannot convert argument 2 from 'void' to 'void (__cdecl *)(int)' c:\users\emlab\documents\visual studio 2013\projects\vc++\call_for_ex\call_for_ex\call_for_ex.cpp 21 1 call_for_ex
2 IntelliSense: argument of type "void" is incompatible with parameter of
type "void (*)(int)" c:\Users\EMlab\Documents\Visual Studio
2013\Projects\VC++\call_for_ex\call_for_ex\call_for_ex.cpp 21 14 call_for_ex
Errors show the problem in the c function, how to pass the c function back to fortran dll then call it in fortran?
For a Fortran procedure to be interoperable, the BIND(C) attribute is required. Both Fortran procedures are missing this attribute.
For a procedure to be exported from a DLL on Windows, the symbolic name of the procedure must ultimately be supplied to the linker. (There are three ways of doing this: a source directive passed through by the compiler into the object code (as per the !DEC$ ATTRIBUTES DLLEXPORT directive used with the arraysum procedure), by listing the procedure name in a module definition file or by listing the name after /EXPORT on the linker command line - I am assuming that the two latter methods have not been used.) Given the source directive approach of nominating one procedure has been used for one of the procedures (arraysum) to be exported, that method should also be used for the other procedure (fcn) that needs to be exported.
For a C++ function to have C linkage, it must be declared with extern "C". There is no such declaration for fcn in the C++ code. (The absence of any declaration for fcn means that C++ code should not have compiled.)
The import library (.lib) generated by the linker when building the Fortran DLL must be provided to the linker when the exe is built from the C++ code. Typically this is done within Visual Studio by providing the import library as an "Additional Dependency" on the Linker > Input property page.

f2py Fortran function interfaces compiling error

f2py gives an error when I try compile FORTRAN subroutine, from which I call another FORTRAN function passing array to it.
I simplified code to leave the problem only.
SUBROUTINE MAS (matrix, a)
IMPLICIT NONE
INTERFACE
LOGICAL FUNCTION LTRY(input_array)
IMPLICIT NONE
INTEGER*4 :: input_array(:,:)
END FUNCTION LTRY
END INTERFACE
INTEGER*4 :: matrix (:,:)
!f2py INTENT(INOUT) :: matrix(:,:)
INTEGER*4 a
!f2py INTENT(INOUT) :: a
a = 1
IF ( LTRY (matrix)) a = 2
END SUBROUTINE
LOGICAL FUNCTION LTRY(input_array)
IMPLICIT NONE
INTEGER*4 :: input_array (:,:)
IF ( ANY(input_array == 0)) LTRY = .FALSE.
END FUNCTION LTRY
After I try to compile this using
f2py -c -m ptest ptest.f90
I get a tremendous number of errors. What's wrong?
Using Ubuntu and gfortran compiler.
Here is compiler output (part with error reports):
gfortran:f77: /tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:16.35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:18.72:
integer, dimension(:,:) :: input
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:19.72:
logical :: ltry
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:20.17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:40.32:
ltryf2pywrap = .not.(.not.ltry(input_array))
1
Error: Operand of .not. operator at (1) is INTEGER(4)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:16.35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:18.72:
integer, dimension(:,:) :: input
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:19.72:
logical :: ltry
1
Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:20.17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f:40.32:
ltryf2pywrap = .not.(.not.ltry(input_array))
1
Error: Operand of .not. operator at (1) is INTEGER(4)
error: Command "/usr/bin/gfortran -Wall -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops -I/tmp/tmpSZHMCR/src.linux-i686-2.7 -I/usr/lib/python2.7/dist-packages/numpy/core/include -I/usr/include/python2.7 -c -c /tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.f -o /tmp/tmpSZHMCR/tmp/tmpSZHMCR/src.linux-i686-2.7/ptest-f2pywrappers.o" failed with exit status 1
Compilation failed.
Some errors look quite strange. For example compiler considers logical function as an integer.
Unfortunately, you have not indicated which type of error you get.
I have tried to compile it on my system, and I do get error messages:
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:16:35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:18:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:19:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:20:17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:16:35:
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
1
Error: Unexpected junk after function declaration at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:18:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:19:72: Error: Unexpected data declaration statement in INTERFACE block at (1)
/tmp/tmpLKy0jV/src.linux-x86_64-2.7/ptest-f2pywrappers.f:20:17:
end function ltry
1
Error: Expecting END INTERFACE statement at (1)
Looking into the wrapped file, we see that the wrapper has made a very dubious decision: It has added comments at the end of the line, but then line-wrapped the comment without declaring it a comment in the second line:
C -*- fortran -*-
C This file is autogenerated with f2py (version:2)
C It contains Fortran 77 wrappers to fortran functions.
subroutine f2pywrapmas (matrix, a, f2py_matrix_d0, f2py_matr
&ix_d1)
integer*4 a
integer f2py_matrix_d0
integer f2py_matrix_d1
integer*4 matrix(f2py_matrix_d0,f2py_matrix_d1)
interface
subroutine mas(matrix,a)
integer*4, dimension(:,:) :: matrix
integer*4 :: a
interface ! in :ptest:ptest.f90:mas
function ltry(input) ! in :ptest:ptest.f90:mas:unkno
&wn_interface
integer, dimension(:,:) :: input
logical :: ltry
end function ltry
end interface
end subroutine mas
end interface
call mas(matrix, a)
end
I don't know how to help you, though. But I do suggest you post your actual error messages in the question.