ENH: multi-region support for foamToEnsight (#2080)

- additional finite-area support too.
This commit is contained in:
Mark Olesen 2021-05-28 15:05:37 +02:00
parent 9f5df1adba
commit 3e87a46498
17 changed files with 719 additions and 284 deletions

View File

@ -1,5 +1,6 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/finiteArea/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
@ -7,6 +8,7 @@ EXE_INC = \
EXE_LIBS = \
-lfiniteVolume \
-lfiniteArea \
-lfileFormats \
-lconversion \
-llagrangianIntermediate \

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Check field availability for last time.
Done to avoid mapping 'undefined' when a field only exists as time 0.
Requires
readFields.H (for the checkData function)
\*---------------------------------------------------------------------------*/
// Initially all possible objects that are available at the final time
List<wordHashSet> availableRegionObjectNames(meshes.size());
forAll(meshes, regioni)
{
const auto& mesh = meshes[regioni];
IOobjectList objects(mesh, timeDirs.last().name());
if (!fieldPatterns.empty())
{
objects.filterObjects(fieldPatterns);
}
// Remove "*_0" restart fields
objects.prune_0();
if (!doPointValues)
{
// Prune point fields if disabled
objects.filterClasses
(
[](const word& clsName)
{
return fieldTypes::point.found(clsName);
},
true // prune
);
}
wordList objectNames(objects.sortedNames());
// Check availability for all times...
checkData(mesh, timeDirs, objectNames);
availableRegionObjectNames[regioni] = objectNames;
}
// ************************************************************************* //

View File

@ -1,46 +1,83 @@
// Check for "points" in any of the result directories
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
bool hasMovingMesh = false;
Description
Check for "points" in any of the result directories (each region)
if (timeDirs.size() > 1 && Pstream::master())
\*---------------------------------------------------------------------------*/
// All regions moving, or no regions moving. Do not mix.
bool hasMovingMesh(false);
if (timeDirs.size() > 1)
{
// We already loaded a mesh (usually from constant).
// We already loaded meshes (usually from constant).
// See if any other "polyMesh/points" files exist too.
// Do all regions as moving, or all as static.
boolList isMoving(meshes.size(), false);
label nMoving = 0;
Info<< "Search for moving mesh ... " << flush;
for (const instant& inst : timeDirs)
{
const word& timeName = inst.name();
hasMovingMesh =
(
timeName != mesh.pointsInstance()
&& IOobject
(
"points",
timeName,
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
).typeHeaderOk<pointIOField>(true, false)
);
forAll(meshes, regioni)
{
const fvMesh& mesh = meshes[regioni];
if (hasMovingMesh)
if
(
!isMoving[regioni]
&& (timeName != mesh.pointsInstance())
&& IOobject
(
"points",
timeName,
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
).typeHeaderOk<pointIOField>(true, false)
)
{
isMoving[regioni] = true;
++nMoving;
}
}
if (nMoving == isMoving.size())
{
break;
}
}
if (hasMovingMesh)
if (nMoving)
{
Info<< "found. Writing meshes for every timestep." << endl;
Info<< "found " << nMoving
<< " moving regions. Writing meshes for every timestep." << endl;
}
else
{
Info<< "none detected." << endl;
}
hasMovingMesh = (nMoving != 0);
}
// Ensure consistency
reduce(hasMovingMesh, orOp<bool>());
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Code chunk for converting area fields
included by foamToEnsight.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Area fields (finiteArea)
if (doFiniteArea && ensFaCasePtr && ensFaMeshPtr)
{
Info<< " area field (";
writeAllAreaFields(*ensFaCasePtr, *ensFaMeshPtr, objects);
Info<< " )" << nl;
}
// ************************************************************************* //

View File

@ -8,20 +8,7 @@
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part 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.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Code chunk for post-processing conversion of cloud(s) to Ensight
@ -31,6 +18,10 @@ Description
// Cloud field data output
if (doLagrangian)
{
// Lagrangian
const auto& cloudFields = regionCloudFields[regioni];
const auto& cloudNames = regionCloudNames[regioni];
for (const word& cloudName : cloudNames)
{
const HashTable<word>& theseCloudFields = cloudFields[cloudName];
@ -44,7 +35,7 @@ if (doLagrangian)
)
);
Info<< "Write " << cloudName << " (";
Info<< "Cloud " << cloudName << " (";
const bool cloudExists =
returnReduce(currentCloudDirs.found(cloudName), orOp<bool>());

View File

@ -5,23 +5,10 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part 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.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Code chunk for converting volume and dimensioned fields
@ -31,9 +18,10 @@ Description
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Cell field data output
// Volume field data output
if (doBoundary || doInternal)
{
Info<< "Write volume field (";
Info<< " volume field (";
writeAllVolFields(ensCase, ensMesh, objects, nearCellValue);
writeAllDimFields(ensCase, ensMesh, objects);
@ -44,7 +32,7 @@ Description
// - only construct pointMesh on request (it constructs edge addressing)
if (doPointValues)
{
Info<< "Write point field (";
Info<< " point field (";
writeAllPointFields(ensCase, ensMesh, objects);
Info<< " )" << nl;
}

View File

@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Additional mesh accounting (Ensight)
\*---------------------------------------------------------------------------*/
PtrList<ensightCase> ensightCases(regionNames.size());
PtrList<ensightMesh> ensightMeshes(regionNames.size());
PtrList<faMesh> meshesFa(regionNames.size());
PtrList<ensightCase> ensightCasesFa(regionNames.size());
PtrList<ensightFaMesh> ensightMeshesFa(regionNames.size());
{
forAll(regionNames, regioni)
{
const fvMesh& mesh = meshes[regioni];
const word& regionName = regionNames[regioni];
const word& regionDir =
(
regionName != polyMesh::defaultRegion
? regionName
: word::null
);
fileName ensCasePath(outputDir);
word ensCaseName(args.globalCaseName());
if (!regionDir.empty())
{
ensCaseName = regionName;
ensCasePath /= regionName;
// Handle very rare naming collision with Ensight directories
if (regionName == "data")
{
ensCasePath += "-region";
}
}
ensightMeshes.set
(
regioni,
new ensightMesh(mesh, writeOpts)
);
// New ensight case file, initialize header etc.
ensightCases.set
(
regioni,
new ensightCase(ensCasePath, ensCaseName, caseOpts)
);
if (doFiniteArea)
{
autoPtr<faMesh> faMeshPtr;
const bool throwing = FatalError.throwExceptions();
try
{
faMeshPtr.reset(new faMesh(mesh));
}
catch (const Foam::error& err)
{
faMeshPtr.reset(nullptr);
}
FatalError.throwExceptions(throwing);
if (faMeshPtr)
{
ensightCasesFa.set
(
regioni,
new ensightCase
(
ensCasePath/"finite-area",
"finite-area",
caseOpts
)
);
meshesFa.set(regioni, faMeshPtr);
ensightMeshesFa.set
(
regioni,
new ensightFaMesh(meshesFa[regioni])
);
}
}
}
}
// ************************************************************************* //

View File

@ -1,68 +1,100 @@
// check all time directories for the following:
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Check time directories for lagrangian data.
\*---------------------------------------------------------------------------*/
// The fields for each cloud:
HashTable<HashTable<word>> cloudFields;
List<HashTable<HashTable<word>>> regionCloudFields(meshes.size());
// Identify if lagrangian data exist at any time step.
if (timeDirs.size() && doLagrangian)
{
const fileName& baseDir = mesh.time().path();
const fileName cloudPrefix(regionDir/cloud::prefix);
Info<< "Search for lagrangian ... " << flush;
Info<< "Searching for lagrangian ... " << flush;
for (const instant& inst : timeDirs)
forAll(meshes, regioni)
{
const word& timeName = inst.name();
const fvMesh& mesh = meshes[regioni];
auto& cloudFields = regionCloudFields[regioni];
// DO NOT USE -->> runTime.setTime(timeDirs[timeI], timeI); <<--
// It incurs a large overhead when done so frequently.
fileNameList cloudDirs
const word& regionName = regionNames[regioni];
const word& regionDir =
(
readDir
(
baseDir/timeName/cloudPrefix,
fileName::DIRECTORY
)
regionName != polyMesh::defaultRegion
? regionName
: word::null
);
for (fileName& cloudDir : cloudDirs)
{
const word cloudName(std::move(cloudDir));
const fileName cloudPrefix(regionDir/cloud::prefix);
IOobjectList cloudObjs
for (const instant& inst : timeDirs)
{
const word& timeName = inst.name();
// DO NOT USE -->> runTime.setTime(timeDirs[timeI], timeI); <<--
// It incurs a large overhead when done so frequently.
fileNameList cloudDirs
(
mesh,
timeName,
cloudPrefix/cloudName
readDir
(
mesh.time().path()/timeName/cloudPrefix,
fileName::DIRECTORY
)
);
// Clouds require "coordinates".
// The "positions" are for v1706 and lower.
// - detect and remove since these are treated specially
bool isCloud = false;
if (cloudObjs.erase("coordinates"))
for (fileName& cloudDir : cloudDirs)
{
isCloud = true;
}
if (cloudObjs.erase("positions"))
{
isCloud = true;
}
const word cloudName(std::move(cloudDir));
if (isCloud)
{
// Save the cloud fields on a per cloud basis
auto& fieldsPerCloud = cloudFields(cloudName);
IOobjectList cloudObjs
(
mesh,
timeName,
cloudPrefix/cloudName
);
forAllConstIters(cloudObjs, fieldIter)
// Clouds require "coordinates".
// The "positions" are for v1706 and lower.
// - detect and remove since these are treated specially
bool isCloud = false;
if (cloudObjs.erase("coordinates"))
{
const IOobject* io = *fieldIter;
isCloud = true;
}
if (cloudObjs.erase("positions"))
{
isCloud = true;
}
// Field name/type
fieldsPerCloud.insert(io->name(), io->headerClassName());
if (isCloud)
{
// Save the cloud fields on a per cloud basis
auto& fieldsPerCloud = cloudFields(cloudName);
forAllConstIters(cloudObjs, fieldIter)
{
const IOobject* io = *fieldIter;
// Field name/type
fieldsPerCloud.insert
(
io->name(),
io->headerClassName()
);
}
}
}
}
@ -70,24 +102,42 @@ if (timeDirs.size() && doLagrangian)
if (Pstream::parRun())
{
Pstream::mapCombineGather(cloudFields, HashTableOps::plusEqOp<word>());
Pstream::mapCombineScatter(cloudFields);
}
if (cloudFields.empty())
{
Info<< "none detected." << endl;
for (auto& cloudFields : regionCloudFields)
{
Pstream::mapCombineGather
(
cloudFields,
HashTableOps::plusEqOp<word>()
);
Pstream::mapCombineScatter(cloudFields);
}
}
}
// Sorted list of cloud names
const wordList cloudNames(cloudFields.sortedToc());
List<wordList> regionCloudNames(meshes.size());
if (cloudNames.size())
{
// Complete the echo information - as flatOutput
cloudNames.writeList(Info) << endl;
wordHashSet allRegionClouds;
forAll(regionCloudNames, regioni)
{
regionCloudNames[regioni] = regionCloudFields[regioni].sortedToc();
allRegionClouds.insert(regionCloudNames[regioni]);
}
const wordList allCloudNames(allRegionClouds.sortedToc());
if (allRegionClouds.empty())
{
Info<< "none detected." << endl;
}
else
{
// Complete the echo information - as flatOutput
allRegionClouds.writeList(Info) << endl;
}
}

View File

@ -124,6 +124,7 @@ Usage
#include "OFstream.H"
#include "PstreamCombineReduceOps.H"
#include "HashOps.H"
#include "regionProperties.H"
#include "fvc.H"
#include "fvMesh.H"
@ -135,8 +136,10 @@ Usage
// file-format/conversion
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightFaMesh.H"
#include "ensightMesh.H"
#include "ensightOutputCloud.H"
#include "ensightOutputAreaField.H"
#include "ensightOutputVolField.H"
// local files
@ -144,6 +147,7 @@ Usage
#include "writeVolFields.H"
#include "writeDimFields.H"
#include "writePointFields.H"
#include "writeAreaFields.H"
#include "memInfo.H"
@ -166,7 +170,7 @@ int main(int argc, char *argv[])
argList::setAdvanced("decomposeParDict");
argList::setAdvanced("noFunctionObjects");
#include "addRegionOption.H"
#include "addAllRegionOptions.H"
argList::addBoolOption
(
@ -253,6 +257,12 @@ int main(int argc, char *argv[])
// "one-boundary", // allPatches
// "Combine all patches into a single part"
// );
argList::addBoolOption
(
"finite-area",
"Write finite area fields",
true // mark as an advanced option
);
argList::addOption
(
@ -292,9 +302,11 @@ int main(int argc, char *argv[])
);
argList::addOptionCompat("cellZones", {"cellZone", 1912});
#include "setRootCase.H"
// ------------------------------------------------------------------------
// Configuration
// Default to binary output, unless otherwise specified
const IOstream::streamFormat format =
(
@ -303,28 +315,11 @@ int main(int argc, char *argv[])
: IOstream::BINARY
);
cpuTime timer;
memInfo mem;
Info<< "Initial memory " << mem.update().size() << " kB" << endl;
#include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
#include "createNamedMesh.H"
const word& regionDir =
(
regionName == polyMesh::defaultRegion ? word::null : regionName
);
//
// Configuration
//
const bool doBoundary = !args.found("no-boundary");
const bool doInternal = !args.found("no-internal");
const bool doCellZones = !args.found("no-cellZones");
const bool doLagrangian = !args.found("no-lagrangian");
const bool doFiniteArea = args.found("finite-area");
const bool doPointValues = !args.found("no-point-data");
const bool nearCellValue = args.found("nearCellValue") && doBoundary;
@ -332,7 +327,6 @@ int main(int argc, char *argv[])
label indexingNumber(0);
const bool doConsecutive = args.readIfPresent("index", indexingNumber);
// Write the geometry, unless otherwise specified
bool doGeometry = !args.found("no-mesh");
@ -361,15 +355,6 @@ int main(int argc, char *argv[])
// Can also have separate directory for lagrangian
// caseOpts.separateCloud(true);
// Define sub-directory name to use for EnSight data.
// The path to the ensight directory is at case level only
// - For parallel cases, data only written from master
fileName outputDir = args.getOrDefault<word>("name", "EnSight");
if (!outputDir.isAbsolute())
{
outputDir = args.globalPath()/outputDir;
}
ensightMesh::options writeOpts;
writeOpts.useBoundaryMesh(doBoundary);
writeOpts.useInternalMesh(doInternal);
@ -396,29 +381,64 @@ int main(int argc, char *argv[])
// Report the setup
writeOpts.print(Info);
//
// Output configuration (field related)
//
wordRes fieldPatterns;
args.readListIfPresent<wordRe>("fields", fieldPatterns);
// New ensight case file, initialize header etc.
ensightCase ensCase(outputDir, args.globalCaseName(), caseOpts);
// ------------------------------------------------------------------------
// Construct ensight mesh
ensightMesh ensMesh(mesh, writeOpts);
#include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args);
// Handle -allRegions, -regions, -region
#include "getAllRegionOptions.H"
// ------------------------------------------------------------------------
// Directory management
// Define sub-directory name to use for EnSight data.
// The path to the ensight directory is at case level only
// - For parallel cases, data only written from master
// Sub-directory for output
const word ensDirName = args.getOrDefault<word>("name", "EnSight");
fileName outputDir(args.globalPath()/ensDirName);
if (!outputDir.isAbsolute())
{
outputDir = args.globalPath()/outputDir;
}
// ------------------------------------------------------------------------
cpuTime timer;
memInfo mem;
Info<< "Initial memory " << mem.update().size() << " kB" << endl;
#include "createNamedMeshes.H"
#include "createMeshAccounting.H"
if (Pstream::master())
{
Info<< "Converting " << timeDirs.size() << " time steps" << nl;
ensCase.printInfo(Info) << endl;
// ensCase.printInfo(Info) << endl;
}
// Check mesh motion
#include "checkMeshMoving.H"
if (hasMovingMesh && !doGeometry)
{
Info<< "has moving mesh: ignoring '-no-mesh' option" << endl;
doGeometry = true;
}
// Check lagrangian
#include "findCloudFields.H"
// Check field availability
#include "checkFieldAvailability.H"
// test the pre-check variable if there is a moving mesh
// time-set for geometries
// TODO: split off into separate time-set,
@ -429,93 +449,116 @@ int main(int argc, char *argv[])
<< mem.update().size() << " kB" << nl << endl;
// Initially all possible objects that are available at the final time
wordHashSet testedObjectNames;
{
IOobjectList objects(mesh, timeDirs.last().name());
if (!fieldPatterns.empty())
{
objects.filterObjects(fieldPatterns);
}
// Remove "*_0" restart fields
objects.prune_0();
if (!doPointValues)
{
// Prune point fields if disabled
objects.filterClasses
(
[](const word& clsName)
{
return fieldTypes::point.found(clsName);
},
true // prune
);
}
wordList objectNames(objects.sortedNames());
// Check availability for all times...
checkData(mesh, timeDirs, objectNames);
testedObjectNames = objectNames;
}
if (hasMovingMesh && !doGeometry)
{
Info<< "has moving mesh: ignoring '-no-mesh' option" << endl;
doGeometry = true;
}
forAll(timeDirs, timei)
{
runTime.setTime(timeDirs[timei], timei);
// Index for the Ensight case
// Index for the Ensight case(s). Continues if not possible
#include "getTimeIndex.H"
ensCase.setTime(timeDirs[timei], timeIndex);
Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
polyMesh::readUpdateState meshState = mesh.readUpdate();
const bool moving = (meshState != polyMesh::UNCHANGED);
if (moving)
forAll(regionNames, regioni)
{
ensMesh.expire();
ensMesh.correct();
}
const word& regionName = regionNames[regioni];
const word& regionDir =
(
regionName != polyMesh::defaultRegion
? regionName
: word::null
);
if (timei == 0 || moving)
{
if (doGeometry)
if (regionNames.size() > 1)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(hasMovingMesh);
ensMesh.write(os);
Info<< "region=" << regionName << nl;
}
auto& mesh = meshes[regioni];
polyMesh::readUpdateState meshState = mesh.readUpdate();
const bool moving = (meshState != polyMesh::UNCHANGED);
// Ensight
auto& ensCase = ensightCases[regioni];
auto& ensMesh = ensightMeshes[regioni];
// Finite-area (can be missing)
auto* ensFaCasePtr = ensightCasesFa.get(regioni);
auto* ensFaMeshPtr = ensightMeshesFa.get(regioni);
ensCase.setTime(timeDirs[timei], timeIndex);
if (ensFaCasePtr)
{
ensFaCasePtr->setTime(timeDirs[timei], timeIndex);
}
if (moving)
{
ensMesh.expire();
ensMesh.correct();
if (ensFaMeshPtr)
{
ensFaMeshPtr->expire();
ensFaMeshPtr->correct();
}
}
if ((timei == 0 || moving) && doGeometry)
{
// finite-volume
{
autoPtr<ensightGeoFile> os =
ensCase.newGeometry(hasMovingMesh);
ensMesh.write(os);
}
// finite-area
if (ensFaCasePtr && ensFaMeshPtr)
{
autoPtr<ensightGeoFile> os =
ensFaCasePtr->newGeometry(hasMovingMesh);
ensFaMeshPtr->write(os);
}
}
// Objects at this time
IOobjectList objects(mesh, runTime.timeName());
// Restrict to objects that are available for all times
objects.filterObjects
(
availableRegionObjectNames[regioni]
);
// Volume, internal, point fields
#include "convertVolumeFields.H"
// The finiteArea fields
#include "convertAreaFields.H"
// Lagrangian fields
#include "convertLagrangian.H"
}
// Objects at this time
IOobjectList objects(mesh, runTime.timeName());
// Restrict to objects that are available for all times
objects.filterObjects(testedObjectNames);
// Volume, internal, point fields
#include "convertVolumeFields.H"
// Lagrangian fields
#include "convertLagrangian.H"
Info<< "Wrote in "
<< timer.cpuTimeIncrement() << " s, "
<< mem.update().size() << " kB" << nl << nl;
}
ensCase.write();
// Write cases
forAll(ensightCases, regioni)
{
ensightCases[regioni].write();
}
forAll(ensightCasesFa, regioni)
{
if (ensightCasesFa.set(regioni))
{
ensightCasesFa[regioni].write();
}
}
Info<< "\nEnd: "
<< timer.elapsedCpuTime() << " s, "

View File

@ -1,8 +1,29 @@
// Read time index from */uniform/time, but treat 0 and constant specially
// or simply increment from the '-index' option if it was supplied
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
Description
Read time index from ../uniform/time, but treat 0 and constant specially
or simply increment from the '-index' option if it was supplied
Note
Does a 'continue' out of the loop if not possible to obtain an index
\*---------------------------------------------------------------------------*/
label timeIndex = 0;
{
bool goodTimeIndex = true;
if (doConsecutive)
{
timeIndex = indexingNumber++;
@ -21,7 +42,7 @@ label timeIndex = 0;
runTime,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false // no register
false // no register
);
if (io.typeHeaderOk<IOdictionary>(true, false))
@ -33,8 +54,16 @@ label timeIndex = 0;
}
else
{
goodTimeIndex = false;
Info<< "skip ... missing entry " << io.objectPath() << endl;
continue;
}
}
if (!goodTimeIndex)
{
continue;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
InNamespace
Foam
Description
Read finiteArea fields from disk and write ensightFaMesh
\*---------------------------------------------------------------------------*/
#ifndef ensight_writeAreaFields_H
#define ensight_writeAreaFields_H
#include "readFields.H"
#include "areaFaMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
bool writeAreaField
(
ensightCase& ensCase,
const ensightFaMesh& ensMesh,
const tmp<GeometricField<Type, faPatchField, areaMesh>>& tfield
)
{
if (!tfield.valid())
{
return false;
}
const auto& field = tfield();
autoPtr<ensightFile> os =
ensCase.newData<Type>(field.name());
bool wrote = ensightOutput::writeAreaField<Type>
(
os.ref(),
field,
ensMesh
);
tfield.clear();
return wrote;
}
template<class Type>
label writeAreaFields
(
ensightCase& ensCase,
const ensightFaMesh& ensMesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, faPatchField, areaMesh> GeoField;
const faMesh& mesh = ensMesh.mesh();
label count = 0;
for (const word& fieldName : objects.sortedNames<GeoField>())
{
if
(
writeAreaField<Type>
(
ensCase,
ensMesh,
getField<GeoField>(objects.findObject(fieldName), mesh)
)
)
{
Info<< ' ' << fieldName;
++count;
}
}
return count;
}
label writeAllAreaFields
(
ensightCase& ensCase,
const ensightFaMesh& ensMesh,
const IOobjectList& objects
)
{
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writeAreaFields<PrimitiveType> \
( \
ensCase, \
ensMesh, \
objects \
)
label count = 0;
count += ensight_WRITE_FIELD(scalar);
count += ensight_WRITE_FIELD(vector);
count += ensight_WRITE_FIELD(sphericalTensor);
count += ensight_WRITE_FIELD(symmTensor);
count += ensight_WRITE_FIELD(tensor);
#undef ensight_WRITE_FIELD
return count;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,23 +5,10 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part 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.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
InNamespace
Foam
@ -29,8 +16,6 @@ InNamespace
Description
Read dimensioned fields from disk and write with ensightMesh
SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef ensight_writeDimFields_H

View File

@ -5,32 +5,16 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part 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.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
InNamespace
Foam
Description
Read point fields from disk
and write as ensight data
SourceFiles
Read point fields from disk and write as ensight data
\*---------------------------------------------------------------------------*/

View File

@ -5,23 +5,10 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part 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.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
InNamespace
Foam
@ -29,8 +16,6 @@ InNamespace
Description
Read volume fields from disk and write with ensightMesh
SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef ensight_writeVolFields_H

View File

@ -3,10 +3,11 @@ cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
#------------------------------------------------------------------------------
runApplication blockMesh
decompDict="-decomposeParDict system/decomposeParDict-procBoundary8"
fileHandler="-fileHandler collated"
# reconstruct=true
runApplication blockMesh
runApplication $decompDict decomposePar $fileHandler
@ -14,6 +15,13 @@ runParallel $decompDict makeFaMesh $fileHandler
runParallel $decompDict $(getApplication) $fileHandler
runApplication reconstructPar $fileHandler
runParallel $decompDict foamToEnsight -finite-area
if [ "$reconstruct" = true ]
then
runApplication reconstructPar $fileHandler
else
echo "Skipping reconstructPar $fileHandler"
fi
#------------------------------------------------------------------------------

View File

@ -24,8 +24,10 @@ done
runApplication $(getApplication)
echo
echo "Use paraFoam -touch-all to create files for paraview post-processing"
echo
runApplication foamToEnsight -allRegions
# echo
# echo "Use paraFoam -touch-all to create files for paraview post-processing"
# echo
#------------------------------------------------------------------------------

View File

@ -28,11 +28,13 @@ done
# Run
runParallel $(getApplication)
runParallel foamToEnsight -allRegions
# Reconstruct
runApplication reconstructPar -allRegions
echo
echo "Use paraFoam -touch-all to create files for paraview post-processing"
echo
# echo
# echo "Use paraFoam -touch-all to create files for paraview post-processing"
# echo
#------------------------------------------------------------------------------