preCICE uses MPI for communication between different participants (and also for communication between ranks of the same participant). So are there any problems if the solver that you intend to couple also already uses MPI (e.g. for parallelization)? Who should initialize MPI? Who should finalize MPI? This is what we discuss here.

It is not complicated. There are three rules that preCICE follows:

  • preCICE only initializes MPI if it is not yet initialized (by e.g. the solver you want to couple).
  • preCICE finalizes MPI if and only if it was also initialized by preCICE.
  • preCICE only initializes MPI if it needs MPI.
  • preCICE uses MPI_COMM_WORLD if no custom communicator is provided.

So what does this mean for your adapter code:

  • Initialize preCICE after you initialize MPI.
  • Finalize preCICE before you finalize MPI.
[...] // start up your solver

MPI_Init(NULL, NULL);
int world_rank, world_size;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);

[...] // maybe more initialization

precice::Participant precice("SolverName", "precice-config.xml", world_rank, world_size);

[...] // declare meshes vertices etc.

precice.initialize();

[...] // solving and coupling

precice.finalize();

[...] // more finalization

MPI_Finalize();

If you need to provide a custom communicator to preCICE, you can do so as follows:


[...] // Initialize MPI and start your solver

MPI_Comm my_comm = /* ... */;

precice::Participant precice("SolverName", "precice-config.xml", world_rank, world_size, &my_comm);

[...]