Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions src/dynamicMesh/clearCodedRedirects.H
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is a derivative work of OpenFOAM.

OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

\*---------------------------------------------------------------------------*/

#ifndef Foam_blastAMR_clearCodedRedirects_H
#define Foam_blastAMR_clearCodedRedirects_H

#include "fvMesh.H"
#include "codedFixedValueFvPatchField.H"
#include "codedMixedFvPatchField.H"

namespace Foam
{

// Reset cached redirect patch fields on coded BCs (codedFixedValue,
// codedMixed) after any topology change (refine, unrefine, redistribute).
//
// OpenFOAM does not override autoMap/rmap on these BCs to clear the cached
// redirectPatchFieldPtr_, so it keeps a pointer at the pre-change patch field
// memory. After autoMap reallocates the parent buffer, the redirect dangles;
// any user "code" block that writes per-face data buffer-overruns the new
// patch field, and destruction of the redirect later double-frees / hits an
// invalid pointer.
//
// Workaround: replace each affected patch field with its clone. The
// codedFixedValueFvPatchField/codedMixedFvPatchField copy constructors
// initialise redirectPatchFieldPtr_ to null, so the clone has a fresh redirect
// that is rebuilt lazily on the next updateCoeffs at the correct post-change
// size.
template<class GeoField>
void clearCodedRedirects(fvMesh& mesh)
{
using ValueType = typename GeoField::value_type;
using FixedT = codedFixedValueFvPatchField<ValueType>;
using MixedT = codedMixedFvPatchField<ValueType>;

HashTable<GeoField*> flds(mesh.template lookupClass<GeoField>());
forAllIter(typename HashTable<GeoField*>, flds, iter)
{
GeoField& fld = *iter();
auto& bfld = fld.boundaryFieldRef();
forAll(bfld, patchi)
{
const auto& pf = bfld[patchi];
if (isA<FixedT>(pf) || isA<MixedT>(pf))
{
bfld.set(patchi, pf.clone(fld.internalField()).ptr());
}
}
}
}


// Convenience: clear coded redirects on all common volField types.
inline void clearCodedRedirectsAllVol(fvMesh& mesh)
{
clearCodedRedirects<volScalarField>(mesh);
clearCodedRedirects<volVectorField>(mesh);
clearCodedRedirects<volSphericalTensorField>(mesh);
clearCodedRedirects<volSymmTensorField>(mesh);
clearCodedRedirects<volTensorField>(mesh);
}

} // End namespace Foam

#endif
5 changes: 5 additions & 0 deletions src/dynamicMesh/fvMeshBalance/fvMeshBalance.C
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ License
#include "preservePatchesConstraint.H"
#include "preserveBafflesConstraint.H"
#include "sampledSurfaceWorkaround.H"
#include "clearCodedRedirects.H"
#include "dynamicMotionSolverFvMesh.H"
#include "pointIOField.H"

Expand Down Expand Up @@ -639,6 +640,10 @@ Foam::fvMeshBalance::distribute()

blastMeshObject::distribute<fvMesh>(mesh_, map());

// Reset stale codedFixedValue/codedMixed redirects after autoMap.
// See clearCodedRedirects.H for rationale.
clearCodedRedirectsAllVol(mesh_);

// Expire sampled surfaces in surfaceFieldValue function objects.
// OpenFOAM's surfaceFieldValue::updateMesh() doesn't properly expire
// its internal sampledPtr_ cache, leading to stale face indices after
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ License

#include "fvMeshHexRefiner.H"
#include "addToRunTimeSelectionTable.H"
#include "clearCodedRedirects.H"
#include "surfaceInterpolate.H"
#include "volFields.H"
#include "polyTopoChange.H"
Expand Down Expand Up @@ -229,6 +230,10 @@ Foam::fvMeshHexRefiner::refine
// would result in double cloud remapping.
mesh_.updateMesh(map);

// Reset stale codedFixedValue/codedMixed redirects after autoMap.
// See clearCodedRedirects.H for rationale.
clearCodedRedirectsAllVol(mesh_);

// Update numbering of protectedCell_
if (protectedCell_.size())
{
Expand Down Expand Up @@ -322,6 +327,10 @@ Foam::fvMeshHexRefiner::unrefine
// would result in double cloud remapping.
mesh_.updateMesh(map);

// Reset stale codedFixedValue/codedMixed redirects after autoMap.
// See clearCodedRedirects.H for rationale.
clearCodedRedirectsAllVol(mesh_);

// Update numbering of protectedCell_
if (protectedCell_.size())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ License

#include "refinement.H"
#include "polyTopoChanger.H"
#include "clearCodedRedirects.H"
#include "fvMesh.H"
#include "polyAddFace.H"
#include "polyAddPoint.H"
#include "polyModifyFace.H"
Expand Down Expand Up @@ -908,6 +910,11 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::refinement::refine
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
mesh.updateMesh(map());

if (auto* fvm = dynamic_cast<fvMesh*>(&mesh))
{
clearCodedRedirectsAllVol(*fvm);
}

Info<< "Refined from "
<< returnReduce(map().nOldCells(), sumOp<label>())
<< " to " << mesh_.globalData().nTotalCells() << " cells." << endl;
Expand All @@ -926,6 +933,11 @@ bool Foam::refinement::unrefine
autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
mesh.updateMesh(map());

if (auto* fvm = dynamic_cast<fvMesh*>(&mesh))
{
clearCodedRedirectsAllVol(*fvm);
}

Info<< "Unrefined from "
<< returnReduce(map().nOldCells(), sumOp<label>())
<< " to " << mesh_.globalData().nTotalCells() << " cells."
Expand Down
Loading