Dear colleagues,
I wrote a short program using rksuite_90.f90 from: ode/rksuite,
name of my program: example_rksuite.f90
I did: gfortran -c rksuite_90.f90 no errors/no warning
gfortran -c example_rksuite.f90 no errors/no warning
gfortran -g -o example_rksuite example_rksuite.f90 rksuite_90.f90 :
I get: undefined reference to `setup_r1_'
I tried:
nm rksuite_90.o | grep setup_r1 => __rksuite_90_MOD_setup_r1
I think: my compiler is looking for setup_r1, but cannot find it !?
I was checking up: procedure setup_r1 is part of: rksuite_90.f90:
subroutine setup_r1(comm,t_start,y_start,t_end,tolerance,thresholds, &
method,task,error_assess,h_start,message)
I found: subroutine setup_r1 is part of rksuite_90.o with name __rksuite_90_MOD_setup_r1
The setup_r1 subroutine must be included within module: in the file rksuite_90.f90, you should find module rksuite at the beginning of the file. To use the subroutines, functions, constants, etc., defined within this module, you should add use rksuite (or use rksuite, only: setup_r1) where you want to use this subroutine.
With gfortran -g -o example_rksuite example_rksuite.f90 rksuite_90.f90, the compiler starts by compiling example_rksuite.f90, and it wonāt find the module since itās not yet compiled.
Try to build in 3 steps, starting with the module file:
I get:
$ gfortran -o example_rksuite rksuite_90.o example_rksuite.o
C:/msys64/ucrt64/bin/ā¦/lib/gcc/x86_64-w64-mingw32/14.2.0/ā¦/ā¦/ā¦/ā¦/x86_64-w64-mingw32/bin/ld.exe:
example_rksuite.o: in function test_rksuite': C:/ode_rksuite/example_rksuite.f90:30:(.text+0x17c): undefined reference to setup_r1_ā
collect2.exe: error: ld returned 1 exit status
interface setup
module procedure setup_r1
end interface
The module contains the private statement, meaning that all variables, routines, etc, are private by default, unless explicitly declared as public: only setup is declared as public, not setup_r1, therefore what you have to call is setup rather than setup_r1
26 | call setup(comm, t_start, y, t_end, tolerance, thresholds, method, task, error_assess, h
_start, message)
|
1
Error: There is no specific subroutine for the generic āsetupā at (1)
In the routine, comm is declared as type(rk_comm_real_1d), but you are passing an integer; task and method are character(len=*), but you are passing integers; message is a logical, but you are passing a character(len=100)ā¦
And BTW, try sticking with the way the real arguments are declared in the routine. When a dummy argument is: real(kind=wp), intent(in) :: tolerance
Then declare it in your main with real(kind=wp) instead of real(8). real(8) will most of time work because with the most current compilers wp = selected_real_kind(10,50) will be effectively equal to 8, but this is not guaranteed, as some compilers use a different numbering for the kinds. Also, if at some point you want to change the definition of wp, your code will always be consistent with the routines in rksuite_f90.
The name setup_r1 is private. You should see that if you specify it explicitly on the include line:
use rksuite_90, only: setup_r1 ! (error)
use rksuite_90, only: setup ! expected to work
The error you got previously, i.e.
26 | call setup(comm, t_start, y, t_end, tolerance, thresholds, method, task, error_assess, h
_start, message)
|
1
Error: There is no specific subroutine for the generic āsetupā at (1)
was because of the type mismatches as @PierU has explained. When explicit interfaces are used, that is you use procedures from a module, the compiler performs strict type-checking (or rather type-, kind- and rank-checking) for all passed arguments. (There are some exceptions where the rules are slightly different, but I donāt want to go into the details here.)
program test_rksuite
use rksuite_90, only: setup, rk_comm_real_1d
implicit none
! The precision 'wp' is now inherited from the module 'rksuite_90'
! Define precision
! Variable declarations
integer, parameter :: wp = selected_real_kind(10,50)
with call setup it doesnāt work at all??? moreover, I think there is some mistake in variable declaration ,maybe according to comm??? Thank you very much for help! Andreas
Itās difficult to help you just with āit doesnāt workā⦠At the very least copy/paste the error messages you get from the compiler.
That said:
Unless you have declared setup_r1 as public in the rksuite_90 module, this call wonāt work as the setup_r1 name is not visible from your code. You have been told in the above comments to replace it by:
Thank you for answer! Yes, you are right: I tried several times, as you told- with: call setup(comm, t_start, y_start, t_end, tolerance, thresholds, method, task, error_assess, h_start, message) but always with same error message: Error: There is no specific subroutine for the generic āsetupā at (1) ???
(when I tried: gfortran -c example_rksuite.f90 with: call setup_r1 I get no errormessage⦠???)
I believe , there is something wrong with: type(rk_comm_real_1d) :: comm
?
You are importing onlysetup and rk_comm_real_1d, not setup_r1: consequently the compiler assumes that setup_r1 is an external routine and that its interface is unknown at this point. And because the interface is unknown, the compiler does not check the arguments, hence no reported error.
And BTW you should import wp as well instead of redefining it.
Now I have found the error: y_start should be an array, not a scalar.
Both of these variables are declared as real(wp), but the constants on the right are the default real kind. If there is a mismatch of kind values, then this can result in sometimes difficult to debug errors. It would probably be more robust to declare the constants with the appropriate kind, namely 1.0e-6_wp and 0.1_wp.