Variable time steps without sub-cycling in serial-explicit coupling

Hello,
I am setting up a CHT case with three regions (one fluid, two solids). Region Capsule is between regions PCM and Water and coupled to both of them.
I am using the fluid region as “master-region” and want the coupling time step to be equal to the fluid time step, which is adjusted automatically by OpenFOAM using adjustTimeStep. The solids should adapt to the fluid time step.

Serial-explicit coupling schemes with method=“first-participant” are used:

  • first: Water - second: Capsule
  • first: Capsule - second: PCM

With adjustTimeStep=on in both solid regions, the simulations do not start if the initial time step of the solid simulations is smaller or larger than the fluid time step. I get the following Error message:
(0) 13:49:10 [impl::SolverInterfaceImpl]:405 in advance: ERROR: advance() cannot be called with a timestep size of 0.

With adjustTimeStep=off in both solid regions, the simulations do not start if a initial time step higher than the fluid time step is set in the solids.

---[precice] ERROR:  The timestep length given to preCICE in "advance" 0.003 exceeds the maximum allowed timestep length 0.00032286454805998625 in the remaining of this time window. Did you restrict your timestep length, "dt = min(precice_dt, dt)"? For more information, consult the adapter example in the preCICE documentation.

With adjustTimeStep=off, if the initial time step of the solids is set smaller than the fluid time step, the solid solvers sub-cycle, which is not desirable in my case.

Time = 0.0003

...

---[precice]  Time window completed
---[precice]  Water: iteration: 1, time-window: 1, time: 0.0003 of 250, time-window-size: 0.000322865, max-timestep-length: 2.28645e-05, ongoing: yes, time-window-complete: no, 
PCM: iteration: 1, time-window: 2, time: 0.0003 of 250, max-timestep-length: 250, ongoing: yes, time-window-complete: yes, 

...

    Warning in the preCICE adapter: 
The solver's timestep cannot be larger than the coupling timestep. Adjusting from 0.000300 to 0.000023

...

Time = 0.000322865

...

---[precice]  Water: iteration: 1, time-window: 2, time: 0.000322865 of 250, time-window-size: 0.000359798, max-timestep-length: 0.000359798, ongoing: yes, time-window-complete: yes, 
PCM: iteration: 1, time-window: 3, time: 0.000322865 of 250, max-timestep-length: 250, ongoing: yes, time-window-complete: yes, 
---[preciceAdapter] The solver's timestep is smaller than the coupling timestep. Subcycling...

...

Time = 0.000622865

Do I have to specify something else to disable sub-cycling? How can I set up the coupling in order to get the same time step in all three regions, dictated by the fluid region?

I am using preCICE 2.4.0 and the openfoam-adapter 1.1.0 with OpenFOAM-v2112

Thanks in advance!

I think something you could try here is the first-participant setting for time-window-size: XML reference | preCICE - The Coupling Library

But I am not sure if there are limitations on the type of coupling you can do with this. In any case, try it out and let us know! :slight_smile:

Thanks for your reply, I forgot to mention I am already using the first-participant method, which results in this behavior.

Hi @auer1329 :wave:

Could you please upload the preCICE config file precice-config.xml that you currently use?

I think what you intend to do does not work since there is no coupling scheme between “Water” and “PCM”. But I am confident that one could find a workaround.

What is your motivation to use two separate solid regions in the first place? Both solid regions are OpenFOAM as well?

Hello @uekerman, thank you for your reply!

I am investigating different coupling methods for simulations of latent heat thermal energy storages with a fluid region, a phase change material region and a solid capsule wall. This case is a simplification with a second solid region instead of the PCM.

I already tried with a case with only one solid region, but I get the same errors and the solid solver is subcycling.

Attached you will find my precice-config.xml file I am using for the three-region case.

precice-config.xml (5.8 KB)

Could be that we have a bug in preCICE here.

@auer1329 Could you please try this version and check whether it solves your problem?

(Please let me know if you are not sure how to check out, compile, and link this specific version.)

The code compiled without errors and all tests passed afterwards. I recompiled the openfoam-adapter and tried to run the case with the fixed version, but I get an error right after the preCICE initialization:

---[preciceAdapter] preCICE was configured and initialized
ASSERTION FAILED
Location:   virtual double precice::cplscheme::BaseCouplingScheme::getTimeWindowSize() const
File:       /home/christophauer/OpenFOAM/christophauer-v2112/precice/src/cplscheme/BaseCouplingScheme.cpp:285
Expression: not math::equals(_timeWindowSize, UNDEFINED_TIME_WINDOW_SIZE)
Rank:       1
Arguments:  none

I attached the logfiles for all regions and the preCICE log.
logs.zip (18.6 KB)

Thanks for the quick test!
I was able to reproduce your problem and understand the bug, but have not yet fixed it.
Please follow the PR. We will probably ask you again to test a potential fix eventually.

Quick info:
With commit 15ecc76 it is working again with the same behavior I described in my initial post.

If you use

adjustTimeStep=off

in both Capsule and PCM and if you use a very high value deltaT for both as well, what happens then?

