BUG: areaWrite fails with partial fields (#2084)

- depending on how the finiteArea is split up across processors,
  it is possible that some processors have failed to register
  fields in their object registry.

  Now ensure that the field names are synchronized in parallel before
  attempting a write. Replace locally missing fields with a dummy
  zero-sized field.
This commit is contained in:
Mark Olesen
2021-05-20 15:16:58 +02:00
parent 2990b14d89
commit 0abafd98c7
3 changed files with 33 additions and 14 deletions

View File

@ -1,6 +1,10 @@
EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
LIB_LIBS = \
-lOpenFOAM \
-lfileFormats \
-lsurfMesh \
-lmeshTools

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -144,12 +144,15 @@ class areaWrite
// Private Member Functions
//- Write fieldName on surface and on outputDir path
//- Write fieldName on surface and on outputDir path.
// Can have a field nullptr for partially missing fields,
// but the caller should generally filter out completely
// missing fields.
template<class Type>
void writeSurface
(
surfaceWriter& writer,
const Field<Type>& values,
const Field<Type>* fieldPtr,
const word& fieldName
);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,10 +35,12 @@ template<class Type>
void Foam::areaWrite::writeSurface
(
surfaceWriter& writer,
const Field<Type>& values,
const Field<Type>* fieldPtr,
const word& fieldName
)
{
const Field<Type>& values = (fieldPtr ? *fieldPtr : Field<Type>::null());
fileName outputName = writer.write(fieldName, values);
// Case-local file name with "<case>" to make relocatable
@ -64,11 +66,23 @@ void Foam::areaWrite::performAction
wordList fieldNames;
if (loadFromFiles_)
{
fieldNames = objects.sortedNames<GeoField>(fieldSelection_);
// With syncPar (sorted and parallel-consistent)
fieldNames = objects.names<GeoField>(fieldSelection_, true);
}
else
{
fieldNames = areaMesh.thisDb().sortedNames<GeoField>(fieldSelection_);
fieldNames = areaMesh.thisDb().names<GeoField>(fieldSelection_);
// With syncPar
if (Pstream::parRun())
{
// Synchronize names
Pstream::combineGather(fieldNames, ListOps::uniqueEqOp<word>());
Pstream::combineScatter(fieldNames);
}
// Sort for consistent order on all processors
Foam::sort(fieldNames);
}
for (const word& fieldName : fieldNames)
@ -92,16 +106,14 @@ void Foam::areaWrite::performAction
areaMesh
);
writeSurface(writer, fld, fieldName);
writeSurface(writer, &fld, fieldName);
}
else
{
writeSurface
(
writer,
areaMesh.thisDb().lookupObject<GeoField>(fieldName),
fieldName
);
const auto* fieldPtr =
areaMesh.thisDb().cfindObject<GeoField>(fieldName);
writeSurface(writer, fieldPtr, fieldName);
}
}
}