I messed around with the MPI_F08 module a bit yesterday, and I figured out how to make the Fortran interface largely agnostic to whether the user invokes the MPI_F08 vs. MPI modules (I haven’t tested it with mpif.h, but its use is not recommended anyway). However, I thought I should run it by you first, as it might slightly complicate the process.
Basically, the only way that I’ve been able to track down for sending communicators from Fortran to C is using MPI_Comm_f2c from C, which is in use as part of lammps_open_fortran. The MPI_F08 module uses TYPE (MPI_comm) for its communicators, but the type is just used for the strict type-checking required by the standard and there is always a comm%MPI_VAL element that is the “old style” INTEGER communicator ID that the MPI module would use.
The solution is to import only MPI_Comm from MPI_F08, then write two overloaded constructors. The first would be the one that’s already there, which is used if “use MPI” was invoked in the calling routine. The second would use “TYPE(MPI_Comm)” in place of “INTEGER” on the appropriate line, then grab comm%MPI_VAL from it and call the original. It is my impression that the MPI standard requires the integer-style communicators in code that loads MPI to work alongside derived-type-style communicators in code that loads MPI_F08, but I haven’t actually read the standard.
The other idea I had on this was to provide another overloaded constructor that takes the whole command line rather than breaking it into an array first. The difference from the user’s perspective (assuming they’re trying to grab the actual command line the way C and C++ do) would be something like
! Current constructor
CHARACTER (LEN=128), allocatable :: command_args(:)
ALLOCATE(command_args(0:COMMAND_ARGUMENT_COUNT()))
DO i=0,COMMAND_ARGUMENT_COUNT()
CALL GET_COMMAND_ARGUMENT(i,command_args(i))
END DO
lmp = LAMMPS(command_args, MPI_COMM_WORLD)
DEALLOCATE(command_args)
for the way it’s written now, or something like
! Alternative constructor
CHARACTER (LEN=1024) :: command_line
CALL GET_COMMAND(command_line)
lmp = LAMMPS(command_line, MPI_COMM_WORLD)
If they pass a string. The constructor is overloaded, so they would have either option.
The user could, of course, provide arbitrary strings/arrays of strings to these constructors, as in the example.
If it’s easier to see encoded in full, I could make these changes to a branch and do a pull request (now that I know how to do that) and let you look at it that way. I haven’t looked at any of the other functions yet; the constructor seemed like the most important part, and it’s also the most likely part to depend in any particular way on which MPI module is being used.