(together with the current state of Fix first participant method in compositional cplscheme by uekerman · Pull Request #1307 · precice/precice · GitHub)

If this does not work, could you please upload separate log files for each of the three participants?

Thanks for testing!

This configuration produces a similar error to the one from the initial post with adjustTimeStep=off and a larger time step than the initial Water time step.
deltaT for the participants Capsule and PCM was set to 1.0 s , while Water starts with about 0.00035 s.

I attached the logs for all three participants and the preCICE debug log.

PCM.log (2.9 KB)
Water.log (6.5 KB)
Capsule.log (4.6 KB)
preCICE.log (312.0 KB)

Thanks for the quick reaction.
In the controlDict files of your three solvers, have you by chance set adjustTimeStep to yes?

More information:

Could you also please switch on debug output for the OpenFOAM adapter (and submit the log files again)? For this, you need to set the compile flag ADAPTER_DEBUG_MODE, see

We certainly have already fixed two problems with the preCICE PR, but there is still sth wrong with either the OpenFOAM adapter or your setup. We are getting closer :grin:

In the controlDict files of your three solvers, have you by chance set adjustTimeStep to yes ?

I set adjustTimeStep to yes for Water and to no for Capsule and PCM. If I deactivate it for the Water participant or activate it for Capsule and PCM, I get the same errors as in the initial post.

Could you also please switch on debug output for the OpenFOAM adapter (and submit the log files again)?

I attached the log files with debug output for the same configuration as yesterday.

Capsule.log (9.3 KB)
PCM.log (5.9 KB)
preCICE.log (312.0 KB)
Water.log (20.4 KB)

Thank you for your help so far! :smile:

I think this is a problem of the OpenFOAM adapter. To be sure, I need help from @Makis.

@Makis Please have a look at the output of Capsule. This participant should use an adaptive timestep size, but not determined by OpenFOAM, but determined by preCICE.
So, adjustTimeStep is false.

During initialize when calling adjustSolverTimeStep, this call is apparently not successful:

Here, timestepStored should be set to 1.0, the timestep size defined in controlDict of Capsule. It is not, because later

---[preciceAdapter] The solver's timestep is smaller than the coupling timestep. Subcycling...

Coupling timestep here is: 0.0003228645…

and then later, we run into an error, but I think the first problem is here already.

So, if I understand correctly, there is the following config:

<time-window-size value="-1" method="first-participant"/>
<participants first="Capsule" second="PCM"/>

meaning that Capsule should prescribe the time step size.

Since adjustTimeStep is set to no, Capsule should always return the same time step size (I assume 1.0, should be defined in the controlDict). I also see that the first solution is at Time = 1.

preCICE then reports:

The timestep length given to preCICE in "advance" 1 exceeds the maximum allowed timestep length 0.00032286454805996456 in the remaining of this time window.

So, I am wondering where the 0.00032286454805996456 is coming from, if Capsule is the one to prescribe the time step size.

Looking closer, I see that there are two coupling schemes here, the other one describing:

<time-window-size value="-1" method="first-participant"/>
<participants first="Water" second="Capsule"/>

which makes me scratch my head: does Capsule both prescribe and not prescribe the time step size? I see how this is an interesting case that unsurprisingly led to a bug discovery in preCICE.

Storing the time step size should work and is easy to check. Just try printing the value of timestepStored_ after

timestepStored_ = runTime_.deltaT().value();
adapterInfo(std::to_string(timestepStored_));

It should print 1.

Later down in the same time step, the solver enters:

which is what we see in the Capsule log. Then, the timestepSolver_ is used:

which will set the time step size to 1.

A good question maybe is if really timestepSolverDetermined < timestepPrecice_ in this case (maybe timestepPrecice_ is not up-to-date?). This should come from initialization:

so, it would also be helpful to know the value of timestepPrecice_ at that point.

Not a full understanding yet, but I hope this already helps.

I want to achieve the following behavior:

Serial-Implicit coupling from Water to Capsule and then from Capsule to PCM, where Water prescribes the time step size (automatically determined by OpenFOAM: 0.00032286454805996456) for Capsule, which is then passed on to the PCM participant.

I need to prescribe the exact same time step size for all three participants to achieve a 1:1 coupling between the three regions where coupling time step = simulation time step.
The point of this is, that I want to replicate the coupling of chtMultiRegionFoam and the multiWorld feature of OpenFOAM and compare the three couplings for my Master’s project.

I understand, that with the current implementation the Capsule participant gets the prescribed time step size from Water and then Capsule is not able to prescribe the time step for PCM as it is already using a prescribed time step size itself.

I think this is the problem. The OpenFOAM adapter does not yet support this.
preCICE is able to handle this (after fixing some bugs), see this test: https://github.com/uekerman/precice/blob/fix-three-solver-first-participant/tests/serial/three-solvers/ThreeSolversFirstParticipant.cpp

@auer1329 Could you provide your cases? Or a simplified version? Could make debugging easier.

@uekerman @Makis I attached simplified versions of my setup. The coupled simulation can be started using the ./Allrun script, which generates the meshes and runs the participants, the meshes and result files can be deleted using the ./Allclean script.

The OpenFOAM version I used is v2112.

three-participants-timestep-sample.zip (41.4 KB)

Thanks for sharing. I was able to run the case and reproduce the problem.
Turns out, there is another bug in preCICE :see_no_evil: (not in the OpenFOAM adapter) . I added an integration test to reproduce. We still need to fix it. Will update everybody here once fixed.