Issue 148 – May 27, 2023

Divergence Detector

Hey there 👋

It’s Robin from CFD Engine & do you know what’s worse than having a simulation diverge unexpectedly? Having a simulation almost diverge but carry on iterating, residuals through the roof, taking up valuable cluster time 🤦‍♂️

If you know that pain, then you might like my “slow-mo divergence detector”.

A set-&-forget function that uses runTimeControl plus a couple of tweak-able conditions to catch these pesky time-wasters.

If everything runs like clockwork, it’ll never get used.

If things go wrong, then it’ll step in & stop the job, letting the cluster move on to something that was set up correctly 😜

It’s not coming back

Picture the scene, you spent a long time building your case, it’s iterating, but it’s not looking too healthy.

Your max velocities could outrun the Millennium Falcon & the Titanic is the only thing experiencing higher pressures.

But…it might come back, just give it a few more iterations 🤞

It’s not coming back. It’s time to put it out of its misery.

It’s also time to automate the decision, so that it works when you’re not watching.

And as usual, there’s a function object for that…

runTimeControl

runTimeControl started life as a way to end simulations early but it’s been updated a few times & now you can build some pretty complex automations with it.

It provides a way to set a condition, monitor that condition & do something when that condition is met.

Conditions

We can…

  • check whether an averaged value is stable within a given range;
  • check whether a min/max value is above/below a threshold;
  • check whether an initial residual is above/below a threshold;
  • check whether an equation is taking too many iterations to solve;
  • check whether an adaptive time step has gotten too small;

We can have several conditions being checked at once. Plus we can combine conditions so that several things have to be true before it’s satisfied.

Actions

Once a condition is met, we can do a few things…

  • end the simulation early: write out, plus run any end-of-simulation tasks like exports, reports, monitors etc.
  • abort the simulation: write the current time step & stop ✋
  • add some iterations & then finish up;
  • trigger the start/end of other function objects;
  • start monitoring another condition;

You can even loop back to create complex if-else actions, but we’ll save that for another Saturday – let’s keep this one relatively simple.

Divergence Detector

Here’s the script I use to detect & deal with slow-mo divergence (cases with rapid divergence take care of themselves) 💣

In my case, these kind of blow-ups typically feature high velocities & use a lot of pressure iterations, so that’s what I look for. Your cases may behave differently.

An OpenFOAM function using runTimeControls to catch slow divergence and end the simulation early.

Here’s how it breaks down…

Up top we have a fieldMinMax function that is monitoring the mag U throughout the domain.

Then comes the divergenceDetector which uses a runTimeControl function with two conditions.

condition0 is monitoring the output of our fieldMinMax function & waiting for it to exceed 1000.

condition1 is monitoring the number of iterations that the pressure solver is using & waiting for it to exceed 100.

The conditions are grouped together under groupID 1 which means the divergenceDetector will only be satisfied when both conditions are true.

How to use

Save the function as divergenceDetector in your system directory (here’s the copy-paste version).

Reference it in the functions section of your controlDict using #include "divergenceDetector".

Tweak the values & forget about it.

Try adding it to your favourite tutorial case to see it in action – turn the values down while testing to see it fire 👍

Here’s another example from the docs for inspiration.

Give it a go

This is trying to avoid the odd occasions where a dodgy case hogs the cluster all night, iterating on a nonsense solution (that your colleague probably set up).

You’ll already have an idea of how your cases typically diverge, tweak the settings in the detector & add it to your standard case template. It’ll only step in when things are going wrong, and it might save you a few cluster hours.

What conditions would you use to catch divergence? Or does this only happen to me? Let me know 🫣

Until next week, stay safe,

Signed Robin K