Skip to content

fix: reset topoChanging in steps without a mesh change - #49

Open
tmaric wants to merge 1 commit into
STFS-TUDa:v2212from
tmaric:fix/topoChanging-reset
Open

tmaric wants to merge 1 commit into
STFS-TUDa:v2212from
tmaric:fix/topoChanging-reset

Conversation

@tmaric

@tmaric tmaric commented Nov 2, 2026

Copy link
Copy Markdown

Problem

The refiners set mesh.topoChanging() only in the steps in which they run, i.e. every refineInterval steps (fvMeshHexRefiner.C, fvMeshPolyRefiner.C, fvMeshDirectionalRefiner.C: mesh_.topoChanging(hasChanged)). After a step that changed the mesh, nothing resets the flag, so it stays true until the next refinement step. Solvers then see mesh.changing() in steps in which nothing changed and redo their mesh-change work in every one of them. For interIsoFoam/interFoam this is gh/ghf and correctPhi, with a pcorr solve on the whole mesh.

With refineInterval 1 the refiner runs in every step and sets the flag correctly, so the problem only appears with refineInterval > 1.

Fix

adaptiveFvMesh::update() resets the flag before refining, as OpenFOAM's dynamicRefineFvMesh does, and sets it whenever the mesh changed. That includes a redistribution in a step without refinement, which previously did not set the flag at all. It adds 12 lines in adaptiveFvMesh.C.

Test

A new foamUT test case, "Check that topoChanging is reset in steps without a mesh change":

  • it uses refinement and balancing every third step, both refiners, and balancing on/off in parallel;
  • in every step it requires mesh.topoChanging() == mesh.update();
  • it also requires that at least one step without a change follows a change, so the check cannot pass vacuously.
v2212 (e26920b) this branch
foamUT serial / parallel new test fails at its REQUIRE, all other tests pass all tests pass

Effect on tutorials/interIsoFoam/damBreak2D_hexRefiner

The case was run with 4 ranks to t = 0.3 s, both builds against the same OpenFOAM v2506. That build has local changes in GAMG agglomeration, reconstructPar and constantAlphaContactAngle, none in the dynamic-mesh code. The foamUT results above use the same build.

refine/unrefine/balanceInterval steps pcorr solves ExecutionTime
1 (as in the tutorial) v2212 1516 1495 44.1 s
1 this branch 1516 1495 43.9 s
10 v2212 1494 1487 20.1 s
10 this branch 1488 156 17.9 s
  • Interval 1: the fields are bitwise identical.
  • Interval 10:
    • pcorr now runs only in the steps that change the mesh.
    • The surge front is identical at 0.1, 0.2 and 0.3 s.
    • At t = 0.3 s the top of the splash differs by 6 mm and the water volume by 5.6e-4 (relative).
    • For comparison, v2212 with interval 10 vs interval 1 differs by 10 mm and 6.7e-4.

In a larger case, a 3D hydraulic jump with interIsoFoam on 96 ranks and refineInterval 10, the fix saved 30-38 % of the time per step.

The refiners set topoChanging only in the steps in which they run (every
refineInterval steps). After a step that changed the mesh, the flag therefore
stays true until the next refinement step, so solvers see mesh.changing() in
steps in which nothing changed. interIsoFoam, interFoam and the other
dynamic-mesh solvers then redo their mesh-change work in every such step:
gh/ghf, and correctPhi with a pcorr solve on the whole mesh.

adaptiveFvMesh::update() now resets the flag before refining, as OpenFOAM's
dynamicRefineFvMesh does, and sets it when the mesh changed, which also covers
a redistribution in a step without refinement.

test: topoChanging() must equal the return value of update() in every step,
with refinement and balancing every third step.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant