Read data in first time step

What’s the recommended way to build the main coupling loop for either serial or parallel coupling? In a parallel coupling, both participants only need to read data after the first advance. In serial coupling, the second participant needs to read data immediately, before advance. An adapter should be able to handle both cases.

How can the adapter know whether to read data in the first time step? There is the is_read_data_available function which I guess gives the right answer, but it’s deprecated and intended for another purpose according to the documentation. The coupling scheme could also be added into the config file for the adapter, but that would reduntant: if the coupling scheme in the precice config changes, the adapter config needs to be changed as well.

You are probably referring to this page: Coupling flow | preCICE - The Coupling Library

In general, the adapter does not know if it is operating as part of a serial or a parallel scheme.

For the cases where it is important that both participants start with initial values, you can use data initialization: Step 7 - Data initialization | preCICE - The Coupling Library

Yes, that’s the page I’m referring to. But I’m not sure I understand.

The sequence diagram for serial coupling shows the second participant (SolidSolver) receiving the Forces. The communication happens in SolverInterface::initialize, but the second participant needs to read data to use it, i.e. calling SolverInterface::read...Data(). Then it calls solveTimeStep. How does the second participant know that there is data to read? In a serial coupling, there are Forces to read. In a parallel coupling, there is nothing to read, trying to read would just give garbage.

Or otherwise, if the second participant in that serial coupling just doesn’t read the Forces in the first step, then the results of the first participant from the first step are never used at all. The second participant goes from using initial forces (maybe initialized through preCICE or otherwise) to forces from the second time step.

The bottom of the page says “The neat thing about the high-level API of preCICE is that you don’t need to change anything in your code to switch between a serial and a parallel coupling scheme.”. I don’t believe that’s true. The sequence diagram shows a sequence of initialize -> read data -> solve -> advance -> write data -> read data -> ... for the serial coupling and initialize -> solve -> advance -> write data -> read data -> solve -> ... for the parallel coupling. That’s not the same sequence, so I think the second participant needs to know the type of coupling. More correctly, both participants need to know the type of coupling, since both could be the second participant. What am I missing? (I know the diagrams don’t actually say that the data is being read, just received. But what’s the point of receiving data that is never read? So I assume the read...Data calls are omitted for brevity, just like the write...Data calls)

The sequence diagrams only show what preCICE exchanges, not what the adapter/participant writes or reads to/from preCICE. This is a bit confusing.

What is implied here is that you have called precice.writeBlockScalarData before you call initializeData or advance.

preCICE uses some variables to convey whether the adapter needs to perform some steps (e.g., precice::constants::actionWriteInitialData, which one checks with isActionRequired in the adapter).

Note that in the upcoming preCICE v3, initializeData is merged into initialize, and all the write*Data are becoming just writeData. The isActionRequired and the respective variables are dropped in v3, the user is always required to write, and preCICE chooses whether to exchange data, depending on the configuration.

Good questions!

Trying to read would give zero values, which normally is no problem.

You could / should always do:

  1. initialize (+ initData in v2)
  2. read (this gives the initial data or the first real data (second participant in serial coupling) or zero values, all depending on the coupling scheme)
  3. solve
  4. write
  5. advance
  6. go to 2.

Makes sense?

I’m starting so see where my misunderstanding is.

Until now I thought data initialization is only necessary for cases where some computation is required to get an initial value, i.e. you can’t just read it from an input file or similar, and you don’t want to repeat that computation in both participants.

If I understand you correctly, data initialization is required whenever zero isn’t valid or what you want, which for us means pretty much always (maybe we are special in that way). This is also mentioned at the top of this page: Step 7 - Data initialization | preCICE - The Coupling Library, but I hadn’t seen this before. This means that every participant needs to write initial values during the data initialization phase for all the coupled data (or at least needs to be prepared to write depending on the settings in precice config xml). It’s not intended for participants to e.g. read the initial value from some input source and skip the initializeData phase.

This answers my question about reading data in the first time step, since it’s definitely OK to just always read data.

But it creates a problem for data initialization, which until now I was thinking of as a completely optional, advanced feature instead of a basic requirement. Maybe I’m bad at listening/reading, or does it need to be highlighted more in your course/documentation?

Our solver generally cannot easily write initial data during the initialization phase. There are a lot of state variables that the solver produces during simulation, but does not require initial values for. But just because the solver doesn’t have the variables readily available doesn’t mean it’s impossible to get valid initial values. The other participant solver, during it’s normal setup, may be able to get initial values without reading coupled data.

A concrete example: our solver (ISSM) computes temperatures. the temperature variable is not required to be initialized at all. Depending on the setup, it may even be completely inaccessible before the first time step of the solver is done. But initial temperature data might still be available from other sources, maybe measurements or results of previous simulations. The other participant solver (not talking about any specific solver here) might already have that data since it requires temperature data but doesn’t know anything about the coupling. So we could have a situation where one participant is required to write data it doesn’t have just so the other participant can read data it doesn’t need because it already has it. Obviously it’s possible, at least in principle, for ISSM to also read that measurement data or do the necessary computation so it can write initial data. This will require changes to the solver, the adapter, or both, and the necessary computation steps are very different for every variable, of which there are many.

I don’t know how big of a problem this is, the size of the changes will be anywhere between trivial and massive, so we’ll see. It probably means our adapter will have limited support for which variables to couple until we can implement the initial data computation for every variable. I realise that precice can’t change it’s behavior here because every existing adapter and coupling relies on it. So thanks for patiently correcting my misconceptions :smile:

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.