Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/solverdummy/solverdummy.f90
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ PROGRAM main
commsize = 1
dt = 1
numberOfVertices = 3
CALL precicef_create(participantName, config, rank, commsize, 50, 50)
CALL precicef_create(participantName, config, rank, commsize)

! Allocate dummy mesh with only one vertex
CALL precicef_get_mesh_dimensions(meshName, dimensions, 50)
Expand Down
33 changes: 26 additions & 7 deletions precice.f90
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ module precice
implicit none

interface

! This interface contains subroutines of two kinds:
! - precicec_<name> expect C-style, null-terminated strings and their sizes
! - precicef_<name> automatically convert strings to null-terminated and call
! the corresponding `precicec_<name>`.

subroutine precicef_create(participantName, configFileName, &
& solverProcessIndex, solverProcessSize, &
& participantNameLength, configFileNameLength) &
& bind(c, name='precicef_create_')
subroutine precicec_create(participantName, configFileName, &
& solverProcessIndex, solverProcessSize) &
& bind(c, name='precicec_createParticipant')

use, intrinsic :: iso_c_binding
character(kind=c_char), dimension(*) :: participantName
character(kind=c_char), dimension(*) :: configFileName
integer(kind=c_int) :: solverProcessIndex
integer(kind=c_int) :: solverProcessSize
integer(kind=c_int), value :: participantNameLength
integer(kind=c_int), value :: configFileNameLength
end subroutine precicef_create
end subroutine precicec_create

subroutine precicef_initialize() &
& bind(c, name='precicef_initialize_')
Expand Down Expand Up @@ -312,4 +314,21 @@ end subroutine precicef_get_version_information

end interface

contains
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still want that users call precicef_create, so they should be outside the contains block. However, it looks like I cannot call subroutines from inside an interface. What would be the right way here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you have it now as a module procedure (a thin wrapper of the preCICE C API). Isn't that what you want?

Copy link
Member Author

@MakisH MakisH Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want that users call the precicef_create variant without having to provide neither null-terminated strings, nor placeholder lengths. For this, I would need the precicef_create to not be internal (inside the contains), no?

If I ask the users to call the precicec_create, then they need to provide null-terminated strings.

Should I maybe split it into two different modules? Not sure if I can modify the arguments in an interface.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Fortran parlance, interface blocks are like function declarations in C. They are specification statements (i.e. non-executable).

When you want to define a procedure, it must be in the "contains" part:

module precice
 ! ... specification ...
contains
 ! ... procedure definitions (including executable statements) ...
end module

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that helps! But then, I understand that both what I have in the interface and in the contains need to have the same name.


subroutine precicef_create(participantName, configFileName, &
& solverProcessIndex, solverProcessSize)

use, intrinsic :: iso_c_binding, only: c_char, c_int
character(len=*), intent(in) :: participantName
character(len=*), intent(in) :: configFileName
integer(c_int), intent(in) :: solverProcessIndex
integer(c_int), intent(in) :: solverProcessSize

call precicec_create( &
trim(participantName)//c_null_char, &
trim(configFileName)//c_null_char, &
solverProcessIndex, solverProcessSize)
end subroutine precicef_create

end module precice