From 7832d7bfc47bd1abfac9d53318d3483f54930d4b Mon Sep 17 00:00:00 2001 From: Daniels Vidulejs <36682359+vidulejs@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:35:01 +0100 Subject: [PATCH] Fix different dimensions error / Checkpointing issue #158 (#344) --- Adapter.C | 72 ++++++++++++++++++++++++++++++++++++---- Adapter.H | 4 +++ changelog-entries/344.md | 1 + 3 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 changelog-entries/344.md diff --git a/Adapter.C b/Adapter.C index d3a10962..f5ec1bf8 100644 --- a/Adapter.C +++ b/Adapter.C @@ -3,6 +3,7 @@ #include "Utilities.H" #include "IOstreams.H" +#include using namespace Foam; @@ -437,6 +438,7 @@ void preciceAdapter::Adapter::execute() // Read checkpoint if required if (requiresReadingCheckpoint()) { + pruneCheckpointedFields(); readCheckpoint(); } @@ -895,12 +897,12 @@ void preciceAdapter::Adapter::setupCheckpointing() DEBUG(adapterInfo("Adding in checkpointed fields...")); #undef doLocalCode -#define doLocalCode(GeomField) \ - /* Checkpoint registered GeomField objects */ \ - for (const word& obj : mesh_.sortedNames()) \ - { \ - addCheckpointField(mesh_.thisDb().getObjectPtr(obj)); \ - DEBUG(adapterInfo("Checkpoint " + obj + " : " #GeomField)); \ +#define doLocalCode(GeomFieldType) \ + /* Checkpoint registered GeomFieldType objects */ \ + for (const word& obj : mesh_.sortedNames()) \ + { \ + addCheckpointField(mesh_.thisDb().getObjectPtr(obj)); \ + DEBUG(adapterInfo("Checkpoint " + obj + " : " #GeomFieldType)); \ } doLocalCode(volScalarField); @@ -923,6 +925,64 @@ void preciceAdapter::Adapter::setupCheckpointing() ACCUMULATE_TIMER(timeInCheckpointingSetup_); } +void preciceAdapter::Adapter::pruneCheckpointedFields() +{ + // Check if checkpointed fields exist in OpenFOAM registry + // If not, remove them from the checkpointed fields vector + + word fieldName; + uint index; + std::vector regFields; + std::vector toRemoveIndices; + +#undef doLocalCode +#define doLocalCode(GeomFieldType, GeomField_, GeomFieldCopies_) \ + regFields.clear(); \ + toRemoveIndices.clear(); \ + index = 0; \ + /* Iterate through fields in OpenFOAM registry */ \ + for (const word& fieldName : mesh_.sortedNames()) \ + { \ + regFields.push_back(fieldName); \ + } \ + /* Iterate through checkpointed fields */ \ + for (GeomFieldType * fieldObj : GeomFieldCopies_) \ + { \ + fieldName = fieldObj->name(); \ + if (std::find(regFields.begin(), regFields.end(), fieldName) == regFields.end()) \ + { \ + toRemoveIndices.push_back(index); \ + } \ + index += 1; \ + } \ + if (!toRemoveIndices.empty()) \ + { \ + /* Iterate in reverse to avoid index shifting */ \ + for (auto it = toRemoveIndices.rbegin(); it != toRemoveIndices.rend(); ++it) \ + { \ + index = *it; \ + DEBUG(adapterInfo("Removed " #GeomFieldType " : " + GeomFieldCopies_.at(index)->name() + " from the checkpointed fields list.")); \ + GeomField_.erase(GeomField_.begin() + index); \ + delete GeomFieldCopies_.at(index); \ + GeomFieldCopies_.erase(GeomFieldCopies_.begin() + index); \ + } \ + } + + doLocalCode(volScalarField, volScalarFields_, volScalarFieldCopies_); + doLocalCode(volVectorField, volVectorFields_, volVectorFieldCopies_); + doLocalCode(volTensorField, volTensorFields_, volTensorFieldCopies_); + doLocalCode(volSymmTensorField, volSymmTensorFields_, volSymmTensorFieldCopies_); + + doLocalCode(surfaceScalarField, surfaceScalarFields_, surfaceScalarFieldCopies_); + doLocalCode(surfaceVectorField, surfaceVectorFields_, surfaceVectorFieldCopies_); + doLocalCode(surfaceTensorField, surfaceTensorFields_, surfaceTensorFieldCopies_); + + doLocalCode(pointScalarField, pointScalarFields_, pointScalarFieldCopies_); + doLocalCode(pointVectorField, pointVectorFields_, pointVectorFieldCopies_); + doLocalCode(pointTensorField, pointTensorFields_, pointTensorFieldCopies_); + +#undef doLocalCode +} // All mesh checkpointed fields diff --git a/Adapter.H b/Adapter.H index 2e9cd606..b82efa20 100644 --- a/Adapter.H +++ b/Adapter.H @@ -294,6 +294,10 @@ private: //- Configure the checkpointing void setupCheckpointing(); + //- Remove checkpointed fields which are not used by OpenFOAM anymore + void pruneCheckpointedFields(); + + //- Make a copy of the runTime object void storeCheckpointTime(); diff --git a/changelog-entries/344.md b/changelog-entries/344.md new file mode 100644 index 00000000..3e05a373 --- /dev/null +++ b/changelog-entries/344.md @@ -0,0 +1 @@ +- Fixed a bug where a field was checkpointed, but doesn't exist anymore in OpenFOAM registry, causing a crash when reloading last timestep into OpenFOAM. This is done by pruning checkpointed fields that do not (anymore) appear in the registry of objects at that timestep before reading the checkpoint. [#344](https://github.com/precice/openfoam-adapter/pull/344) \ No newline at end of file