ENH: overhaul ensight handling (#1579)

- includes restructuring and simplification of low-level ensight part
  handling and refactor of backends to improve code reuse.

foamToEnsight
-------------

  * new cellZone support.
    This was previously only possible via a separate foamToEnsightParts
    utility that was not parallelized.

  * support for point fields.

  * `-nearCellValue` option (as per foamToVTK)

  * data indexing now uses values from the time index.
    This is consistent with the ensightWrite function object and
    can help with restarts.

  * existing ensight directories are removed, unless the -no-overwrite
    option is supplied

foamToEnsightParts
------------------
  * now redundant and removed.

ensightOutputSurface (new class)
--------------------------------
  * a lightweight wrapper for point/face references that is tailored
    for the ensightSurfaceWriter. It uses compact face/point information
    and is serial only, since this is the format requirements from the
    surfaceWriter class.

ensightMesh (revised class)
---------------------------
  * now only holds a polyMesh reference, which removes its dependency
    on finiteVolume and allows it to be relocated under fileFormats
    instead of conversion.

Removed classes: ensightParts, ensighPartFaces, ensightPartCells

- these were used by foamToEnsightParts, but not needed anymore.
This commit is contained in:
Mark Olesen
2020-02-10 15:21:05 +01:00
committed by Andrew Heather
parent c7e8f22baf
commit a97628121c
64 changed files with 4916 additions and 5885 deletions

View File

@ -3,13 +3,11 @@ EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats \
-ldynamicMesh \
-lconversion \
-llagrangianIntermediate \
-lgenericPatchFields

View File

@ -1,6 +1,6 @@
// Check for "points" in any of the result directories
bool meshMoving = false;
bool hasMovingMesh = false;
if (timeDirs.size() > 1 && Pstream::master())
{
@ -12,7 +12,7 @@ if (timeDirs.size() > 1 && Pstream::master())
{
const word& timeName = inst.name();
meshMoving =
hasMovingMesh =
(
timeName != mesh.pointsInstance()
&& IOobject
@ -27,13 +27,13 @@ if (timeDirs.size() > 1 && Pstream::master())
).typeHeaderOk<pointIOField>(true, false)
);
if (meshMoving)
if (hasMovingMesh)
{
break;
}
}
if (meshMoving)
if (hasMovingMesh)
{
Info<< "found. Writing meshes for every timestep." << endl;
}
@ -43,4 +43,4 @@ if (timeDirs.size() > 1 && Pstream::master())
}
}
reduce(meshMoving, orOp<bool>());
reduce(hasMovingMesh, orOp<bool>());

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,9 +31,8 @@ Description
// Cloud field data output
if (doLagrangian)
{
forAll(cloudNames, cloudNo)
for (const word& cloudName : cloudNames)
{
const word& cloudName = cloudNames[cloudNo];
const HashTable<word>& theseCloudFields = cloudFields[cloudName];
fileNameList currentCloudDirs
@ -48,12 +47,7 @@ if (doLagrangian)
Info<< "Write " << cloudName << " (";
const bool cloudExists =
returnReduce
(
currentCloudDirs.found(cloudName),
orOp<bool>()
);
returnReduce(currentCloudDirs.found(cloudName), orOp<bool>());
{
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,25 +35,19 @@ Description
{
Info<< "Write volume field (";
writeAllVolFields
(
ensCase,
ensMesh,
meshProxy,
objects,
nodeValues
);
writeAllDimFields
(
ensCase,
ensMesh,
meshProxy,
objects,
nodeValues
);
writeAllVolFields(ensCase, ensMesh, objects, nearCellValue);
writeAllDimFields(ensCase, ensMesh, objects);
Info<< " )" << nl;
// PointData
// - only construct pointMesh on request (it constructs edge addressing)
if (doPointValues)
{
Info<< "Write point field (";
writeAllPointFields(ensCase, ensMesh, objects);
Info<< " )" << nl;
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,7 +32,11 @@ Group
Description
Translate OpenFOAM data to EnSight format.
An Ensight part is created for the internalMesh and for each patch.
An Ensight part is created for cellZones (unzoned cells are "internalMesh")
and patches.
- Handles volume fields, dimensioned fields, point fields
- Handles mesh topology changes.
Usage
\b foamToEnsight [OPTION]
@ -51,36 +55,65 @@ Usage
The quoting is required to avoid shell expansions and to pass the
information as a single argument.
- \par -nearCellValue
Use zero-gradient cell values on patches
- \par -nodeValues
Force interpolation of values to nodes
- \par -no-boundary
Suppress writing any patches.
Suppress output for all boundary patches
- \par -no-internal
Suppress writing the internal mesh.
Suppress output for internal (volume) mesh
- \par -no-cellZones
Suppress cellZone handling
- \par -no-lagrangian
Suppress writing lagrangian positions and fields.
- \par -patches patch or patch list
Specify particular patches to write.
- \par -no-mesh
Suppress writing the geometry. Can be useful for converting partial
results for a static geometry.
- \par -faceZones zone or zone list
Specify faceZones to write, with wildcards
- \par -cellZone zoneName
Specify single cellZone to write (not lagrangian)
- \par -no-point-data
Suppress conversion of pointFields. No interpolated PointData.
- \par -noZero
Exclude the often incomplete initial conditions.
- \par -index \<start\>
Use consecutive indexing for \c data/######## files with the
specified start index.
Ignore the time index contained in the uniform/time file.
- \par -name \<subdir\>
Define sub-directory name to use for Ensight data (default: "EnSight")
- \par -width \<n\>
Width of Ensight data subdir (default: 8)
Note
Writes to \a EnSight directory to avoid collisions with
foamToEnsightParts
- \par -cellZones NAME | LIST
Specify single zone or multiple cell zones (name or regex) to write
- \par -faceZones NAME | LIST
Specify single zone or multiple face zones (name or regex) to write
- \par -patches NAME | LIST
Specify single patch or multiple patches (name or regex) to write
For example,
\verbatim
-patches top
-patches '( front \".*back\" )'
\endverbatim
- \par -excludePatches NAME | LIST
Specify single or multiple patches (name or regex) not to convert.
For example,
\verbatim
-excludePatches '( inlet_1 inlet_2 "proc.*" )'
\endverbatim
\*---------------------------------------------------------------------------*/
@ -93,6 +126,7 @@ Note
#include "HashOps.H"
#include "fvc.H"
#include "fvMesh.H"
#include "fieldTypes.H"
#include "volFields.H"
#include "scalarIOField.H"
@ -104,35 +138,27 @@ Note
#include "ensightMesh.H"
#include "ensightOutputCloud.H"
#include "ensightOutputVolField.H"
#include "fvMeshSubsetProxy.H"
// local files
#include "readFields.H"
#include "writeVolFields.H"
#include "writeDimFields.H"
#include "writePointFields.H"
#include "memInfo.H"
#undef foamToEnsight_useTimeIndex
using namespace Foam;
//- Get internal field and make it a zero-gradient volume field with subsetting
template<class GeoField>
tmp<GeoField>
getZeroGradInternalField(IOobject& io, const fvMeshSubsetProxy& proxy)
{
auto tfield = tmp<typename GeoField::Internal>::New(io, proxy.baseMesh());
return proxy.interpolateInternal(tfield);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Translate OpenFOAM data to Ensight format with a part for"
" the internalMesh and for each patch."
"Translate OpenFOAM data to Ensight format with individual parts"
" for cellZones, unzoned cells and patches"
);
timeSelector::addOptions();
@ -147,10 +173,42 @@ int main(int argc, char *argv[])
"ascii",
"Write in ASCII format instead of 'C Binary'"
);
argList::addOption
(
"index",
"start",
"Starting index for consecutive number of Ensight data/ files."
" Ignore the time index contained in the uniform/time file."
, true // mark as an advanced option
);
argList::addOption
(
"name",
"subdir",
"Sub-directory name for Ensight output (default: 'EnSight')"
);
argList::addBoolOption
(
"no-overwrite",
"Suppress removal of existing EnSight output directory"
);
argList::addOption
(
"width",
"n",
"Width of Ensight data subdir"
);
argList::addBoolOption
(
"nearCellValue",
"Use zero-gradient cell values on patches"
, true // mark as an advanced option
);
argList::addBoolOption
(
"nodeValues",
"Write values at nodes"
"Force interpolation of values to nodes"
, true // mark as an advanced option
);
argList::addBoolOption
(
@ -165,12 +223,37 @@ int main(int argc, char *argv[])
"Suppress writing the internal mesh"
);
argList::addBoolOption
(
"no-cellZones",
"Suppress writing any cellZones"
);
argList::addBoolOption
(
"no-lagrangian", // noLagrangian
"Suppress writing lagrangian positions and fields"
);
argList::addOptionCompat("no-lagrangian", {"noLagrangian", 1806});
argList::addBoolOption
(
"no-point-data",
"Suppress conversion of pointFields and disables -nodeValues"
);
argList::addBoolOption
(
"no-mesh", // noMesh
"Suppress writing the geometry."
" Can be useful for converting partial results for a static geometry"
, true // mark as an advanced option
);
// Future?
// argList::addBoolOption
// (
// "one-boundary", // allPatches
// "Combine all patches into a single part"
// );
argList::addOption
(
"patches",
@ -179,6 +262,14 @@ int main(int argc, char *argv[])
"Eg, 'inlet' or '(outlet \"inlet.*\")'"
);
argList::addOption
(
"excludePatches",
"wordRes",
"Specify single patch or multiple patches to exclude from writing."
" Eg, 'outlet' or '( inlet \".*Wall\" )'"
, true // mark as an advanced option
);
argList::addOption
(
"faceZones",
"wordRes",
@ -194,22 +285,13 @@ int main(int argc, char *argv[])
);
argList::addOption
(
"cellZone",
"word",
"Specify cellZone to write"
);
argList::addOption
(
"name",
"subdir",
"Sub-directory name for Ensight output (default: 'EnSight')"
);
argList::addOption
(
"width",
"n",
"Width of Ensight data subdir"
"cellZones",
"wordRes",
"Specify single or multiple cellZones to write\n"
"Eg, 'cells' or '( slice \"mfp-.*\" )'."
);
argList::addOptionCompat("cellZone", {"cellZones", 1912});
#include "setRootCase.H"
@ -221,8 +303,6 @@ int main(int argc, char *argv[])
: IOstream::BINARY
);
const bool nodeValues = args.found("nodeValues");
cpuTime timer;
memInfo mem;
Info<< "Initial memory " << mem.update().size() << " kB" << endl;
@ -239,19 +319,50 @@ int main(int argc, char *argv[])
regionPrefix = 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 doPointValues = !args.found("no-point-data");
const bool nearCellValue = args.found("nearCellValue") && doBoundary;
// Control for numbering iterations
label indexingNumber(0);
const bool doConsecutive = args.readIfPresent("index", indexingNumber);
// Write the geometry, unless otherwise specified
bool doGeometry = !args.found("no-mesh");
if (nearCellValue)
{
Info<< "Using neighbouring cell value instead of patch value"
<< nl << endl;
}
if (!doPointValues)
{
Info<< "Point fields and interpolated point data"
<< " disabled with the '-no-point-data' option"
<< nl;
}
//
// General (case) output options
//
ensightCase::options caseOpts(format);
caseOpts.nodeValues(args.found("nodeValues"));
// Forced point interpolation?
caseOpts.nodeValues(doPointValues && args.found("nodeValues"));
caseOpts.width(args.get<label>("width", 8));
caseOpts.overwrite(true); // remove existing output directory
caseOpts.overwrite(!args.found("no-overwrite")); // Remove existing?
// 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
@ -261,23 +372,32 @@ int main(int argc, char *argv[])
outputDir = args.globalPath()/outputDir;
}
//
// Output configuration (geometry related)
//
ensightMesh::options writeOpts(format);
writeOpts.useBoundaryMesh(!args.found("no-boundary"));
writeOpts.useInternalMesh(!args.found("no-internal"));
const bool doLagrangian = !args.found("no-lagrangian");
ensightMesh::options writeOpts;
writeOpts.useBoundaryMesh(doBoundary);
writeOpts.useInternalMesh(doInternal);
writeOpts.useCellZones(doCellZones);
if (args.found("patches"))
{
writeOpts.patchSelection(args.getList<wordRe>("patches"));
}
if (args.found("excludePatches"))
{
writeOpts.patchExclude(args.getList<wordRe>("excludePatches"));
}
if (args.found("faceZones"))
{
writeOpts.faceZoneSelection(args.getList<wordRe>("faceZones"));
}
if (args.found("cellZones"))
{
writeOpts.cellZoneSelection(args.getList<wordRe>("cellZones"));
}
// Report the setup
writeOpts.print(Info);
//
// Output configuration (field related)
@ -286,22 +406,11 @@ int main(int argc, char *argv[])
wordRes fieldPatterns;
args.readListIfPresent<wordRe>("fields", fieldPatterns);
word cellZoneName;
if (args.readIfPresent("cellZone", cellZoneName))
{
Info<< "Converting cellZone " << cellZoneName
<< " only, with new outside faces as \"oldInternalFaces\"."
<< nl;
}
// Ignored (unproxied) if cellZoneName is empty
fvMeshSubsetProxy meshProxy(mesh, fvMeshSubsetProxy::ZONE, cellZoneName);
// New ensight case file, initialize header etc.
ensightCase ensCase(outputDir, args.globalCaseName(), caseOpts);
// Construct the Ensight mesh
ensightMesh ensMesh(meshProxy.mesh(), writeOpts);
// Construct ensight mesh
ensightMesh ensMesh(mesh, writeOpts);
if (Pstream::master())
{
@ -335,50 +444,64 @@ int main(int argc, char *argv[])
// Remove "*_0" restart fields
objects.prune_0();
// Only retain volume and dimensioned fields.
if (!doPointValues)
{
// Prune point fields if disabled
objects.filterClasses
(
[](const word& clsName){
return
(
fieldTypes::volume.found(clsName)
|| fieldTypes::internal.found(clsName)
[](const word& clsName)
{
return fieldTypes::point.found(clsName);
},
true // prune
);
}
);
wordList objectNames(objects.sortedNames());
// Check availability for all times...
checkData(meshProxy.baseMesh(), timeDirs, objectNames);
checkData(mesh, timeDirs, objectNames);
testedObjectNames = objectNames;
}
forAll(timeDirs, timeIndex)
if (hasMovingMesh && !doGeometry)
{
runTime.setTime(timeDirs[timeIndex], timeIndex);
ensCase.nextTime(timeDirs[timeIndex]);
Info<< "has moving mesh: ignoring '-no-mesh' option" << endl;
doGeometry = true;
}
forAll(timeDirs, timei)
{
runTime.setTime(timeDirs[timei], timei);
// Index for the Ensight case
#include "getTimeIndex.H"
ensCase.setTime(timeDirs[timei], timeIndex);
Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
polyMesh::readUpdateState meshState = mesh.readUpdate();
if (meshState != polyMesh::UNCHANGED)
const bool moving = (meshState != polyMesh::UNCHANGED);
if (moving)
{
meshProxy.correct();
ensMesh.expire();
ensMesh.correct();
}
if (timeIndex == 0 || meshMoving)
if (timei == 0 || moving)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
if (doGeometry)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(hasMovingMesh);
ensMesh.write(os);
}
}
// Objects at this time
IOobjectList objects(meshProxy.baseMesh(), runTime.timeName());
IOobjectList objects(mesh, runTime.timeName());
// Restrict to objects that are available for all times
objects.filterObjects(testedObjectNames);
@ -386,7 +509,7 @@ int main(int argc, char *argv[])
// Volume, internal, point fields
#include "convertVolumeFields.H"
// Write lagrangian data
// Lagrangian fields
#include "convertLagrangian.H"
Info<< "Wrote in "

View File

@ -3,7 +3,7 @@
label timeIndex = 0;
{
if (optIndex)
if (doConsecutive)
{
timeIndex = indexingNumber++;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,7 +27,8 @@ InNamespace
Foam
Description
Read fields from disk for foamToEnsight
Helper routines for reading a field or fields,
for foamToEnsight
SourceFiles
readFields.C
@ -39,39 +40,114 @@ SourceFiles
#include "instantList.H"
#include "IOobjectList.H"
#include "fvMeshSubsetProxy.H"
#include "zeroGradientFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Get the field and subset it, or return nullptr
//- Get the field or return nullptr
template<class GeoField>
tmp<GeoField> getField(const IOobject* io, const fvMeshSubsetProxy& proxy)
tmp<GeoField> getField
(
const IOobject* io,
const typename GeoField::Mesh& mesh
)
{
if (io)
{
auto tfield = tmp<GeoField>::New(*io, proxy.baseMesh());
return proxy.interpolate(tfield);
return tmp<GeoField>::New(*io, mesh);
}
return nullptr;
}
//- Get internal field and make it a zero-gradient volume field with subsetting
//- Get the named field from the objects, or return nullptr.
template<class GeoField>
tmp<GeoField>
getZeroGradField(const IOobject* io, const fvMeshSubsetProxy& proxy)
tmp<GeoField> getField
(
const typename GeoField::Mesh& mesh,
const IOobjectList& objects,
const word& fieldName
)
{
if (io)
// Can do something with syncPar on failure ...
return getField<GeoField>(objects.findObject(fieldName), mesh);
}
//- Convert an internal field to zero-gradient volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
makeZeroGradientField
(
const tmp
<
typename GeometricField<Type, fvPatchField, volMesh>::Internal
>& tdf
)
{
if (tdf.valid())
{
auto tfield =
tmp<typename GeoField::Internal>::New(*io, proxy.baseMesh());
return proxy.interpolateInternal(tfield);
auto& df = tdf.ref();
auto tfield = GeometricField<Type, fvPatchField, volMesh>::New
(
df.name(),
df.mesh(),
df.dimensions(),
std::move(df.field()),
zeroGradientFvPatchScalarField::typeName
);
tfield.ref().oriented() = df.oriented();
tfield.ref().correctBoundaryConditions();
tdf.clear();
return tfield;
}
tdf.clear();
return nullptr;
}
//- Convert a volume field to zero-gradient volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>>
makeZeroGradientField
(
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tdf
)
{
if (tdf.valid())
{
auto& df = tdf.ref();
auto tfield = GeometricField<Type, fvPatchField, volMesh>::New
(
df.name(),
df.mesh(),
df.dimensions(),
std::move(df.primitiveFieldRef(false)), // No update accessTime
zeroGradientFvPatchScalarField::typeName
);
tfield.ref().oriented() = df.oriented();
tfield.ref().correctBoundaryConditions();
tdf.clear();
return tfield;
}
tdf.clear();
return nullptr;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,12 +30,11 @@ Description
Read dimensioned fields from disk and write with ensightMesh
SourceFiles
writeDimFields.H
\*---------------------------------------------------------------------------*/
#ifndef writeDimFields_H
#define writeDimFields_H
#ifndef ensight_writeDimFields_H
#define ensight_writeDimFields_H
#include "writeVolFields.H"
@ -44,40 +43,60 @@ SourceFiles
namespace Foam
{
template<class Type>
bool writeDimField
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const tmp<DimensionedField<Type, volMesh>>& tdf
)
{
if (!tdf.valid())
{
return false;
}
auto tfield = makeZeroGradientField<Type>(tdf);
// Now a volField with zero-gradient boundaries
return writeVolField<Type>
(
ensCase,
ensMesh,
tfield,
false // No nearCellValue, we already have zero-gradient
);
}
template<class Type>
label writeDimFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
typedef typename
GeometricField
<
Type, fvPatchField, volMesh
>::Internal DimField;
const fvMesh& mesh = dynamicCast<const fvMesh>(ensMesh.mesh());
label count = 0;
for (const word& fieldName : objects.sortedNames<DimField>())
{
const IOobject* io = objects.findObject(fieldName);
if
(
writeVolField<Type>
writeDimField<Type>
(
ensCase,
ensMesh,
proxy,
getZeroGradField<GeoField>(io, proxy),
nodeValues
getField<DimField>(objects.findObject(fieldName), mesh)
)
)
{
@ -94,29 +113,26 @@ label writeAllDimFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const IOobjectList& objects
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writeDimFields<PrimitiveType> \
( \
ensCase, ensMesh, \
proxy, \
objects, \
nodeValues \
ensCase, \
ensMesh, \
objects \
)
label count = 0;
count += foamToEnsight_WRITE_FIELD(scalar);
count += foamToEnsight_WRITE_FIELD(vector);
count += foamToEnsight_WRITE_FIELD(sphericalTensor);
count += foamToEnsight_WRITE_FIELD(symmTensor);
count += foamToEnsight_WRITE_FIELD(tensor);
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 foamToEnsight_WRITE_FIELD
#undef ensight_WRITE_FIELD
return count;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,17 +27,18 @@ InNamespace
Foam
Description
Read volume fields from disk and write with ensightParts
Read point fields from disk
and write as ensight data
SourceFiles
writeVolFields.H
\*---------------------------------------------------------------------------*/
#ifndef writeVolFields_H
#define writeVolFields_H
#ifndef ensight_writePointFields_H
#define ensight_writePointFields_H
#include "readFields.H"
#include "ensightMesh.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -46,12 +47,11 @@ namespace Foam
{
template<class Type>
bool writeVolField
bool writePointField
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tfield
const ensightMesh& ensMesh,
const tmp<GeometricField<Type, pointPatchField, pointMesh>>& tfield
)
{
if (!tfield.valid())
@ -61,14 +61,14 @@ bool writeVolField
const auto& field = tfield();
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
// PointData = true
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name(), true);
// Currently serial only
bool wrote = ensightOutput::Serial::writeVolField<Type>
bool wrote = ensightOutput::writePointField<Type>
(
os.ref(),
field,
ensParts,
os.ref()
ensMesh
);
tfield.clear();
@ -77,15 +77,16 @@ bool writeVolField
template<class Type>
label writeVolFields
label writePointFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const ensightMesh& ensMesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
typedef GeometricField<Type, pointPatchField, pointMesh> GeoField;
const pointMesh& ptMesh = pointMesh::New(ensMesh.mesh());
label count = 0;
@ -93,12 +94,11 @@ label writeVolFields
{
if
(
writeVolField<Type>
writePointField<Type>
(
ensCase,
ensParts,
mesh,
getField<GeoField>(objects.findObject(fieldName), mesh)
ensMesh,
getField<GeoField>(ptMesh, objects, fieldName)
)
)
{
@ -111,31 +111,30 @@ label writeVolFields
}
label writeAllVolFields
label writeAllPointFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const ensightMesh& ensMesh,
const IOobjectList& objects
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
writeVolFields<PrimitiveType> \
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writePointFields<PrimitiveType> \
( \
ensCase, ensParts, \
mesh, \
ensCase, \
ensMesh, \
objects \
)
label count = 0;
count += foamToEnsight_WRITE_FIELD(scalar);
count += foamToEnsight_WRITE_FIELD(vector);
count += foamToEnsight_WRITE_FIELD(sphericalTensor);
count += foamToEnsight_WRITE_FIELD(symmTensor);
count += foamToEnsight_WRITE_FIELD(tensor);
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 foamToEnsight_WRITE_FIELD
#undef ensight_WRITE_FIELD
return count;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,15 +30,14 @@ Description
Read volume fields from disk and write with ensightMesh
SourceFiles
writeVolFields.H
\*---------------------------------------------------------------------------*/
#ifndef writeVolFields_H
#define writeVolFields_H
#ifndef ensight_writeVolFields_H
#define ensight_writeVolFields_H
#include "readFields.H"
#include "fvMeshSubsetProxy.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -50,25 +49,41 @@ bool writeVolField
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const tmp<GeometricField<Type, fvPatchField, volMesh>>& tfield,
const bool nodeValues
const bool nearCellValue = false
)
{
if (!tfield.valid())
{
return false;
}
else if (nearCellValue)
{
auto tzgrad = makeZeroGradientField<Type>(tfield);
// Recursive call
return writeVolField
(
ensCase,
ensMesh,
tzgrad,
false // No nearCellValue, we already have zero-gradient
);
}
const auto& field = tfield();
autoPtr<ensightFile> os = ensCase.newData<Type>(field.name());
// Forced use of node values?
const bool nodeValues = ensCase.nodeValues();
autoPtr<ensightFile> os =
ensCase.newData<Type>(field.name(), nodeValues);
bool wrote = ensightOutput::writeVolField<Type>
(
os.ref(),
field,
ensMesh,
os.ref(),
nodeValues
);
@ -82,13 +97,14 @@ label writeVolFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const bool nearCellValue = false
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
const fvMesh& mesh = dynamicCast<const fvMesh>(ensMesh.mesh());
label count = 0;
for (const word& fieldName : objects.sortedNames<GeoField>())
@ -99,9 +115,8 @@ label writeVolFields
(
ensCase,
ensMesh,
proxy,
getField<GeoField>(objects.findObject(fieldName), proxy),
nodeValues
getField<GeoField>(objects.findObject(fieldName), mesh),
nearCellValue
)
)
{
@ -118,29 +133,28 @@ label writeAllVolFields
(
ensightCase& ensCase,
const ensightMesh& ensMesh,
const fvMeshSubsetProxy& proxy,
const IOobjectList& objects,
const bool nodeValues
const bool nearCellValue = false
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
#undef ensight_WRITE_FIELD
#define ensight_WRITE_FIELD(PrimitiveType) \
writeVolFields<PrimitiveType> \
( \
ensCase, ensMesh, \
proxy, \
ensCase, \
ensMesh, \
objects, \
nodeValues \
nearCellValue \
)
label count = 0;
count += foamToEnsight_WRITE_FIELD(scalar);
count += foamToEnsight_WRITE_FIELD(vector);
count += foamToEnsight_WRITE_FIELD(sphericalTensor);
count += foamToEnsight_WRITE_FIELD(symmTensor);
count += foamToEnsight_WRITE_FIELD(tensor);
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 foamToEnsight_WRITE_FIELD
#undef ensight_WRITE_FIELD
return count;
}

View File

@ -1,4 +0,0 @@
foamToEnsightParts.C
readFields.C
EXE = $(FOAM_APPBIN)/foamToEnsightParts

View File

@ -1,15 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/conversion/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfileFormats \
-lconversion \
-ldynamicMesh \
-llagrangianIntermediate \
-lgenericPatchFields

View File

@ -1,45 +0,0 @@
// check for "points" in all of the result directories
// - could restrict to the selected times
bool meshMoving = false;
if (timeDirs.size() > 1 && Pstream::master())
{
// We already loaded a mesh (usually from constant).
// See if any other "polyMesh/points" files exist too.
Info<< "Search for moving mesh ... " << flush;
forAll(timeDirs, timeI)
{
meshMoving =
(
IOobject
(
"points",
timeDirs[timeI].name(),
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
).typeHeaderOk<pointIOField>(true, false)
);
if (meshMoving)
{
break;
}
}
if (meshMoving)
{
Info<< "found." << nl
<< " Writing meshes for every timestep." << endl;
}
else
{
Info<< "none detected." << endl;
}
}
reduce(meshMoving, orOp<bool>());

View File

@ -1,138 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 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/>.
Description
Code chunk for post-processing conversion of cloud(s) to Ensight
\*---------------------------------------------------------------------------*/
// Cloud field data output
if (doLagrangian)
{
forAll(cloudNames, cloudNo)
{
const word& cloudName = cloudNames[cloudNo];
const HashTable<word>& theseCloudFields = cloudFields[cloudName];
fileNameList currentCloudDirs
(
readDir
(
runTime.timePath()/regionPrefix/cloud::prefix,
fileName::DIRECTORY
)
);
Info<< "Write " << cloudName << " (";
const bool cloudExists =
returnReduce
(
currentCloudDirs.found(cloudName),
orOp<bool>()
);
{
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
ensightOutput::writeCloudPositions
(
mesh,
cloudName,
cloudExists,
os
);
Info<< " positions";
if (!cloudExists)
{
Info<< "{0}"; // report empty field
}
}
forAllConstIters(theseCloudFields, fieldIter)
{
const word& fieldName = fieldIter.key();
const word& fieldType = fieldIter.val();
IOobject fieldObject
(
fieldName,
mesh.time().timeName(),
cloud::prefix/cloudName,
mesh,
IOobject::MUST_READ
);
bool fieldExists = cloudExists; // No field without positions
if (cloudExists)
{
// Want MUST_READ (globally) and valid=false (locally),
// but that combination does not work.
// So check the header and sync globally
fieldExists =
fieldObject.typeHeaderOk<IOField<scalar>>(false);
reduce(fieldExists, orOp<bool>());
}
bool wrote = false;
if (fieldType == scalarIOField::typeName)
{
autoPtr<ensightFile> os =
ensCase.newCloudData<scalar>(cloudName, fieldName);
wrote = ensightOutput::writeCloudField<scalar>
(
fieldObject, fieldExists, os
);
}
else if (fieldType == vectorIOField::typeName)
{
autoPtr<ensightFile> os =
ensCase.newCloudData<vector>(cloudName, fieldName);
wrote = ensightOutput::writeCloudField<vector>
(
fieldObject, fieldExists, os
);
}
if (wrote)
{
Info<< ' ' << fieldName;
if (!fieldExists)
{
Info<< "{0}"; // report empty field
}
}
}
Info<< " )" << nl;
}
}
// ************************************************************************* //

View File

@ -1,94 +0,0 @@
// check all time directories for the following:
// The fields for each cloud:
HashTable<HashTable<word>> cloudFields;
// Identify if lagrangian data exist at any time step.
if (timeDirs.size() && doLagrangian)
{
const fileName& baseDir = mesh.time().path();
const fileName cloudPrefix(regionPrefix/cloud::prefix);
Info<< "Searching for lagrangian ... " << flush;
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
(
readDir
(
baseDir/timeName/cloudPrefix,
fileName::DIRECTORY
)
);
for (fileName& cloudDir : cloudDirs)
{
const word cloudName(std::move(cloudDir));
IOobjectList cloudObjs
(
mesh,
timeName,
cloudPrefix/cloudName
);
// 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"))
{
isCloud = true;
}
if (cloudObjs.erase("positions"))
{
isCloud = true;
}
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());
}
}
}
}
if (Pstream::parRun())
{
Pstream::mapCombineGather(cloudFields, HashTableOps::plusEqOp<word>());
Pstream::mapCombineScatter(cloudFields);
}
if (cloudFields.empty())
{
Info<< "none detected." << endl;
}
}
// Sorted list of cloud names
const wordList cloudNames(cloudFields.sortedToc());
if (cloudNames.size())
{
// Complete the echo information - as flatOutput
cloudNames.writeList(Info) << endl;
}
// ************************************************************************* //

View File

@ -1,370 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 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/>.
Application
foamToEnsightParts
Group
grpPostProcessingUtilities
Description
Translate OpenFOAM data to Ensight format with an Ensight part
for each cellZone and patch.
Usage
\b foamToEnsightParts [OPTION]
Options:
- \par -ascii
Write Ensight data in ASCII format instead of "C Binary"
- \par -fields \<fields\>
Specify single or multiple fields to write (all by default)
For example,
\verbatim
-fields T
-fields '(p T U \"alpha.*\")'
\endverbatim
The quoting is required to avoid shell expansions and to pass the
information as a single argument.
- \par -noZero
Exclude the often incomplete initial conditions.
- \par -index \<start\>
Ignore the time index contained in the time file and use a
simple indexing when creating the \c Ensight/data/######## files.
- \par -no-lagrangian
Suppress writing lagrangian positions and fields.
- \par -no-mesh
Suppress writing the geometry. Can be useful for converting partial
results for a static geometry.
- \par -noZero
Exclude the often incomplete initial conditions.
- \par -name \<subdir\>
Define sub-directory name to use for Ensight data (default: "Ensight")
- \par -width \<n\>
Width of Ensight data subdir
Note
- no parallel data.
- writes to \a Ensight directory to avoid collisions with foamToEnsight.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "timeSelector.H"
#include "IOobjectList.H"
#include "IOmanip.H"
#include "OFstream.H"
#include "PstreamCombineReduceOps.H"
#include "HashOps.H"
#include "fieldTypes.H"
#include "volFields.H"
#include "scalarIOField.H"
#include "vectorIOField.H"
// file-format/conversion
#include "ensightCase.H"
#include "ensightGeoFile.H"
#include "ensightParts.H"
#include "ensightOutputCloud.H"
#include "ensightOutputVolField.H"
#include "fvMeshSubsetProxy.H"
// local files
#include "readFields.H"
#include "writeVolFields.H"
#include "writeDimFields.H"
#include "memInfo.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Translate OpenFOAM data to Ensight format with an Ensight part"
" for each cellZone and patch."
);
// Enable -constant
// Probably don't need -withZero though, since the fields are vetted
// afterwards anyhow
timeSelector::addOptions(true, false); // constant(true), zero(false)
#include "addRegionOption.H"
argList::noParallel();
argList::addBoolOption
(
"ascii",
"Write in ASCII format instead of 'C Binary'"
);
argList::addOption
(
"index",
"start",
"Ignore the time index contained in the uniform/time file"
" and use simple indexing when creating files"
);
argList::addBoolOption
(
"no-lagrangian", // noLagrangian
"Suppress writing lagrangian positions and fields"
);
argList::addOptionCompat("no-lagrangian", {"noLagrangian", 1806});
argList::addBoolOption
(
"no-mesh", // noMesh
"Suppress writing the geometry."
" Can be useful for converting partial results for a static geometry"
);
argList::addOptionCompat("no-mesh", {"noMesh", 1806});
argList::addOption
(
"fields",
"wordRes",
"Specify single or multiple fields to write (all by default)\n"
"Eg, 'T' or '( \"U.*\" )'"
);
argList::addOption
(
"name",
"subdir",
"Sub-directory name for Ensight output (default: 'Ensight')"
);
argList::addOption
(
"width",
"n",
"Width of Ensight data subdir"
);
#include "setRootCase.H"
// Default to binary output, unless otherwise specified
const IOstream::streamFormat format =
(
args.found("ascii")
? IOstream::ASCII
: 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"
fileName regionPrefix; // Mesh instance (region0 gets filtered out)
if (regionName != polyMesh::defaultRegion)
{
regionPrefix = regionName;
}
//
// general (case) output options
//
ensightCase::options caseOpts(format);
caseOpts.width(args.get<label>("width", 8));
caseOpts.overwrite(false); // leave existing output directory
// 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 ensightDir = args.get<word>("name", "Ensight");
if (!ensightDir.isAbsolute())
{
ensightDir = args.globalPath()/ensightDir;
}
//
// Open new ensight case file, initialize header etc.
//
ensightCase ensCase
(
ensightDir,
"Ensight", // args.globalCaseName(),
caseOpts
);
//
// Output configuration
//
// Control for renumbering iterations
label indexingNumber = 0;
const bool optIndex = args.readIfPresent("index", indexingNumber);
const bool doLagrangian = !args.found("no-lagrangian");
// Write the geometry, unless otherwise specified
bool doGeometry = !args.found("no-mesh");
//
// Output configuration (field related)
//
wordRes fieldPatterns;
args.readListIfPresent<wordRe>("fields", fieldPatterns);
// Construct the list of ensight parts for the entire mesh
ensightParts ensParts(mesh);
// Write summary information
if (Pstream::master())
{
Info<< "Converting " << timeDirs.size() << " time steps" << endl;
OFstream info(ensCase.path()/"partsInfo");
info
<< "// summary of ensight parts" << nl << nl;
ensParts.writeSummary(info);
}
#include "checkMeshMoving.H"
#include "findCloudFields.H"
Info<< "Startup in "
<< timer.cpuTimeIncrement() << " s, "
<< 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();
// Only retain volume and dimensioned fields.
objects.filterClasses
(
[](const word& clsName){
return
(
fieldTypes::volume.found(clsName)
|| fieldTypes::internal.found(clsName)
);
}
);
wordList objectNames(objects.sortedNames());
// Check availability for all times...
checkData(mesh, timeDirs, objectNames);
testedObjectNames = objectNames;
}
if (meshMoving && !doGeometry)
{
Info<< "mesh is moving: ignoring '-no-mesh' option" << endl;
doGeometry = true;
}
forAll(timeDirs, timeI)
{
runTime.setTime(timeDirs[timeI], timeI);
#include "getTimeIndex.H"
#include "moveMesh.H"
ensCase.setTime(timeDirs[timeI], timeIndex);
Info<< "Time [" << timeIndex << "] = " << runTime.timeName() << nl;
if (timeI == 0 || mesh.moving())
{
if (mesh.moving())
{
ensParts.recalculate(mesh);
}
if (doGeometry)
{
autoPtr<ensightGeoFile> os = ensCase.newGeometry(meshMoving);
ensParts.write(os.ref());
}
}
// Objects at this time
IOobjectList objects(mesh, runTime.timeName());
// Restrict to objects that are available for all times
objects.filterObjects(testedObjectNames);
// Volume, internal fields
#include "convertVolumeFields.H"
// Lagrangian fields
#include "convertLagrangian.H"
Info<< "Wrote in "
<< timer.cpuTimeIncrement() << " s, "
<< mem.update().size() << " kB" << endl;
}
ensCase.write();
Info<< "\nEnd: "
<< timer.elapsedCpuTime() << " s, "
<< mem.update().peak() << " kB (peak)\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,19 +0,0 @@
{
IOobject io
(
"points",
runTime.timeName(),
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
);
if (io.typeHeaderOk<pointIOField>(true, false))
{
// Read new points
io.readOpt() = IOobject::MUST_READ;
mesh.movePoints(pointIOField(io));
}
}

View File

@ -1,101 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 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/>.
InNamespace
Foam
Description
Read fields from disk for foamToEnsight
SourceFiles
readFields.C
\*---------------------------------------------------------------------------*/
#ifndef readFields_H
#define readFields_H
#include "instantList.H"
#include "IOobjectList.H"
#include "fvMesh.H"
#include "fvMeshSubsetProxy.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Get the field and subset it, or return nullptr
template<class GeoField>
tmp<GeoField> getField(const IOobject* io, const fvMesh& mesh)
{
if (io)
{
auto tfield = tmp<GeoField>::New(*io, mesh);
return tfield;
}
return nullptr;
}
//- Get internal field and make it a zero-gradient volume field with subsetting
template<class GeoField>
tmp<GeoField>
getZeroGradField(const IOobject* io, const fvMesh& mesh)
{
if (io)
{
auto tdimfield =
tmp<typename GeoField::Internal>::New(*io, mesh);
auto tfield = fvMeshSubsetProxy::zeroGradientField(tdimfield());
tdimfield.clear();
return tfield;
}
return nullptr;
}
//- Check if fields are good to use (available at all times)
// ignore special fields (_0 fields),
// ignore fields that are not available for all time-steps
label checkData
(
const fvMesh& mesh,
const instantList& timeDirs,
wordList& objectNames
);
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,125 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 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/>.
InNamespace
Foam
Description
Read dimensioned fields from disk and write with ensightParts
SourceFiles
writeDimFields.H
\*---------------------------------------------------------------------------*/
#ifndef ensightParts_writeDimFields_H
#define ensightParts_writeDimFields_H
#include "writeVolFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
label writeDimFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const IOobjectList& objects
)
{
typedef GeometricField<Type, fvPatchField, volMesh> GeoField;
typedef typename
GeometricField
<
Type, fvPatchField, volMesh
>::Internal DimField;
label count = 0;
for (const word& fieldName : objects.sortedNames<DimField>())
{
const IOobject* io = objects.findObject(fieldName);
if
(
writeVolField<Type>
(
ensCase,
ensParts,
mesh,
getZeroGradField<GeoField>(io, mesh)
)
)
{
Info<< ' ' << fieldName;
++count;
}
}
return count;
}
label writeAllDimFields
(
ensightCase& ensCase,
const ensightParts& ensParts,
const fvMesh& mesh,
const IOobjectList& objects
)
{
#undef foamToEnsight_WRITE_FIELD
#define foamToEnsight_WRITE_FIELD(PrimitiveType) \
writeDimFields<PrimitiveType> \
( \
ensCase, ensParts, \
mesh, \
objects \
)
label count = 0;
count += foamToEnsight_WRITE_FIELD(scalar);
count += foamToEnsight_WRITE_FIELD(vector);
count += foamToEnsight_WRITE_FIELD(sphericalTensor);
count += foamToEnsight_WRITE_FIELD(symmTensor);
count += foamToEnsight_WRITE_FIELD(tensor);
#undef foamToEnsight_WRITE_FIELD
return count;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -7,10 +7,6 @@ common/writer/meshWriter.C
common/tables/boundaryRegion.C
common/tables/cellTable.C
ensight/mesh/ensightMesh.C
ensight/mesh/ensightMeshIO.C
ensight/mesh/ensightMeshOptions.C
fire/FIREMeshReader.C
fire/FIREMeshWriter.C
fire/checkFireEdges.C

View File

@ -1,404 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightMesh.H"
#include "fvMesh.H"
#include "globalMeshData.H"
#include "PstreamCombineReduceOps.H"
#include "emptyPolyPatch.H"
#include "processorPolyPatch.H"
#include "mapDistribute.H"
#include "stringListOps.H"
#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightMesh::clear()
{
meshCells_.clear();
boundaryPatchFaces_.clear();
faceZoneFaces_.clear();
patchLookup_.clear();
globalPointsPtr_.clear();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightMesh::ensightMesh
(
const fvMesh& mesh,
const ensightMesh::options& opts
)
:
options_(new options(opts)),
mesh_(mesh),
needsUpdate_(true)
{
if (!option().lazy())
{
correct();
}
}
Foam::ensightMesh::ensightMesh(const fvMesh& mesh)
:
ensightMesh(mesh, IOstream::streamFormat::BINARY)
{}
Foam::ensightMesh::ensightMesh
(
const fvMesh& mesh,
const IOstream::streamFormat format
)
:
options_(new options(format)),
mesh_(mesh),
needsUpdate_(true)
{
if (!option().lazy())
{
correct();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::ensightMesh::~ensightMesh()
{
deleteDemandDrivenData(options_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::ensightMesh::needsUpdate() const
{
return needsUpdate_;
}
bool Foam::ensightMesh::expire()
{
clear();
// Already marked as expired
if (needsUpdate_)
{
return false;
}
needsUpdate_ = true;
return true;
}
void Foam::ensightMesh::correct()
{
clear();
// Part number
label nParts = 0;
if (useInternalMesh())
{
meshCells_.index() = nParts++;
meshCells_.classify(mesh_);
// Determine parallel shared points
globalPointsPtr_ = mesh_.globalData().mergePoints
(
pointToGlobal_,
uniquePointMap_
);
}
meshCells_.reduce();
if (useBoundaryMesh())
{
// Patches are output. Check that they are synced.
mesh_.boundaryMesh().checkParallelSync(true);
wordList patchNames = mesh_.boundaryMesh().names();
if (Pstream::parRun())
{
// Do not include processor patches in matching
patchNames.resize(mesh_.boundaryMesh().nNonProcessor());
}
const wordRes& matcher = option().patchSelection();
const labelList patchIds =
(
matcher.empty()
? identity(patchNames.size()) // Use all
: findStrings(matcher, patchNames) // Use specified names
);
for (const label patchId : patchIds)
{
const word& patchName = patchNames[patchId];
// Use fvPatch (not polyPatch) to automatically remove empty patches
const fvPatch& p = mesh_.boundary()[patchId];
ensightFaces& ensFaces = boundaryPatchFaces_(patchName);
ensFaces.clear();
if (p.size())
{
// Local face addressing (offset = 0),
// - this is what we'll need later when writing fields
ensFaces.classify(p.patch());
}
else
{
// The patch is empty (on this processor)
// or the patch is 'empty' (as fvPatch type)
ensFaces.clear();
}
// Finalize
ensFaces.reduce();
if (ensFaces.total())
{
patchLookup_.set(patchId, patchName);
ensFaces.index() = nParts++;
}
else
{
boundaryPatchFaces_.erase(patchName);
}
}
// At this point,
// * patchLookup_ is a map of (patchId, name)
// * boundaryPatchFaces_ is a lookup by name for the faces elements
}
if (option().useFaceZones())
{
// Mark boundary faces to be excluded from export
bitSet excludeFace(mesh_.nFaces());
for (const polyPatch& pp : mesh_.boundaryMesh())
{
const auto* procPatch = isA<processorPolyPatch>(pp);
if (isA<emptyPolyPatch>(pp))
{
excludeFace.set(pp.range());
}
else if (procPatch && !procPatch->owner())
{
// Exclude neighbour-side, retain owner-side only
excludeFace.set(pp.range());
}
}
// Use sorted order for later consistency
const wordList zoneNames =
mesh_.faceZones().sortedNames(option().faceZoneSelection());
// Count face types in each selected faceZone
for (const word& zoneName : zoneNames)
{
const label zoneID = mesh_.faceZones().findZoneID(zoneName);
const faceZone& fz = mesh_.faceZones()[zoneID];
ensightFaces& ensFaces = faceZoneFaces_(zoneName);
ensFaces.clear();
if (fz.size())
{
ensFaces.classify
(
mesh_.faces(),
fz,
fz.flipMap(),
excludeFace
);
}
// Finalize
ensFaces.reduce();
if (ensFaces.total())
{
ensFaces.index() = nParts++;
}
else
{
faceZoneFaces_.erase(zoneName);
}
}
}
needsUpdate_ = false;
}
void Foam::ensightMesh::write(ensightGeoFile& os) const
{
//
// Write internalMesh
//
if (useInternalMesh())
{
const label nPoints = globalPoints().size();
const pointField uniquePoints(mesh_.points(), uniquePointMap_);
// writePartHeader(os, 0, "internalMesh");
// beginCoordinates(os, nPoints);
writeAllPoints
(
meshCells_.index(),
"internalMesh",
nPoints,
uniquePoints,
os
);
writeCellConnectivity(meshCells_, pointToGlobal_, os);
}
//
// Write patches - sorted by Id
//
for (const label patchId : patchLookup_.sortedToc())
{
const word& patchName = patchLookup_[patchId];
const ensightFaces& ensFaces = boundaryPatchFaces_[patchName];
const polyPatch& pp = mesh_.boundaryMesh()[patchId];
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh_.globalData().mergePoints
(
pp.meshPoints(),
pp.meshPointMap(),
pointToGlobal, // local point to unique global index
uniqueMeshPointLabels // unique global points
);
// Renumber the patch faces,
// from local patch indexing to unique global index
faceList patchFaces(pp.localFaces());
for (face& f : patchFaces)
{
inplaceRenumber(pointToGlobal, f);
}
writeAllPoints
(
ensFaces.index(),
patchName,
globalPointsPtr().size(),
pointField(mesh_.points(), uniqueMeshPointLabels),
os
);
writeFaceConnectivity(ensFaces, patchFaces, os);
}
//
// Write faceZones, if requested
//
for (const word& zoneName : faceZoneFaces_.sortedToc())
{
const ensightFaces& ensFaces = faceZoneFaces_[zoneName];
// Use the properly sorted faceIds (ensightFaces) and do NOT use the
// faceZone directly, otherwise the point-maps will not correspond.
// - perform face-flipping later
indirectPrimitivePatch pp
(
IndirectList<face>(mesh_.faces(), ensFaces.faceIds()),
mesh_.points()
);
// Renumber the points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh_.globalData().mergePoints
(
pp.meshPoints(),
pp.meshPointMap(),
pointToGlobal, // local point to unique global index
uniqueMeshPointLabels // unique global points
);
// Renumber the faces belonging to the faceZone,
// from local numbering to unique global index.
// Also a good place to perform face flipping
const boolList& flip = ensFaces.flipMap();
faceList patchFaces(pp.localFaces());
forAll(patchFaces, facei)
{
face& f = patchFaces[facei];
if (flip[facei])
{
f.flip();
}
inplaceRenumber(pointToGlobal, f);
}
writeAllPoints
(
ensFaces.index(),
zoneName,
globalPointsPtr().size(),
pointField(mesh_.points(), uniqueMeshPointLabels),
os
);
writeFaceConnectivity(ensFaces, patchFaces, os, true);
}
}
// ************************************************************************* //

View File

@ -1,503 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2018 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/>.
Class
Foam::ensightMesh
Description
Encapsulation of volume meshes for writing in ensight format.
SourceFiles
ensightMesh.C
ensightMeshIO.C
ensightMeshOptions.C
\*---------------------------------------------------------------------------*/
#ifndef ensightMesh_H
#define ensightMesh_H
#include "ensightCells.H"
#include "ensightFaces.H"
#include "ensightGeoFile.H"
#include "cellList.H"
#include "faceList.H"
#include "cellShapeList.H"
#include "HashTable.H"
#include "Map.H"
#include "scalarField.H"
#include "wordRes.H"
#include "globalIndex.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class fvMesh;
class ensightMesh;
/*---------------------------------------------------------------------------*\
Class ensightMesh Declaration
\*---------------------------------------------------------------------------*/
class ensightMesh
{
public:
// Forward declarations
class options;
private:
// Private data
//- Writer options
const options* options_;
//- Reference to the OpenFOAM mesh
const fvMesh& mesh_;
//- The volume cells (internalMesh)
ensightCells meshCells_;
//- Face elements per patch
HashTable<ensightFaces> boundaryPatchFaces_;
//- Face elements per faceZone
HashTable<ensightFaces> faceZoneFaces_;
//- The list of patches to be output
Map<word> patchLookup_;
//- Track if it needs an update
mutable bool needsUpdate_;
// Parallel merged points
//- Global numbering for merged points
autoPtr<globalIndex> globalPointsPtr_;
//- From mesh point to global merged point
labelList pointToGlobal_;
//- Local points that are unique
labelList uniquePointMap_;
// Private Member Functions
//- Clear some storage
void clear();
//- Inplace renumber of cell-shapes
static cellShapeList& renumberShapes
(
cellShapeList& shapes,
const labelUList& pointToGlobal
);
//- Copy and return renumbered cell-shapes
static cellShapeList renumberShapes
(
const cellShapeList& shapes,
const labelUList& addr,
const labelUList& pointToGlobal
);
//- Write list of faces
static void writeFaceList
(
const faceList& faces,
ensightGeoFile& os
);
//- Write list of faces
static void writeFaceList
(
const UIndirectList<face>& faces,
ensightGeoFile& os
);
//- Return sizes of faces in the list
static labelList getFaceSizes
(
const faceList& faces
);
//- Return sizes of faces in the list
static labelList getFaceSizes
(
const UIndirectList<face>& faces
);
//- Write sizes of faces in the list
static void writeFaceSizes
(
const faceList& faces,
ensightGeoFile& os
);
//- Write sizes of faces in the list
static void writeFaceSizes
(
const UIndirectList<face>& faces,
ensightGeoFile& os
);
//- Write cell connectivity via cell shapes
static void writeCellShapes
(
const cellShapeList& shapes,
ensightGeoFile& os
);
//- Return the number of faces per poly element
static labelList getPolysNFaces
(
const labelUList& polys,
const cellList& cellFaces
);
//- Write the number of faces per poly element
static void writePolysNFaces
(
const labelUList& polys,
const cellList& cellFaces,
ensightGeoFile& os
);
//- Return the number of points per poly element
static labelList getPolysNPointsPerFace
(
const labelUList& polys,
const cellList& cellFaces,
const faceList& faces
);
//- Write the number of points per poly element
static void writePolysNPointsPerFace
(
const labelUList& polys,
const cellList& cellFaces,
const faceList& faces,
ensightGeoFile& os
);
//- Write the point ids per poly element
static void writePolysPoints
(
const labelUList& addr,
const cellList& cellFaces,
const faceList& faces,
const labelList& faceOwner,
ensightGeoFile& os
);
//- Write the poly connectivity
void writePolysConnectivity
(
const labelUList& polys,
const labelList& pointToGlobal,
ensightGeoFile&
) const;
//- Write the regular cell connectivity for all types
void writeCellConnectivity
(
const ensightCells& ensCells,
const labelList& pointToGlobal,
ensightGeoFile& os
) const;
//- Write the regular cell connectivity for specified type
void writeCellConnectivity
(
ensightCells::elemType elemType,
const ensightCells& ensCells,
const labelList& pointToGlobal,
ensightGeoFile& os
) const;
//- Write the regular face connectivity for specified type and
//- and specified faces
void writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faces,
const labelUList& addr,
ensightGeoFile&
) const;
//- Write the regular face connectivity for specified type
void writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faces,
ensightGeoFile& os
) const;
void writeFaceConnectivity
(
const ensightFaces& ensFaces,
const faceList& faces,
ensightGeoFile& os,
const bool raw = false
) const;
void writeAllPoints
(
const label partId,
const word& ensightPartName,
const label nTotal,
const pointField& uniquePoints,
ensightGeoFile&
) const;
//- No copy construct
ensightMesh(const ensightMesh&) = delete;
//- No copy assignment
void operator=(const ensightMesh&) = delete;
public:
// Constructors
//- Construct from components
ensightMesh(const fvMesh& mesh, const options& opts);
//- Construct from fvMesh with all default options, binary output
explicit ensightMesh(const fvMesh& mesh);
//- Construct from fvMesh with all default options and specified format
ensightMesh(const fvMesh& mesh, const IOstream::streamFormat format);
//- Destructor
~ensightMesh();
// Member Functions
// Access
//- Reference to the underlying fvMesh
inline const fvMesh& mesh() const;
//- Reference to the writer/mesh options
inline const ensightMesh::options& option() const;
//- Ascii/Binary file output
inline IOstream::streamFormat format() const;
//- Using internal?
inline bool useInternalMesh() const;
//- Using boundary?
inline bool useBoundaryMesh() const;
//- The volume cells (internalMesh)
inline const ensightCells& meshCells() const;
//- The list of patches to be output
inline const Map<word>& patches() const;
//- Face elements per selected patch
inline const HashTable<ensightFaces>& boundaryPatchFaces() const;
//- Face elements per selected faceZone.
// To be output in sorted order.
inline const HashTable<ensightFaces>& faceZoneFaces() const;
// Parallel point merging
//- Global numbering for merged points
const globalIndex& globalPoints() const
{
return globalPointsPtr_();
}
//- From mesh point to global merged point
const labelList& pointToGlobal() const
{
return pointToGlobal_;
}
//- Local points that are unique
const labelList& uniquePointMap() const
{
return uniquePointMap_;
}
// Other
//- Does the content need an update?
bool needsUpdate() const;
//- Mark as needing an update.
// May also free up unneeded data.
// Return false if already marked as expired.
bool expire();
//- Update for new mesh
void correct();
// Output
//- Write to file
inline void write(autoPtr<ensightGeoFile>& os) const;
//- Write to file
void write(ensightGeoFile& os) const;
};
//- Configuration options for the ensightMesh
class ensightMesh::options
{
//- Ascii/Binary file output
IOstream::streamFormat format_;
//- Create in 'expired' mode
bool lazy_;
//- Use the internal mesh
bool internal_;
//- Use the boundary mesh
bool boundary_;
//- Output of selected patches only
wordRes patchPatterns_;
//- Output of selected faceZones
wordRes faceZonePatterns_;
public:
// Constructors
//- Construct for binary output
options();
//- Construct for specified format
explicit options(IOstream::streamFormat format);
// Member Functions
// Access
//- File output format (ascii | binary)
IOstream::streamFormat format() const;
//- Lazy creation? (ie, ensightMesh starts as needsUpdate)
bool lazy() const;
//- Using internal?
bool useInternalMesh() const;
//- Using boundary?
bool useBoundaryMesh() const;
//- Using faceZones?
bool useFaceZones() const;
//- Selection of patches. Empty if unspecified.
const wordRes& patchSelection() const;
//- Selection of faceZones. Empty if unspecified.
const wordRes& faceZoneSelection() const;
// Edit
//- Reset to defaults
void reset();
//- Lazy creation - ensightMesh starts as needsUpdate.
void lazy(bool beLazy);
//- Alter the useBoundaryMesh state
void useInternalMesh(bool on);
//- Alter the useBoundaryMesh state
void useBoundaryMesh(bool on);
//- Define patch selection matcher
void patchSelection(const UList<wordRe>& patterns);
//- Define patch selection matcher
void patchSelection(List<wordRe>&& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(const UList<wordRe>& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(List<wordRe>&& patterns);
// Housekeeping
//- Older name for useBoundaryMesh()
// \deprecated OCT-2018
bool usePatches() const { return useBoundaryMesh(); }
//- Older name for useBoundaryMesh()
// \deprecated OCT-2018
void noPatches(bool off) { useBoundaryMesh(!off); }
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightMeshI.H"
#endif
// ************************************************************************* //

View File

@ -1,794 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2016-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightMesh.H"
#include "fvMesh.H"
#include "globalMeshData.H"
#include "PstreamCombineReduceOps.H"
#include "processorPolyPatch.H"
#include "mapDistribute.H"
#include "stringListOps.H"
#include "ensightFile.H"
#include "ensightGeoFile.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::cellShapeList& Foam::ensightMesh::renumberShapes
(
cellShapeList& shapes,
const labelUList& pointToGlobal
)
{
for (cellShape& shape : shapes)
{
inplaceRenumber(pointToGlobal, shape);
}
return shapes;
}
Foam::cellShapeList Foam::ensightMesh::renumberShapes
(
const cellShapeList& shapes,
const labelUList& addr,
const labelUList& pointToGlobal
)
{
cellShapeList list(shapes, addr);
renumberShapes(list, pointToGlobal);
return list;
}
void Foam::ensightMesh::writeFaceList
(
const faceList& faceLst,
ensightGeoFile& os
)
{
for (const face& f : faceLst)
{
for (const label labi : f)
{
os.write(labi + 1);
}
os.newline();
}
}
void Foam::ensightMesh::writeFaceList
(
const UIndirectList<face>& faceLst,
ensightGeoFile& os
)
{
for (const face& f : faceLst)
{
for (const label labi : f)
{
os.write(labi + 1);
}
os.newline();
}
}
Foam::labelList Foam::ensightMesh::getFaceSizes
(
const faceList& faceLst
)
{
labelList list(faceLst.size());
auto outIter = list.begin();
for (const face& f : faceLst)
{
*outIter = f.size();
++outIter;
}
return list;
}
Foam::labelList Foam::ensightMesh::getFaceSizes
(
const UIndirectList<face>& faceLst
)
{
labelList list(faceLst.size());
auto outIter = list.begin();
for (const face& f : faceLst)
{
*outIter = f.size();
++outIter;
}
return list;
}
void Foam::ensightMesh::writeFaceSizes
(
const faceList& faceLst,
ensightGeoFile& os
)
{
for (const face& f : faceLst)
{
os.write(f.size());
os.newline();
}
}
void Foam::ensightMesh::writeFaceSizes
(
const UIndirectList<face>& faceLst,
ensightGeoFile& os
)
{
for (const face& f : faceLst)
{
os.write(f.size());
os.newline();
}
}
void Foam::ensightMesh::writeCellShapes
(
const cellShapeList& shapes,
ensightGeoFile& os
)
{
for (const cellShape& cellPoints : shapes)
{
// Convert global -> local index
// (note: Ensight indices start with 1)
// In ASCII, write one cell per line
for (const label pointi : cellPoints)
{
os.write(pointi + 1);
}
os.newline();
}
}
Foam::labelList Foam::ensightMesh::getPolysNFaces
(
const labelUList& addr,
const cellList& cellFaces
)
{
labelList list(addr.size());
auto outIter = list.begin();
// The number of faces per element
for (const label cellId : addr)
{
const labelUList& cf = cellFaces[cellId];
*outIter = cf.size();
++outIter;
}
return list;
}
void Foam::ensightMesh::writePolysNFaces
(
const labelUList& addr,
const cellList& cellFaces,
ensightGeoFile& os
)
{
// Write the number of faces per element (1/line in ASCII)
for (const label cellId : addr)
{
const labelUList& cf = cellFaces[cellId];
os.write(cf.size());
os.newline();
}
}
Foam::labelList Foam::ensightMesh::getPolysNPointsPerFace
(
const labelUList& addr,
const cellList& cellFaces,
const faceList& faces
)
{
// Count the number of faces per element
label nTotFaces = 0;
for (const label cellId : addr)
{
const labelUList& cf = cellFaces[cellId];
nTotFaces += cf.size();
}
labelList list(nTotFaces);
auto outIter = list.begin();
// The number of points per element face
for (const label cellId : addr)
{
const labelUList& cf = cellFaces[cellId];
for (const label facei : cf)
{
*outIter = faces[facei].size();
++outIter;
}
}
return list;
}
void Foam::ensightMesh::writePolysNPointsPerFace
(
const labelUList& addr,
const cellList& cellFaces,
const faceList& faces,
ensightGeoFile& os
)
{
// Write the number of points per element face (1/line in ASCII)
for (const label cellId : addr)
{
const labelUList& cf = cellFaces[cellId];
for (const label facei : cf)
{
os.write(faces[facei].size());
os.newline();
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightMesh::writePolysPoints
(
const labelUList& addr,
const cellList& cellFaces,
const faceList& faces,
const labelList& faceOwner,
ensightGeoFile& os
)
{
for (const label cellId : addr)
{
const labelUList& cf = cellFaces[cellId];
for (const label faceId : cf)
{
const face& f = faces[faceId]; // face points (in global points)
if (faceId < faceOwner.size() && faceOwner[faceId] != cellId)
{
// internal face, neighbour
//
// as per face::reverseFace(), but without copying
os.write(f[0] + 1);
for (label pti = f.size()-1; pti > 0; --pti)
{
os.write(f[pti] + 1);
}
}
else
{
for (const label labi : f)
{
os.write(labi + 1);
}
}
os.newline();
}
}
}
void Foam::ensightMesh::writePolysConnectivity
(
const labelUList& addr,
const labelList& pointToGlobal,
ensightGeoFile& os
) const
{
const cellList& cellFaces = mesh_.cells();
const faceList& meshFaces = mesh_.faces();
const labelList& faceOwner = mesh_.faceOwner();
// Number of faces for each poly cell
if (Pstream::master())
{
// Master
writePolysNFaces(addr, cellFaces, os);
// Slaves
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList addr(fromSlave);
cellList cellFaces(fromSlave);
writePolysNFaces(addr, cellFaces, os);
}
}
else
{
OPstream toMaster(Pstream::commsTypes::scheduled, Pstream::masterNo());
toMaster
<< addr
<< cellFaces;
}
// Number of points for each face of the above list
if (Pstream::master())
{
// Master
writePolysNPointsPerFace
(
addr,
cellFaces,
meshFaces,
os
);
// Slaves
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList addr(fromSlave);
cellList cellFaces(fromSlave);
faceList meshFaces(fromSlave);
writePolysNPointsPerFace
(
addr,
cellFaces,
meshFaces,
os
);
}
}
else
{
OPstream toMaster(Pstream::commsTypes::scheduled, Pstream::masterNo());
toMaster
<< addr
<< cellFaces
<< meshFaces;
}
// Renumber faces to use global point numbers
faceList faces(mesh_.faces());
for (face& f : faces)
{
inplaceRenumber(pointToGlobal, f);
}
// List of points id for each face of the above list
if (Pstream::master())
{
// Master
writePolysPoints
(
addr,
cellFaces,
faces,
faceOwner,
os
);
// Slaves
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList addr(fromSlave);
cellList cellFaces(fromSlave);
faceList faces(fromSlave);
labelList faceOwner(fromSlave);
writePolysPoints
(
addr,
cellFaces,
faces,
faceOwner,
os
);
}
}
else
{
OPstream toMaster(Pstream::commsTypes::scheduled, Pstream::masterNo());
toMaster
<< addr
<< cellFaces
<< faces
<< faceOwner;
}
}
void Foam::ensightMesh::writeCellConnectivity
(
const ensightCells::elemType elemType,
const ensightCells& ensCells,
const labelList& pointToGlobal,
ensightGeoFile& os
) const
{
const label nTotal = ensCells.total(elemType);
if (nTotal)
{
const labelUList& addr = ensCells.cellIds(elemType);
if (Pstream::master())
{
os.writeKeyword(ensightCells::key(elemType));
os.write(nTotal);
os.newline();
}
if (elemType == ensightCells::NFACED)
{
writePolysConnectivity
(
addr,
pointToGlobal,
os
);
}
else
{
const cellShapeList shapes
(
renumberShapes
(
mesh_.cellShapes(),
addr,
pointToGlobal
)
);
if (Pstream::master())
{
writeCellShapes(shapes, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
cellShapeList recv(fromSlave);
writeCellShapes(recv, os);
}
}
else
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< shapes;
}
}
}
}
void Foam::ensightMesh::writeCellConnectivity
(
const ensightCells& ensCells,
const labelList& pointToGlobal,
ensightGeoFile& os
) const
{
for (label typei=0; typei < ensightCells::nTypes; ++typei)
{
const ensightCells::elemType what =
ensightCells::elemType(typei);
writeCellConnectivity(what, ensCells, pointToGlobal, os);
}
}
void Foam::ensightMesh::writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faces,
ensightGeoFile& os
) const
{
if (nTotal)
{
if (Pstream::master())
{
os.writeKeyword(ensightFaces::key(elemType));
os.write(nTotal);
os.newline();
}
if (elemType == ensightFaces::NSIDED)
{
// Number of points per face
if (Pstream::master())
{
writeFaceSizes(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
faceList recv(fromSlave);
writeFaceSizes(recv, os);
}
}
else
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< faces;
}
}
// List of points id for each face
if (Pstream::master())
{
writeFaceList(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
faceList recv(fromSlave);
writeFaceList(recv, os);
}
}
else
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< faces;
}
}
}
void Foam::ensightMesh::writeFaceConnectivity
(
ensightFaces::elemType elemType,
const label nTotal,
const faceList& faceLst,
const labelUList& addr,
ensightGeoFile& os
) const
{
if (nTotal)
{
if (Pstream::master())
{
os.writeKeyword(ensightFaces::key(elemType));
os.write(nTotal);
os.newline();
}
const UIndirectList<face> faces(faceLst, addr);
if (elemType == ensightFaces::NSIDED)
{
// Number of points per face
if (Pstream::master())
{
writeFaceSizes(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
faceList recv(fromSlave);
writeFaceSizes(recv, os);
}
}
else
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< faces;
}
}
// List of points id per face
if (Pstream::master())
{
writeFaceList(faces, os);
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
faceList recv(fromSlave);
writeFaceList(recv, os);
}
}
else
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< faces;
}
}
}
void Foam::ensightMesh::writeFaceConnectivity
(
const ensightFaces& ensFaces,
const faceList& faceLst,
ensightGeoFile& os,
const bool raw
) const
{
for (label typei=0; typei < ensightFaces::nTypes; ++typei)
{
const ensightFaces::elemType what =
ensightFaces::elemType(typei);
if (raw)
{
writeFaceConnectivity
(
what,
ensFaces.total(what),
SubList<face>
(
faceLst,
ensFaces.faceIds(what).size(),
ensFaces.offset(what)
),
os
);
}
else
{
writeFaceConnectivity
(
what,
ensFaces.total(what),
faceLst,
ensFaces.faceIds(what),
os
);
}
}
}
void Foam::ensightMesh::writeAllPoints
(
const label partId,
const word& ensightPartName,
const label nPoints,
const pointField& uniquePoints,
ensightGeoFile& os
) const
{
if (Pstream::master())
{
os.beginPart(partId, ensightPartName);
// Write points
os.beginCoordinates(nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
os.writeList(uniquePoints.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
scalarField recv(fromSlave);
os.writeList(recv);
}
}
}
else
{
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< uniquePoints.component(cmpt);
}
}
}
// ************************************************************************* //

View File

@ -1,183 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2018 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightMesh::options::options()
:
options(IOstream::streamFormat::BINARY)
{}
Foam::ensightMesh::options::options(IOstream::streamFormat format)
:
format_(format),
lazy_(false),
internal_(true),
boundary_(true),
patchPatterns_(),
faceZonePatterns_()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::IOstream::streamFormat Foam::ensightMesh::options::format() const
{
return format_;
}
bool Foam::ensightMesh::options::lazy() const
{
return lazy_;
}
bool Foam::ensightMesh::options::useInternalMesh() const
{
return internal_;
}
bool Foam::ensightMesh::options::useBoundaryMesh() const
{
return boundary_;
}
bool Foam::ensightMesh::options::useFaceZones() const
{
return faceZonePatterns_.size();
}
void Foam::ensightMesh::options::reset()
{
internal_ = true;
boundary_ = true;
patchPatterns_.clear();
faceZonePatterns_.clear();
}
void Foam::ensightMesh::options::lazy(bool beLazy)
{
lazy_ = beLazy;
}
void Foam::ensightMesh::options::useInternalMesh(bool on)
{
internal_ = on;
}
void Foam::ensightMesh::options::useBoundaryMesh(bool on)
{
boundary_ = on;
if (!boundary_ && patchPatterns_.size())
{
patchPatterns_.clear();
WarningInFunction
<< "Deactivating boundary and removing old patch selection"
<< endl;
}
}
void Foam::ensightMesh::options::patchSelection
(
const UList<wordRe>& patterns
)
{
patchPatterns_ = wordRes(patterns);
if (!boundary_ && patchPatterns_.size())
{
patchPatterns_.clear();
WarningInFunction
<< "Ignoring patch selection, boundary is not active"
<< endl;
}
}
void Foam::ensightMesh::options::patchSelection
(
List<wordRe>&& patterns
)
{
patchPatterns_ = wordRes(std::move(patterns));
if (!boundary_ && patchPatterns_.size())
{
patchPatterns_.clear();
WarningInFunction
<< "Ignoring patch selection, boundary is not active"
<< endl;
}
}
void Foam::ensightMesh::options::faceZoneSelection
(
const UList<wordRe>& patterns
)
{
faceZonePatterns_ = wordRes(patterns);
}
void Foam::ensightMesh::options::faceZoneSelection
(
List<wordRe>&& patterns
)
{
faceZonePatterns_ = wordRes(std::move(patterns));
}
const Foam::wordRes& Foam::ensightMesh::options::patchSelection() const
{
return patchPatterns_;
}
const Foam::wordRes& Foam::ensightMesh::options::faceZoneSelection() const
{
return faceZonePatterns_;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,10 +35,8 @@ Description
#define ensightOutputVolField_H
#include "ensightOutput.H"
#include "ensightPart.H"
#include "ensightParts.H"
#include "ensightPartFaces.H"
#include "ensightPartCells.H"
#include "ensightFaces.H"
#include "ensightCells.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -46,40 +44,12 @@ Description
namespace Foam
{
// Forward declarations
// Forward Declarations
class ensightMesh;
namespace ensightOutput
{
/*---------------------------------------------------------------------------*\
Namespace ensightOutput::Detail
\*---------------------------------------------------------------------------*/
namespace Detail
{
//- Write volume field component-wise
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os
);
//- Write point field component-wise
template<class Type>
bool writePointField
(
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh,
ensightFile& os
);
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Namespace ensightOutput
\*---------------------------------------------------------------------------*/
@ -88,52 +58,32 @@ bool writePointField
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>&,
const ensightMesh& ensMesh,
ensightFile& os,
const bool nodeValues = false
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh
);
/*---------------------------------------------------------------------------*\
Namespace ensightOutput::Serial
\*---------------------------------------------------------------------------*/
namespace Serial
{
//- Write volume field component-wise for specified faces
//- Write volume field component-wise, optionally forcing interpolation
template<class Type>
bool writeVolField
(
ensightFile& os,
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartFaces& part,
ensightFile& os
const ensightMesh& ensMesh,
const bool nodeValues
);
//- Write volume field component-wise for specified cells
//- Write point field component-wise
template<class Type>
bool writeVolField
bool writePointField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartCells& part,
ensightFile& os
ensightFile& os,
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh
);
//- Write volume field component-wise
template<class Type>
bool writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightParts& list,
ensightFile& os
);
} // End namespace Serial
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensightOutput

View File

@ -5,8 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,74 +29,81 @@ License
#include "ensightMesh.H"
#include "fvMesh.H"
#include "globalIndex.H"
#include "linear.H"
#include "volPointInterpolation.H"
#include "interpolation.H"
#include "linear.H"
#include "processorFvPatch.H"
#include "uindirectPrimitivePatch.H"
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * Detail * * * * * * * * * * * * * * * * * //
template<class Type>
bool Foam::ensightOutput::Detail::writeVolField
bool Foam::ensightOutput::writeVolField
(
ensightFile& os,
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os
const ensightMesh& ensMesh
)
{
constexpr bool parallel = true;
bool parallel = Pstream::parRun();
const fvMesh& mesh = ensMesh.mesh();
const ensightCells& meshCells = ensMesh.meshCells();
const Map<word>& patchLookup = ensMesh.patches();
const HashTable<ensightFaces>& patchFaces = ensMesh.boundaryPatchFaces();
const HashTable<ensightFaces>& zoneFaces = ensMesh.faceZoneFaces();
const fvMesh& mesh = vf.mesh();
const polyBoundaryMesh& bmesh = mesh.boundaryMesh();
//
// write internalMesh, unless patch-selection was requested
//
if (ensMesh.useInternalMesh())
const Map<ensightCells>& cellZoneParts = ensMesh.cellZoneParts();
const Map<ensightFaces>& faceZoneParts = ensMesh.faceZoneParts();
const Map<ensightFaces>& boundaryParts = ensMesh.boundaryParts();
// Write internalMesh and cellZones - sorted by index
for (const label zoneId : cellZoneParts.sortedToc())
{
Detail::writeCellField(vf, meshCells, os, parallel);
const ensightCells& part = cellZoneParts[zoneId];
ensightOutput::writeField(os, vf, part, parallel);
}
//
// write patches
// use sortedToc for extra safety
//
const labelList patchIds = patchLookup.sortedToc();
for (const label patchId : patchIds)
{
const word& patchName = patchLookup[patchId];
const ensightFaces& part = patchFaces[patchName];
writeFaceField
// Write patches - sorted by index
for (const label patchId : boundaryParts.sortedToc())
{
const ensightFaces& part = boundaryParts[patchId];
if (patchId < 0 || patchId >= bmesh.size())
{
// Future handling of combined patches?
continue;
}
const label patchStart = bmesh[patchId].start();
// Either use a flat boundary field for all patches,
// or patch-local face ids
// Operate on a copy
ensightFaces localPart(part);
// Change from global faceIds to patch-local
localPart.decrFaceIds(patchStart);
ensightOutput::writeField
(
vf.boundaryField()[patchId],
part,
os,
vf.boundaryField()[patchId],
localPart,
parallel
);
}
//
// write faceZones, if requested
// use sortedToc for extra safety
//
const wordList zoneNames = zoneFaces.sortedToc();
if (!zoneNames.empty())
// No face zones data
if (faceZoneParts.empty())
{
// Interpolates cell values to faces - needed only when exporting
// faceZones...
GeometricField<Type, fvsPatchField, surfaceMesh> sf
(
Foam::linearInterpolate(vf)
);
return true;
}
// flat boundary field
// Flat boundary field
// similar to volPointInterpolation::flatBoundaryField()
Field<Type> flat(mesh.nBoundaryFaces(), Zero);
@ -131,31 +137,59 @@ bool Foam::ensightOutput::Detail::writeVolField
}
}
for (const word& zoneName : zoneNames)
{
const ensightFaces& part = zoneFaces[zoneName];
// Field (local size)
Field<Type> values(part.size());
// Interpolate cell values to faces
// - only needed when exporting faceZones...
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tsfld
= Foam::linearInterpolate(vf);
const auto& sfld = tsfld();
// Local output buffer
label maxLen = 0;
forAllConstIters(faceZoneParts, iter)
{
maxLen = max(maxLen, iter.val().size());
}
DynamicField<Type> values(maxLen);
//
// Write requested faceZones - sorted by index
//
for (const label zoneId : faceZoneParts.sortedToc())
{
const ensightFaces& part = faceZoneParts[zoneId];
// Loop over face ids to store the needed field values
// - internal faces use linear interpolation
// - boundary faces use the corresponding patch value
forAll(part, i)
// Local copy of the field
values.resize(part.size());
values = Zero;
auto valIter = values.begin();
for (const label faceId : part.faceIds())
{
const label faceId = part[i];
values[i] =
*valIter =
(
mesh.isInternalFace(faceId)
? sf[faceId]
? sfld[faceId]
: flat[faceId - mesh.nInternalFaces()]
);
++valIter;
}
// The field is already copied in the proper order
// The field is already in the proper element order
// - just need its corresponding sub-fields
Detail::writeFaceSubField(values, part, os, parallel);
}
ensightOutput::Detail::writeFaceSubField(os, values, part, parallel);
}
return true;
@ -163,118 +197,90 @@ bool Foam::ensightOutput::Detail::writeVolField
template<class Type>
bool Foam::ensightOutput::Detail::writePointField
bool Foam::ensightOutput::writePointField
(
ensightFile& os,
const GeometricField<Type, pointPatchField, pointMesh>& pf,
const ensightMesh& ensMesh,
ensightFile& os
const ensightMesh& ensMesh
)
{
constexpr bool parallel = true;
bool parallel = Pstream::parRun();
const fvMesh& mesh = ensMesh.mesh();
const Map<word>& patchLookup = ensMesh.patches();
const polyMesh& mesh = ensMesh.mesh();
const HashTable<ensightFaces>& patchFaces = ensMesh.boundaryPatchFaces();
const HashTable<ensightFaces>& zoneFaces = ensMesh.faceZoneFaces();
const Map<ensightCells>& cellZoneParts = ensMesh.cellZoneParts();
const Map<ensightFaces>& faceZoneParts = ensMesh.faceZoneParts();
const Map<ensightFaces>& boundaryParts = ensMesh.boundaryParts();
//
// write internalMesh, unless patch-selection was requested
// Write internalMesh and cellZones - sorted by index
//
if (ensMesh.useInternalMesh())
for (const label zoneId : cellZoneParts.sortedToc())
{
if (Pstream::master())
{
os.beginPart(0); // 0 = internalMesh
}
const ensightCells& part = cellZoneParts[zoneId];
Detail::writeFieldComponents
(
"coordinates",
Field<Type>(pf.internalField(), ensMesh.uniquePointMap()),
os,
parallel
);
}
//
// write patches
// use sortedToc for extra safety
//
const labelList patchIds = patchLookup.sortedToc();
for (const label patchId : patchIds)
{
const word& patchName = patchLookup[patchId];
const ensightFaces& part = patchFaces[patchName];
const fvPatch& p = mesh.boundary()[patchId];
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
p.patch().meshPoints(),
p.patch().meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
part.uniqueMeshPoints(mesh, uniqueMeshPointLabels, parallel);
if (Pstream::master())
{
os.beginPart(part.index());
}
Detail::writeFieldComponents
ensightOutput::Detail::writeFieldComponents
(
"coordinates",
Field<Type>(pf.internalField(), uniqueMeshPointLabels),
os,
ensightFile::coordinates,
UIndirectList<Type>(pf.internalField(), uniqueMeshPointLabels),
parallel
);
}
//
// write faceZones, if requested
// Write patches - sorted by index
//
const wordList zoneNames = zoneFaces.sortedToc();
for (const word& zoneName : zoneNames)
for (const label patchId : boundaryParts.sortedToc())
{
const ensightFaces& part = zoneFaces[zoneName];
const ensightFaces& part = boundaryParts[patchId];
uindirectPrimitivePatch p
(
UIndirectList<face>
(
mesh.faces(),
part.faceIds()
),
mesh.points()
);
// Renumber the patch points/faces into unique points
labelList pointToGlobal;
labelList uniqueMeshPointLabels;
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
p.meshPoints(),
p.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
part.uniqueMeshPoints(mesh, uniqueMeshPointLabels, parallel);
if (Pstream::master())
{
os.beginPart(part.index());
}
Detail::writeFieldComponents
ensightOutput::Detail::writeFieldComponents
(
"coordinates",
Field<Type>(pf.internalField(), uniqueMeshPointLabels),
os,
ensightFile::coordinates,
UIndirectList<Type>(pf.internalField(), uniqueMeshPointLabels),
parallel
);
}
//
// Write requested faceZones - sorted by index
//
for (const label zoneId : faceZoneParts.sortedToc())
{
const ensightFaces& part = faceZoneParts[zoneId];
labelList uniqueMeshPointLabels;
part.uniqueMeshPoints(mesh, uniqueMeshPointLabels, parallel);
if (Pstream::master())
{
os.beginPart(part.index());
}
ensightOutput::Detail::writeFieldComponents
(
os,
ensightFile::coordinates,
UIndirectList<Type>(pf.internalField(), uniqueMeshPointLabels),
parallel
);
}
@ -288,9 +294,9 @@ bool Foam::ensightOutput::Detail::writePointField
template<class Type>
bool Foam::ensightOutput::writeVolField
(
ensightFile& os,
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightMesh& ensMesh,
ensightFile& os,
const bool nodeValues
)
{
@ -303,90 +309,10 @@ bool Foam::ensightOutput::writeVolField
pfld.ref().checkOut();
pfld.ref().rename(vf.name());
return Detail::writePointField<Type>(pfld, ensMesh, os);
return ensightOutput::writePointField<Type>(os, pfld, ensMesh);
}
return Detail::writeVolField<Type>(vf, ensMesh, os);
}
// * * * * * * * * * * * * * * * * Serial * * * * * * * * * * * * * * * * * //
template<class Type>
bool Foam::ensightOutput::Serial::writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartFaces& part,
ensightFile& os
)
{
constexpr bool parallel = false; // serial
const label patchi = part.patchIndex();
if (patchi >= 0 && patchi < vf.boundaryField().size())
{
return ensightOutput::Detail::writeFaceField
(
vf.boundaryField()[patchi],
part,
os,
parallel
);
}
return false;
}
template<class Type>
bool Foam::ensightOutput::Serial::writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightPartCells& part,
ensightFile& os
)
{
constexpr bool parallel = false; // serial
return ensightOutput::Detail::writeCellField
(
vf.internalField(),
part,
os,
parallel
);
}
template<class Type>
bool Foam::ensightOutput::Serial::writeVolField
(
const GeometricField<Type, fvPatchField, volMesh>& vf,
const ensightParts& list,
ensightFile& os
)
{
for (const ensightPart& part : list)
{
const ensightPartFaces* fptr = isA<ensightPartFaces>(part);
if (fptr)
{
Serial::writeVolField(vf, *fptr, os);
continue;
}
const ensightPartCells* cptr = isA<ensightPartCells>(part);
if (cptr)
{
Serial::writeVolField(vf, *cptr, os);
continue;
}
}
return true;
return ensightOutput::writeVolField<Type>(os, vf, ensMesh);
}

View File

@ -7,12 +7,20 @@ ensight/file/ensightCaseOptions.C
ensight/file/ensightFile.C
ensight/file/ensightGeoFile.C
ensight/part/ensightCells.C
ensight/part/ensightFaces.C
ensight/part/ensightPart.C
ensight/part/ensightPartCells.C
ensight/part/ensightPartFaces.C
ensight/part/ensightParts.C
ensight/mesh/ensightMesh.C
ensight/mesh/ensightMeshOptions.C
ensight/output/ensightOutput.C
part = ensight/part
$(part)/cells/ensightCells.C
$(part)/cells/ensightCellsAddr.C
$(part)/cells/ensightCellsIO.C
$(part)/faces/ensightFaces.C
$(part)/faces/ensightFacesAddr.C
$(part)/faces/ensightFacesIO.C
$(part)/part/ensightPart.C
$(part)/surface/ensightOutputSurface.C
ensight/read/ensightReadFile.C
ensight/type/ensightPTraits.C

View File

@ -0,0 +1,479 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightMesh.H"
#include "ensightGeoFile.H"
#include "polyMesh.H"
#include "emptyPolyPatch.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::label Foam::ensightMesh::internalZone = -1;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Find matching ids based on whitelist, blacklist
//
// An empty whitelist accepts everything that is not blacklisted.
// A regex match is trumped by a literal match.
//
// Eg,
// input: ( abc apple wall wall1 wall2 )
// whitelist: ( abc def "wall.*" )
// blacklist: ( "[ab].*" wall )
//
// result: (abc wall1 wall2)
//
static labelList getSelected
(
const UList<word>& input,
const wordRes& whitelist,
const wordRes& blacklist
)
{
const label len = input.size();
if (whitelist.empty() && blacklist.empty())
{
return identity(len);
}
labelList indices(len);
label count = 0;
for (label i=0; i < len; ++i)
{
const auto& text = input[i];
bool accept = false;
if (whitelist.size())
{
const auto result = whitelist.matched(text);
accept =
(
result == wordRe::LITERAL
? true
: (result == wordRe::REGEX && !blacklist.match(text))
);
}
else
{
accept = !blacklist.match(text);
}
if (accept)
{
indices[count] = i;
++count;
}
}
indices.resize(count);
return indices;
}
// Patch names without processor patches
static wordList nonProcessorPatchNames(const polyBoundaryMesh& bmesh)
{
#ifdef FULLDEBUG
// Patches are output. Check that they are synced.
bmesh.checkParallelSync(true);
#endif
wordList patchNames(bmesh.names());
patchNames.resize(bmesh.nNonProcessor());
return patchNames;
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightMesh::clear()
{
cellZoneParts_.clear();
faceZoneParts_.clear();
boundaryParts_.clear();
}
void Foam::ensightMesh::renumber()
{
label partNo = 0;
for (const label id : cellZoneParts_.sortedToc())
{
cellZoneParts_[id].index() = partNo++;
}
for (const label id : boundaryParts_.sortedToc())
{
boundaryParts_[id].index() = partNo++;
}
for (const label id : faceZoneParts_.sortedToc())
{
faceZoneParts_[id].index() = partNo++;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightMesh::ensightMesh
(
const polyMesh& mesh
)
:
ensightMesh(mesh, ensightMesh::options())
{}
Foam::ensightMesh::ensightMesh
(
const polyMesh& mesh,
const ensightMesh::options& opts
)
:
options_(new options(opts)),
mesh_(mesh),
needsUpdate_(true)
{
if (!option().lazy())
{
correct();
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightMesh::correct()
{
clear();
const wordRes& czMatcher = option().cellZoneSelection();
const wordRes& fzMatcher = option().faceZoneSelection();
// Possible cellZones
const wordList czNames =
(
(
option().useCellZones()
&& (!czMatcher.empty() || option().useInternalMesh())
)
? mesh_.cellZones().names()
: wordList()
);
const labelList czoneIds =
(
czMatcher.empty()
? identity(czNames.size()) // All
: czMatcher.matching(czNames) // Selected names
);
// Possible faceZones
const wordList fzNames =
(
option().useFaceZones()
? mesh_.faceZones().names()
: wordList()
);
const labelList fzoneIds =
(
fzMatcher.empty()
? identity(fzNames.size()) // All
: fzMatcher.matching(fzNames) // Selected names
);
// Possible patchNames
const wordList patchNames =
(
option().useBoundaryMesh()
? nonProcessorPatchNames(mesh_.boundaryMesh())
: wordList()
);
const labelList patchIds =
(
option().useBoundaryMesh()
? getSelected
(
patchNames,
option().patchSelection(),
option().patchExclude()
)
: labelList()
);
// Track which cells are in a zone or not
bitSet cellSelection;
// Faces to be excluded from export
bitSet excludeFace;
// cellZones first
for (const label zoneId : czoneIds)
{
const word& zoneName = czNames[zoneId];
const cellZone& zn = mesh_.cellZones()[zoneId];
if (returnReduce(!zn.empty(), orOp<bool>()))
{
cellSelection.set(zn);
ensightCells& part = cellZoneParts_(zoneId);
part.clear();
part.identifier() = zoneId;
part.rename(zoneName);
part.classify(mesh_, zn);
// Finalize
part.reduce();
}
}
if (option().useInternalMesh() && czMatcher.empty())
{
// The internal mesh:
// Either the entire mesh (if no zones specified)
// or whatever is leftover as unzoned
if (cellZoneParts_.empty())
{
ensightCells& part = cellZoneParts_(internalZone);
part.clear();
part.identifier() = internalZone;
part.rename("internalMesh");
part.classify(mesh_);
// Finalize
part.reduce();
}
else
{
// Unzoned cells - flip selection from zoned to unzoned
cellSelection.flip();
if (returnReduce(cellSelection.any(), orOp<bool>()))
{
ensightCells& part = cellZoneParts_(internalZone);
part.clear();
part.identifier() = internalZone;
part.rename("internalMesh");
part.classify(mesh_, cellSelection);
// Finalize
part.reduce();
}
}
// Handled all cells
cellSelection.clearStorage();
}
else if (cellSelection.none())
{
// No internal, no cellZones selected - just ignore
cellSelection.clearStorage();
}
// Face exclusion based on cellZones
if (returnReduce(!cellSelection.empty(), orOp<bool>()))
{
excludeFace.resize(mesh_.nFaces());
const labelList& owner = mesh_.faceOwner();
forAll(owner, facei)
{
const label celli = owner[facei];
if (!cellSelection.test(celli))
{
excludeFace.set(facei);
}
}
}
// Face exclusion for empty/processor types
// so they are ignored for face zones
if (fzoneIds.size())
{
excludeFace.resize(mesh_.nFaces());
for (const polyPatch& p : mesh_.boundaryMesh())
{
const auto* procPatch = isA<processorPolyPatch>(p);
if (isA<emptyPolyPatch>(p))
{
excludeFace.set(p.range());
}
else if (procPatch && !procPatch->owner())
{
// Exclude neighbour-side, retain owner-side only
excludeFace.set(p.range());
}
}
}
// Patches
for (const label patchId : patchIds)
{
const word& patchName = patchNames[patchId];
const polyPatch& p = mesh_.boundaryMesh()[patchId];
if (isA<emptyPolyPatch>(p))
{
// Skip empty patch types
continue;
}
else if (isA<processorPolyPatch>(p))
{
// Only real (non-processor) boundaries.
break;
}
ensightFaces& part = boundaryParts_(patchId);
part.clear();
part.identifier() = patchId;
part.rename(patchName);
part.classify
(
mesh_.faces(),
identity(p.size(), p.start()),
boolList(), // no flip map
excludeFace
);
// Finalize
part.reduce();
if (!part.total())
{
boundaryParts_.erase(patchId);
}
}
// Face zones
for (const label zoneId : fzoneIds)
{
const word& zoneName = fzNames[zoneId];
const faceZone& zn = mesh_.faceZones()[zoneId];
ensightFaces& part = faceZoneParts_(zoneId);
part.clear();
part.identifier() = zoneId;
part.rename(zoneName);
if (zn.size())
{
part.classify
(
mesh_.faces(),
zn,
zn.flipMap(),
excludeFace
);
}
// Finalize
part.reduce();
if (!part.total())
{
faceZoneParts_.erase(zoneId);
}
}
renumber();
needsUpdate_ = false;
}
void Foam::ensightMesh::write
(
ensightGeoFile& os,
bool parallel
) const
{
// The internalMesh, cellZones
for (const label id : cellZoneParts_.sortedToc())
{
cellZoneParts_[id].write(os, mesh_, parallel);
}
// Patches - sorted by index
for (const label id : boundaryParts_.sortedToc())
{
boundaryParts_[id].write(os, mesh_, parallel);
}
// Requested faceZones - sorted by index
for (const label id : faceZoneParts_.sortedToc())
{
faceZoneParts_[id].write(os, mesh_, parallel);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,342 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 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/>.
Class
Foam::ensightMesh
Description
Encapsulation of volume meshes for writing in ensight format.
It manages cellZones, facesZone, patches.
When cellZones are present (and not disabled), the cells are grouped
in parts according to the zone.
Any remaining \em unzoned cells are placed into the "internalMesh" part,
which is always part 0. If cellZones are missing or disabled,
all cells are placed into the "internalMesh" part.
If one or more cellZones are explicitly requested, all other cells
(including any unzoned cells) are ignored.
The converted patch faces are restricted by the volume mesh coverage.
Except when the entire internal mesh has been explicitly suppressed.
Note
The internal data management uses a Map for cellZones, faceZones and
patches. The internalMesh is treated as cellZone with a special index.
Since the patches are subsetted by the internal mesh coverage,
they are treated as indirect patches rather than regular poly patches.
SourceFiles
ensightMesh.C
ensightMeshI.H
ensightMeshOptions.C
\*---------------------------------------------------------------------------*/
#ifndef ensightMesh_H
#define ensightMesh_H
#include "Map.H"
#include "ensightCells.H"
#include "ensightFaces.H"
#include "wordRes.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class polyMesh;
class ensightGeoFile;
class ensightMesh;
/*---------------------------------------------------------------------------*\
Class ensightMesh Declaration
\*---------------------------------------------------------------------------*/
class ensightMesh
{
public:
// Forward Declarations
class options;
//- The zone-id for internal mesh or unzoned cells.
static const label internalZone;
private:
// Private Data
//- Writer options
const std::unique_ptr<options> options_;
//- Reference to the OpenFOAM mesh
const polyMesh& mesh_;
//- Volume elements per cellZone, lookup by zone index.
// The zone -1 is reserved for internal mesh (unzoned cells)
Map<ensightCells> cellZoneParts_;
//- Face elements per faceZone, lookup by zone index.
Map<ensightFaces> faceZoneParts_;
//- Face elements per selected patch, lookup by patch index
Map<ensightFaces> boundaryParts_;
//- Track if it needs an update
mutable bool needsUpdate_;
// Private Member Functions
//- Clear all storage
void clear();
//- Enforce consistent index/part numbering
void renumber();
//- No copy construct
ensightMesh(const ensightMesh&) = delete;
//- No copy assignment
void operator=(const ensightMesh&) = delete;
public:
// Constructors
//- Construct from mesh with all default options
explicit ensightMesh(const polyMesh& mesh);
//- Construct from components
ensightMesh(const polyMesh& mesh, const options& opts);
// Member Functions
// Access
//- Reference to the underlying polyMesh
inline const polyMesh& mesh() const;
//- Reference to the writer/mesh options
inline const ensightMesh::options& option() const;
//- Face elements per selected patch, lookup by patch index
// Process in sorted order.
// May require special treatment for zone -1 (internal).
inline const Map<ensightCells>& cellZoneParts() const;
//- Face elements per faceZone, lookup by zone index.
// Process in sorted order.
inline const Map<ensightFaces>& faceZoneParts() const;
//- Face elements per selected patch, lookup by patch index
// Process in sorted order.
inline const Map<ensightFaces>& boundaryParts() const;
// Sizing Information
//- Any parts?
inline bool empty() const;
//- Number of parts
inline label size() const;
// Other
//- Does the content need an update?
inline bool needsUpdate() const;
//- Mark as needing an update.
// May also free up unneeded data.
// Return false if already marked as expired.
inline bool expire();
//- Update for new mesh
void correct();
// Output
//- Write geometry to file. Normally in parallel
inline void write
(
autoPtr<ensightGeoFile>& os,
bool parallel = Pstream::parRun()
) const;
//- Write geometry to file. Normally in parallel
void write
(
ensightGeoFile& os,
bool parallel = Pstream::parRun()
) const;
};
/*---------------------------------------------------------------------------*\
Class ensightMesh::options Declaration
\*---------------------------------------------------------------------------*/
//- Configuration options for the ensightMesh
class ensightMesh::options
{
// Private Data
//- Create in 'expired' mode
bool lazy_;
//- Use the internal mesh
bool internal_;
//- Use the boundary mesh
bool boundary_;
//- Handle cellZones (if internal_ is true)
bool cellZones_;
//- Selected patches only
wordRes patchInclude_;
//- Deselected patches
wordRes patchExclude_;
//- Selected cellZones
wordRes cellZoneInclude_;
//- Selected faceZones
wordRes faceZoneInclude_;
public:
// Constructors
//- Default construct. Non-lazy with internal/boundary/cellZones.
options();
// Member Functions
// Access
//- Lazy creation? (ie, ensightMesh starts as needsUpdate)
bool lazy() const;
//- Using internal?
bool useInternalMesh() const;
//- Using boundary?
bool useBoundaryMesh() const;
//- Using faceZones?
bool useFaceZones() const;
//- Using cellZones?
bool useCellZones() const;
//- Selection of patches. Empty if unspecified.
const wordRes& patchSelection() const;
//- Selection of black listed patches. Empty if unspecified.
const wordRes& patchExclude() const;
//- Selection of faceZones. Empty if unspecified.
const wordRes& faceZoneSelection() const;
//- Selection of faceZones. Empty if unspecified.
const wordRes& cellZoneSelection() const;
// Edit
//- Reset to defaults
void reset();
//- Lazy creation - ensightMesh starts as needsUpdate
void lazy(bool beLazy);
//- Alter the useBoundaryMesh state
void useInternalMesh(bool on);
//- Alter the useBoundaryMesh state
void useBoundaryMesh(bool on);
//- Alter the useCellZones state
void useCellZones(bool on);
//- Define patch selection matcher
void patchSelection(const UList<wordRe>& patterns);
//- Define patch selection matcher
void patchSelection(List<wordRe>&& patterns);
//- Define patch selection blacklist
void patchExclude(const UList<wordRe>& patterns);
//- Define patch selection blacklist
void patchExclude(List<wordRe>&& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(const UList<wordRe>& patterns);
//- Define faceZone selection matcher
void faceZoneSelection(List<wordRe>&& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(const UList<wordRe>& patterns);
//- Define cellZone selection matcher
void cellZoneSelection(List<wordRe>&& patterns);
// Output
//- Report values
void print(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightMeshI.H"
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,9 +25,9 @@ License
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::fvMesh& Foam::ensightMesh::mesh() const
inline const Foam::polyMesh& Foam::ensightMesh::mesh() const
{
return mesh_;
}
@ -39,53 +39,77 @@ inline const Foam::ensightMesh::options& Foam::ensightMesh::option() const
}
inline Foam::IOstream::streamFormat Foam::ensightMesh::format() const
inline const Foam::Map<Foam::ensightCells>&
Foam::ensightMesh::cellZoneParts() const
{
return options_->format();
return cellZoneParts_;
}
inline bool Foam::ensightMesh::useInternalMesh() const
inline const Foam::Map<Foam::ensightFaces>&
Foam::ensightMesh::faceZoneParts() const
{
return options_->useInternalMesh();
return faceZoneParts_;
}
inline bool Foam::ensightMesh::useBoundaryMesh() const
inline const Foam::Map<Foam::ensightFaces>&
Foam::ensightMesh::boundaryParts() const
{
return options_->useBoundaryMesh();
return boundaryParts_;
}
inline const Foam::ensightCells& Foam::ensightMesh::meshCells() const
inline bool Foam::ensightMesh::expire()
{
return meshCells_;
clear();
// Already marked as expired
if (needsUpdate_)
{
return false;
}
needsUpdate_ = true;
return true;
}
inline const Foam::Map<Foam::word>& Foam::ensightMesh::patches() const
inline bool Foam::ensightMesh::needsUpdate() const
{
return patchLookup_;
return needsUpdate_;
}
inline const Foam::HashTable<Foam::ensightFaces>&
Foam::ensightMesh::boundaryPatchFaces() const
inline bool Foam::ensightMesh::empty() const
{
return boundaryPatchFaces_;
return
(
cellZoneParts_.empty()
&& faceZoneParts_.empty()
&& boundaryParts_.empty()
);
}
inline const Foam::HashTable<Foam::ensightFaces>&
Foam::ensightMesh::faceZoneFaces() const
inline Foam::label Foam::ensightMesh::size() const
{
return faceZoneFaces_;
return
(
cellZoneParts_.size()
+ faceZoneParts_.size()
+ boundaryParts_.size()
);
}
inline void Foam::ensightMesh::write(autoPtr<ensightGeoFile>& os) const
inline void Foam::ensightMesh::write
(
autoPtr<ensightGeoFile>& os,
bool parallel
) const
{
write(os.ref());
write(os.ref(), parallel);
}

View File

@ -0,0 +1,340 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightMesh.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// DIY flatOutput without a leading size indicator
static Ostream& printPatterns(Ostream& os, const wordRes& list)
{
os << token::BEGIN_LIST;
bool sep = false;
for (const wordRe& item : list)
{
if (sep) os << token::SPACE;
os << item;
sep = true;
}
os << token::END_LIST;
return os;
}
} // End namespace
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightMesh::options::options()
:
lazy_(false),
internal_(true),
boundary_(true),
cellZones_(true),
patchInclude_(),
patchExclude_(),
cellZoneInclude_(),
faceZoneInclude_()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::ensightMesh::options::lazy() const
{
return lazy_;
}
bool Foam::ensightMesh::options::useInternalMesh() const
{
return internal_;
}
bool Foam::ensightMesh::options::useBoundaryMesh() const
{
return boundary_;
}
bool Foam::ensightMesh::options::useCellZones() const
{
return cellZones_;
}
bool Foam::ensightMesh::options::useFaceZones() const
{
return faceZoneInclude_.size();
}
void Foam::ensightMesh::options::reset()
{
internal_ = true;
boundary_ = true;
cellZones_ = true;
patchInclude_.clear();
patchExclude_.clear();
faceZoneInclude_.clear();
cellZoneInclude_.clear();
}
void Foam::ensightMesh::options::lazy(bool beLazy)
{
lazy_ = beLazy;
}
void Foam::ensightMesh::options::useInternalMesh(bool on)
{
internal_ = on;
}
void Foam::ensightMesh::options::useBoundaryMesh(bool on)
{
boundary_ = on;
if (!boundary_)
{
if (patchInclude_.size())
{
patchInclude_.clear();
WarningInFunction
<< "Deactivating boundary, removed old patch selection"
<< endl;
}
}
}
void Foam::ensightMesh::options::useCellZones(bool on)
{
cellZones_ = on;
if (!cellZones_ && cellZoneInclude_.size())
{
cellZoneInclude_.clear();
WarningInFunction
<< "Deactivating cellZones, removed old zone selection"
<< endl;
}
}
void Foam::ensightMesh::options::patchSelection
(
const UList<wordRe>& patterns
)
{
patchInclude_ = wordRes(patterns);
if (!boundary_ && patchInclude_.size())
{
patchInclude_.clear();
WarningInFunction
<< "Ignoring patch selection, boundary is disabled"
<< endl;
}
}
void Foam::ensightMesh::options::patchSelection
(
List<wordRe>&& patterns
)
{
patchInclude_ = wordRes(std::move(patterns));
if (!boundary_ && patchInclude_.size())
{
patchInclude_.clear();
WarningInFunction
<< "Ignoring patch selection, boundary is disabled"
<< endl;
}
}
void Foam::ensightMesh::options::patchExclude
(
const UList<wordRe>& patterns
)
{
patchExclude_ = wordRes(patterns);
}
void Foam::ensightMesh::options::patchExclude
(
List<wordRe>&& patterns
)
{
patchExclude_ = wordRes(std::move(patterns));
}
void Foam::ensightMesh::options::faceZoneSelection
(
const UList<wordRe>& patterns
)
{
faceZoneInclude_ = wordRes(patterns);
}
void Foam::ensightMesh::options::faceZoneSelection
(
List<wordRe>&& patterns
)
{
faceZoneInclude_ = wordRes(std::move(patterns));
}
void Foam::ensightMesh::options::cellZoneSelection
(
const UList<wordRe>& patterns
)
{
cellZoneInclude_ = wordRes(patterns);
if (!cellZones_ && cellZoneInclude_.size())
{
cellZoneInclude_.clear();
WarningInFunction
<< "Ignoring cellZone selection, cellZones are disabled"
<< endl;
}
}
void Foam::ensightMesh::options::cellZoneSelection
(
List<wordRe>&& patterns
)
{
cellZoneInclude_ = wordRes(std::move(patterns));
if (!cellZones_ && cellZoneInclude_.size())
{
cellZoneInclude_.clear();
WarningInFunction
<< "Ignoring cellZone selection, cellZones are disabled"
<< endl;
}
}
const Foam::wordRes& Foam::ensightMesh::options::patchSelection() const
{
return patchInclude_;
}
const Foam::wordRes& Foam::ensightMesh::options::patchExclude() const
{
return patchExclude_;
}
const Foam::wordRes& Foam::ensightMesh::options::faceZoneSelection() const
{
return faceZoneInclude_;
}
const Foam::wordRes& Foam::ensightMesh::options::cellZoneSelection() const
{
return cellZoneInclude_;
}
void Foam::ensightMesh::options::print(Ostream& os) const
{
os << "internal: " << Switch::name(internal_) << nl;
os << "cellZones: " << Switch::name(cellZones_) << nl;
if (cellZones_)
{
os.incrIndent();
if (!cellZoneInclude_.empty())
{
os.writeKeyword("include");
printPatterns(os, cellZoneInclude_) << nl;
}
os.decrIndent();
}
os << "boundary: " << Switch::name(boundary_) << nl;
if (boundary_)
{
os.incrIndent();
if (!patchInclude_.empty())
{
os.writeKeyword("include");
printPatterns(os, patchInclude_) << nl;
}
if (!patchExclude_.empty())
{
os.writeKeyword("exclude");
printPatterns(os, patchExclude_) << nl;
}
os.decrIndent();
}
os << "faceZones: " << Switch::name(useFaceZones()) << nl;
if (useFaceZones())
{
os.incrIndent();
if (!faceZoneInclude_.empty())
{
os.writeKeyword("include");
printPatterns(os, faceZoneInclude_) << nl;
}
os.decrIndent();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,490 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightOutput.H"
#include "cell.H"
#include "cellShape.H"
#include "face.H"
#include "polyMesh.H"
#include "ListOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Sizes
Foam::labelList Foam::ensightOutput::Detail::getFaceSizes
(
const UList<face>& faces
)
{
labelList list(faces.size());
auto outIter = list.begin();
for (const face& f : faces)
{
*outIter = f.size();
++outIter;
}
return list;
}
Foam::labelList Foam::ensightOutput::Detail::getFaceSizes
(
const UIndirectList<face>& faces
)
{
labelList list(faces.size());
auto outIter = list.begin();
for (const face& f : faces)
{
*outIter = f.size();
++outIter;
}
return list;
}
Foam::labelList Foam::ensightOutput::Detail::getPolysNFaces
(
const polyMesh& mesh,
const labelUList& addr
)
{
const cellList& meshCells = mesh.cells();
labelList list(addr.size());
auto outIter = list.begin();
// The number of faces per element
for (const label cellId : addr)
{
*outIter = meshCells[cellId].size();
++outIter;
}
return list;
}
Foam::labelList Foam::ensightOutput::Detail::getPolysNPointsPerFace
(
const polyMesh& mesh,
const labelUList& addr
)
{
const cellList& meshCells = mesh.cells();
const faceList& meshFaces = mesh.faces();
// Count the number of faces per element
label nTotFaces = 0;
for (const label cellId : addr)
{
nTotFaces += meshCells[cellId].size();
}
labelList list(nTotFaces);
auto outIter = list.begin();
// The number of points per element face
for (const label cellId : addr)
{
for (const label facei : meshCells[cellId])
{
*outIter = meshFaces[facei].size();
++outIter;
}
}
return list;
}
void Foam::ensightOutput::writeFaceList
(
ensightGeoFile& os,
const UList<face>& faces
)
{
for (const face& f : faces)
{
for (const label labi : f)
{
os.write(labi + 1);
}
os.newline();
}
}
void Foam::ensightOutput::writeFaceList
(
ensightGeoFile& os,
const UIndirectList<face>& faces
)
{
for (const face& f : faces)
{
for (const label labi : f)
{
os.write(labi + 1);
}
os.newline();
}
}
void Foam::ensightOutput::writeCellShapes
(
ensightGeoFile& os,
const UList<cellShape>& shapes
)
{
for (const cellShape& cellPoints : shapes)
{
// Convert global -> local index
// (note: Ensight indices start with 1)
// In ASCII, write one cell per line
for (const label pointi : cellPoints)
{
os.write(pointi + 1);
}
os.newline();
}
}
void Foam::ensightOutput::writePolysPoints
(
ensightGeoFile& os,
const polyMesh& mesh,
const labelUList& addr,
const labelList& pointMap
)
{
const cellList& meshCells = mesh.cells();
const faceList& meshFaces = mesh.faces();
const labelList& owner = mesh.faceOwner();
for (const label cellId : addr)
{
for (const label faceId : meshCells[cellId])
{
const face& f = meshFaces[faceId];
if (faceId < owner.size() && owner[faceId] != cellId)
{
// The neighbour of an internal face
// - write as face::reverseFace()
os.write(pointMap[f[0]] + 1);
for (label pti = f.size()-1; pti > 0; --pti)
{
os.write(pointMap[f[pti]] + 1);
}
}
else
{
for (const label pointi : f)
{
os.write(pointMap[pointi] + 1);
}
}
os.newline();
}
}
}
void Foam::ensightOutput::writePolysPoints
(
ensightGeoFile& os,
const cellUList& meshCells,
const labelUList& addr,
const faceUList& meshFaces,
const labelUList& owner
)
{
for (const label cellId : addr)
{
for (const label faceId : meshCells[cellId])
{
const face& f = meshFaces[faceId];
if (faceId < owner.size() && owner[faceId] != cellId)
{
// The neighbour of an internal face
// - write as face::reverseFace()
os.write(f[0] + 1);
for (label pti = f.size()-1; pti > 0; --pti)
{
os.write(f[pti] + 1);
}
}
else
{
for (const label pointi : f)
{
os.write(pointi + 1);
}
}
os.newline();
}
}
}
void Foam::ensightOutput::writeFaceConnectivity
(
ensightGeoFile& os,
const ensightFaces::elemType etype,
const label nTotal,
const faceUList& faces,
bool parallel
)
{
if (!nTotal)
{
return;
}
parallel = parallel && Pstream::parRun();
const label nSlaves = (parallel ? Pstream::nProcs() : 0);
if (Pstream::master())
{
os.writeKeyword(ensightFaces::key(etype));
os.write(nTotal);
os.newline();
}
if (etype == ensightFaces::NSIDED)
{
// Face sizes (number of points per face)
labelList send(ensightOutput::Detail::getFaceSizes(faces));
if (Pstream::master())
{
os.writeLabels(send);
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList recv(fromSlave);
os.writeLabels(recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << send;
}
}
// List of points id for each face
if (Pstream::master())
{
writeFaceList(os, faces);
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
List<face> recv(fromSlave);
writeFaceList(os, recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << faces;
}
}
void Foam::ensightOutput::writeFaceConnectivity
(
ensightGeoFile& os,
const ensightFaces::elemType etype,
const label nTotal,
const UIndirectList<face>& faces,
bool parallel
)
{
if (!nTotal)
{
return;
}
parallel = parallel && Pstream::parRun();
const label nSlaves = (parallel ? Pstream::nProcs() : 0);
if (Pstream::master())
{
os.writeKeyword(ensightFaces::key(etype));
os.write(nTotal);
os.newline();
}
if (etype == ensightFaces::NSIDED)
{
// Face sizes (number of points per face)
labelList send(ensightOutput::Detail::getFaceSizes(faces));
if (Pstream::master())
{
os.writeLabels(send);
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList recv(fromSlave);
os.writeLabels(recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << send;
}
}
// List of points id per face
if (Pstream::master())
{
writeFaceList(os, faces);
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
List<face> recv(fromSlave);
writeFaceList(os, recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << faces;
}
}
void Foam::ensightOutput::writeFaceConnectivity
(
ensightGeoFile& os,
const ensightFaces& part,
const faceUList& faces,
bool parallel
)
{
for (label typei=0; typei < ensightFaces::nTypes; ++typei)
{
const auto etype = ensightFaces::elemType(typei);
writeFaceConnectivity
(
os,
etype,
part.total(etype),
UIndirectList<face>(faces, part.faceIds(etype)),
parallel
);
}
}
void Foam::ensightOutput::writeFaceConnectivityPresorted
(
ensightGeoFile& os,
const ensightFaces& part,
const faceUList& faces,
bool parallel
)
{
for (label typei=0; typei < ensightFaces::nTypes; ++typei)
{
const auto etype = ensightFaces::elemType(typei);
writeFaceConnectivity
(
os,
etype,
part.total(etype),
SubList<face>(faces, part.range(etype)),
parallel
);
}
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,6 +30,7 @@ Description
A collection of functions for writing ensight file content.
SourceFiles
ensightOutput.C
ensightOutputTemplates.C
\*---------------------------------------------------------------------------*/
@ -38,18 +39,204 @@ SourceFiles
#define ensightOutput_H
#include "ensightFile.H"
#include "ensightGeoFile.H"
#include "ensightCells.H"
#include "ensightFaces.H"
#include "ensightPTraits.H"
#include "faceListFwd.H"
#include "cellListFwd.H"
#include "ListOps.H"
#include "ListListOps.H"
#include "IndirectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Local definitions, could be relocated to ListListOps directly
namespace Foam
{
namespace ListListOps
{
//- Return the sizes of the sub-lists
template<class T, class Addr, class AccessOp>
labelList subSizes
(
const IndirectListBase<T, Addr>& lists,
AccessOp aop
)
{
labelList output(lists.size());
auto out = output.begin();
for (const T& sub : lists)
{
*out = aop(sub).size();
++out;
}
return output;
}
//- Inplace renumber the values (not the indices) of a list of lists.
// Negative IntListType elements are left untouched.
template<class IntListType>
void inplaceRenumber
(
const labelUList& oldToNew,
IntListType& lists
)
{
for (auto& sub : lists)
{
for (auto& item : sub)
{
if (item >= 0)
{
item = oldToNew[item];
}
}
}
}
} // End namespace ListListOps
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class cellShape;
class polyMesh;
namespace ensightOutput
{
/*---------------------------------------------------------------------------*\
Geometry Output
\*---------------------------------------------------------------------------*/
//- Write list of faces
void writeFaceList
(
ensightGeoFile& os,
const UList<face>& faces
);
//- Write list of faces
void writeFaceList
(
ensightGeoFile& os,
const UIndirectList<face>& faces
);
//- Write cell connectivity via cell shapes
void writeCellShapes
(
ensightGeoFile& os,
const UList<cellShape>& shapes
);
//- Write the point ids per poly element.
// Points have been already renumbered
void writePolysPoints
(
ensightGeoFile& os,
const cellUList& meshCells,
const labelUList& addr, //!< Cell ids to write
const faceUList& meshFaces,
const labelUList& faceOwner
);
//- Write the point ids per poly element, with point renumbering
void writePolysPoints
(
ensightGeoFile& os,
const polyMesh& mesh,
const labelUList& addr, //!< Cell ids to write
const labelList& pointMap //!< Point map to use
);
//- Write the regular face connectivity for specified type and
//- and specified faces
void writeFaceConnectivity
(
ensightGeoFile& os,
const ensightFaces::elemType etype,
const label nTotal,
const UIndirectList<face>& faces,
bool parallel //!< Collective write?
);
//- Write the regular face connectivity for specified type
void writeFaceConnectivity
(
ensightGeoFile& os,
const ensightFaces::elemType etype,
const label nTotal,
const faceUList& faces,
bool parallel //!< Collective write?
);
//- Write the face connectivity for the part
void writeFaceConnectivity
(
ensightGeoFile& os,
const ensightFaces& part,
const faceUList& faces,
bool parallel //!< Collective write?
);
//- Write the \b presorted face connectivity for the part
// This is a special case when the list of faces is already in
// ensight sorted order
void writeFaceConnectivityPresorted
(
ensightGeoFile& os,
const ensightFaces& part,
const faceUList& faces,
bool parallel //!< Collective write?
);
/*---------------------------------------------------------------------------*\
Field Output
\*---------------------------------------------------------------------------*/
//- Write a field of cell values as an indirect list,
//- using the cell ids from ensightCells
template<class Type>
bool writeField
(
ensightFile& os,
const Field<Type>& fld,
const ensightCells& part,
bool parallel //!< Collective write?
);
//- Write a field of faces values as an indirect list,
//- using the face ids from ensightFaces
template<class Type>
bool writeField
(
ensightFile& os,
const Field<Type>& fld,
const ensightFaces& part,
bool parallel //!< Collective write?
);
/*---------------------------------------------------------------------------*\
Namespace ensightOutput::Detail
\*---------------------------------------------------------------------------*/
@ -60,76 +247,69 @@ namespace ensightOutput
namespace Detail
{
//- Write field content (component-wise) for the given ensight element type
//- Return sizes of faces in the list
labelList getFaceSizes(const UList<face>& faces);
//- Return sizes of faces in the list
labelList getFaceSizes(const UIndirectList<face>& faces);
//- The number of faces per poly element
labelList getPolysNFaces(const polyMesh& mesh, const labelUList& addr);
//- The number of points for each face of the poly elements
labelList getPolysNPointsPerFace(const polyMesh& mesh, const labelUList& addr);
//- Copy specified field component into a scalarField
// works for various lists types
template<template<typename> class FieldContainer, class Type>
bool writeFieldComponents
void copyComponent
(
const char* key,
const FieldContainer<Type>& fld,
ensightFile& os,
scalarField& res,
const FieldContainer<Type>& input,
const direction cmpt
);
//- Write coordinates (component-wise) for the given part
template<template<typename> class FieldContainer>
bool writeCoordinates
(
ensightGeoFile& os,
const label partId,
const word& partName,
const label nPoints,
const FieldContainer<Foam::point>& fld,
bool parallel //!< Collective write?
);
//- Write a field of faces values as an indirect list,
//- using the face ids from ensightFaces
template<class Type>
bool writeFaceField
//- Write field content (component-wise) for the given ensight element type
template<template<typename> class FieldContainer, class Type>
bool writeFieldComponents
(
const Field<Type>& fld,
const ensightFaces& part,
ensightFile& os,
const char* key,
const FieldContainer<Type>& fld,
bool parallel //!< Collective write?
);
//- Write a sub-field of faces values as an indirect list,
//- using the sublist sizing information from ensightFaces
//- using the sub-list sizing information from ensightFaces
template<class Type>
bool writeFaceSubField
(
ensightFile& os,
const Field<Type>& fld,
const ensightFaces& part,
ensightFile& os,
bool parallel //!< Collective write?
);
//- Write a field of cell values as an indirect list,
//- using the cell ids from ensightCells
template<class Type>
bool writeCellField
(
const Field<Type>& fld,
const ensightCells& part,
ensightFile& os,
bool parallel //!< Collective write?
);
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Namespace ensightOutput::Serial
\*---------------------------------------------------------------------------*/
//- \brief Output routines that are either designed for serial-only,
//- or for which parallelization is pending.
namespace Serial
{
//- Write a field of point (node) values (already compacted?)
template<class Type>
bool writePointField
(
const Field<Type>& fld,
const ensightFaces& part,
ensightFile& os
);
} // End namespace Serial
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace ensightOutput

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,73 +31,72 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<template<typename> class FieldContainer, class Type>
bool Foam::ensightOutput::Detail::writeFieldComponents
void Foam::ensightOutput::Detail::copyComponent
(
const char* key,
const FieldContainer<Type>& fld,
ensightFile& os,
scalarField& res,
const FieldContainer<Type>& input,
const direction cmpt
)
{
res.resize(input.size());
auto iter = res.begin();
for (const Type& val : input)
{
*iter = component(val, cmpt);
++iter;
}
}
template<template<typename> class FieldContainer>
bool Foam::ensightOutput::Detail::writeCoordinates
(
ensightGeoFile& os,
const label partId,
const word& partName,
const label nPoints,
const FieldContainer<Foam::point>& fld,
bool parallel
)
{
// Preliminary checks
// ~~~~~~~~~~~~~~~~~~
parallel = parallel && Pstream::parRun();
bool hasField = !fld.empty();
const label nSlaves = (parallel ? Pstream::nProcs() : 0);
if (parallel)
{
reduce(hasField, orOp<bool>());
}
// Nothing to write
if (!hasField) return false;
// End preliminary checks
// ~~~~~~~~~~~~~~~~~~~~~~
// Using manual copyComponent(...) instead of fld.component() to support
// indirect lists etc.
scalarField send(fld.size());
if (Pstream::master())
{
os.writeKeyword(key);
// Serial output, or parallel (master)
if (!parallel)
os.beginPart(partId, partName);
os.beginCoordinates(nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
// Serial output
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
copyComponent(send, fld, cmpt);
os.writeList(send);
os.writeList(fld.component(cmpt));
}
}
else
{
// Parallel (master)
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
os.writeList(fld.component(cmpt));
for (int slave=1; slave<Pstream::nProcs(); ++slave)
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
scalarField received(fromSlave);
os.writeList(received);
scalarField recv(fromSlave);
os.writeList(recv);
}
}
}
}
else if (parallel)
else if (nSlaves)
{
// Parallel (slaves)
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
const label cmpt = ensightPTraits<Type>::componentOrder[d];
copyComponent(send, fld, cmpt);
OPstream toMaster
(
@ -105,8 +104,7 @@ bool Foam::ensightOutput::Detail::writeFieldComponents
Pstream::masterNo()
);
toMaster
<< fld.component(cmpt);
toMaster << send;
}
}
@ -114,52 +112,77 @@ bool Foam::ensightOutput::Detail::writeFieldComponents
}
template<class Type>
bool Foam::ensightOutput::Detail::writeFaceField
template<template<typename> class FieldContainer, class Type>
bool Foam::ensightOutput::Detail::writeFieldComponents
(
const Field<Type>& fld,
const ensightFaces& part,
ensightFile& os,
const char* key,
const FieldContainer<Type>& fld,
bool parallel
)
{
// Preliminary checks
// ~~~~~~~~~~~~~~~~~~
parallel = parallel && Pstream::parRun();
bool hasGeom = (parallel ? part.total() : part.size());
const label nSlaves = (parallel ? Pstream::nProcs() : 0);
// Preliminary checks
{
bool hasField = !fld.empty();
if (parallel)
{
// Used 'pre-reduced' information for hasGeom
reduce(hasField, orOp<bool>());
}
// Nothing to write
if (!hasGeom || !hasField) return false;
// No field
if (!hasField) return false;
}
// End preliminary checks
// ~~~~~~~~~~~~~~~~~~~~~~
// Using manual copyComponent(...) instead of fld.component() to support
// indirect lists etc.
scalarField send(fld.size());
if (Pstream::master())
{
os.beginPart(part.index());
}
// Serial output, or parallel (master)
for (int typei=0; typei < ensightFaces::nTypes; ++typei)
os.writeKeyword(key);
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const ensightFaces::elemType what = ensightFaces::elemType(typei);
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
writeFieldComponents
copyComponent(send, fld, cmpt);
os.writeList(send);
for (label slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
scalarField recv(fromSlave);
os.writeList(recv);
}
}
}
else if (nSlaves)
{
// Parallel (slaves)
for (direction d=0; d < pTraits<Type>::nComponents; ++d)
{
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
copyComponent(send, fld, cmpt);
OPstream toMaster
(
ensightFaces::key(what),
Field<Type>(fld, part.faceIds(what)),
os,
parallel
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << send;
}
}
return true;
@ -169,31 +192,29 @@ bool Foam::ensightOutput::Detail::writeFaceField
template<class Type>
bool Foam::ensightOutput::Detail::writeFaceSubField
(
ensightFile& os,
const Field<Type>& fld,
const ensightFaces& part,
ensightFile& os,
bool parallel
)
{
// Preliminary checks
// ~~~~~~~~~~~~~~~~~~
parallel = parallel && Pstream::parRun();
bool hasGeom = (parallel ? part.total() : part.size());
// Preliminary checks: total() contains pre-reduced information
{
// No geometry
if (parallel ? !part.total() : !part.size()) return false;
bool hasField = !fld.empty();
if (parallel)
{
// Used 'pre-reduced' information for hasGeom
reduce(hasField, orOp<bool>());
}
// Nothing to write
if (!hasGeom || !hasField) return false;
// End preliminary checks
// ~~~~~~~~~~~~~~~~~~~~~~
// No field
if (!hasField) return false;
}
if (Pstream::master())
@ -201,104 +222,51 @@ bool Foam::ensightOutput::Detail::writeFaceSubField
os.beginPart(part.index());
}
labelList localAddr;
label start = 0; // The start of the sub-list
for (int typei=0; typei < ensightFaces::nTypes; ++typei)
{
const ensightFaces::elemType what = ensightFaces::elemType(typei);
const label size = part.faceIds(what).size();
writeFieldComponents
(
ensightFaces::key(what),
SubField<Type>(fld, size, start),
os,
parallel
);
start += size; // Advance the start for next sub-list
}
return true;
}
template<class Type>
bool Foam::ensightOutput::Serial::writePointField
(
const Field<Type>& fld,
const ensightFaces& part,
ensightFile& os
)
{
// Preliminary checks
// ~~~~~~~~~~~~~~~~~~
bool parallel = false && Pstream::parRun();
bool hasGeom = (parallel ? part.total() : part.size());
bool hasField = !fld.empty();
if (parallel)
{
// Used 'pre-reduced' information for hasGeom
reduce(hasField, orOp<bool>());
}
// Nothing to write
if (!hasGeom || !hasField) return false;
// End preliminary checks
// ~~~~~~~~~~~~~~~~~~~~~~
if (Pstream::master())
{
os.beginPart(part.index());
}
const auto etype = ensightFaces::elemType(typei);
ensightOutput::Detail::writeFieldComponents
(
"coordinates",
fld,
os,
ensightFaces::key(etype),
SubField<Type>(fld, part.range(etype)),
parallel
);
}
return true;
}
template<class Type>
bool Foam::ensightOutput::Detail::writeCellField
bool Foam::ensightOutput::writeField
(
ensightFile& os,
const Field<Type>& fld,
const ensightCells& part,
ensightFile& os,
bool parallel
)
{
// Preliminary checks
// ~~~~~~~~~~~~~~~~~~
parallel = parallel && Pstream::parRun();
bool hasGeom = (parallel ? part.total() : part.size());
// Preliminary checks: total() contains pre-reduced information
{
// No geometry
if (parallel ? !part.total() : !part.size()) return false;
bool hasField = !fld.empty();
if (parallel)
{
// Used 'pre-reduced' information for hasGeom
reduce(hasField, orOp<bool>());
}
// Nothing to write
if (!hasGeom || !hasField) return false;
// End preliminary checks
// ~~~~~~~~~~~~~~~~~~~~~~
// No field
if (!hasField) return false;
}
if (Pstream::master())
{
@ -307,13 +275,63 @@ bool Foam::ensightOutput::Detail::writeCellField
for (int typei=0; typei < ensightCells::nTypes; ++typei)
{
const ensightCells::elemType what = ensightCells::elemType(typei);
const auto etype = ensightCells::elemType(typei);
Detail::writeFieldComponents
ensightOutput::Detail::writeFieldComponents
(
ensightCells::key(what),
Field<Type>(fld, part.cellIds(what)),
os,
ensightCells::key(etype),
UIndirectList<Type>(fld, part.cellIds(etype)),
parallel
);
}
return true;
}
template<class Type>
bool Foam::ensightOutput::writeField
(
ensightFile& os,
const Field<Type>& fld,
const ensightFaces& part,
bool parallel
)
{
parallel = parallel && Pstream::parRun();
// Preliminary checks: total() contains pre-reduced information
{
// No geometry
if (parallel ? !part.total() : !part.size()) return false;
bool hasField = !fld.empty();
if (parallel)
{
reduce(hasField, orOp<bool>());
}
// No field
if (!hasField) return false;
}
if (Pstream::master())
{
os.beginPart(part.index());
}
for (int typei=0; typei < ensightFaces::nTypes; ++typei)
{
const auto etype = ensightFaces::elemType(typei);
ensightOutput::Detail::writeFieldComponents
(
os,
ensightFaces::key(etype),
UIndirectList<Type>(fld, part.faceIds(etype)),
parallel
);
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,31 +33,41 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightCells, 0);
}
const char* Foam::ensightCells::elemNames[5] =
{ "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
static_assert
(
Foam::ensightCells::nTypes == 5,
"Support exactly 5 cell types (tetra4, pyramid5, penta6, hexa8, nfaced)"
);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightCells::resizeAll()
{
// overall required size
label n = 0;
forAll(sizes_, typei)
{
n += sizes_[typei];
}
address_.setSize(n, Zero);
// Assign sub-list offsets, determine overall size
// assign corresponding sub-lists
n = 0;
forAll(sizes_, typei)
{
slices_[typei].setStart(n);
slices_[typei].setSize(sizes_[typei]);
label len = 0;
n += sizes_[typei];
auto iter = offsets_.begin();
*iter = 0;
for (const label n : sizes_)
{
len += n;
*(++iter) = len;
}
// The addressing space
addressing().resize(len, Zero);
}
@ -65,38 +75,17 @@ void Foam::ensightCells::resizeAll()
Foam::ensightCells::ensightCells()
:
ensightCells(0)
ensightPart(),
offsets_(Zero),
sizes_(Zero)
{}
Foam::ensightCells::ensightCells(const label partIndex)
Foam::ensightCells::ensightCells(const string& description)
:
index_(partIndex),
address_(),
slices_(),
sizes_(Zero)
ensightCells()
{
resizeAll(); // adjust allocation/sizing
}
Foam::ensightCells::ensightCells(const ensightCells& obj)
:
index_(obj.index_),
address_(obj.address_),
slices_(),
sizes_()
{
// Save the total (reduced) sizes
FixedList<label, 5> totSizes = obj.sizes_;
// Need local sizes for the resize operation
this->sizes_ = obj.sizes();
resizeAll(); // Adjust allocation/sizing
// Restore total (reduced) sizes
this->sizes_ = totSizes;
rename(description);
}
@ -105,9 +94,10 @@ Foam::ensightCells::ensightCells(const ensightCells& obj)
Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
{
FixedList<label, 5> count;
forAll(slices_, typei)
forAll(count, typei)
{
count[typei] = slices_[typei].size();
count[typei] = size(elemType(typei));
}
return count;
@ -127,17 +117,25 @@ Foam::label Foam::ensightCells::total() const
void Foam::ensightCells::clear()
{
sizes_ = Zero; // reset sizes
resizeAll();
clearOut();
ensightPart::clear();
sizes_ = Zero;
offsets_ = Zero;
}
void Foam::ensightCells::clearOut()
{}
void Foam::ensightCells::reduce()
{
// No listCombineGather, listCombineScatter for FixedList
forAll(sizes_, typei)
{
sizes_[typei] = slices_[typei].size();
sizes_[typei] = size(elemType(typei));
Foam::reduce(sizes_[typei], sumOp<label>());
}
}
@ -145,12 +143,15 @@ void Foam::ensightCells::reduce()
void Foam::ensightCells::sort()
{
forAll(slices_, typei)
for (int typei=0; typei < nTypes; ++typei)
{
if (slices_[typei].size())
const labelRange sub(range(elemType(typei)));
if (!sub.empty())
{
SubList<label> idLst(address_, slices_[typei]);
Foam::sort(idLst);
SubList<label> ids(addressing(), sub);
Foam::sort(ids);
}
}
}
@ -178,59 +179,56 @@ void Foam::ensightCells::classifyImpl
{
const cellModel& model = shapes[id].model();
enum elemType what = NFACED;
elemType etype(NFACED);
if (model == tet)
{
what = TETRA4;
etype = TETRA4;
}
else if (model == pyr)
{
what = PYRAMID5;
etype = PYRAMID5;
}
else if (model == prism)
{
what = PENTA6;
etype = PENTA6;
}
else if (model == hex)
{
what = HEXA8;
etype = HEXA8;
}
sizes_[what]++;
++sizes_[etype];
}
resizeAll(); // adjust allocation
sizes_ = Zero; // reset sizes - use for local indexing here
// Pass 2: Assign cell-id per shape type
for (const label id : cellIds)
{
const cellModel& model = shapes[id].model();
enum elemType what = NFACED;
elemType etype(NFACED);
if (model == tet)
{
what = TETRA4;
etype = TETRA4;
}
else if (model == pyr)
{
what = PYRAMID5;
etype = PYRAMID5;
}
else if (model == prism)
{
what = PENTA6;
etype = PENTA6;
}
else if (model == hex)
{
what = HEXA8;
etype = HEXA8;
}
// eg, the processor local cellId
labelUList slice = address_[slices_[what]];
slice[sizes_[what]] = id;
sizes_[what]++;
add(etype, id);
}
}
@ -262,4 +260,28 @@ void Foam::ensightCells::classify
}
void Foam::ensightCells::writeDict(Ostream& os, const bool full) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("size", size());
if (full)
{
for (int typei=0; typei < ensightCells::nTypes; ++typei)
{
const auto etype = ensightCells::elemType(typei);
os.writeKeyword(ensightCells::key(etype));
cellIds(etype).writeList(os, 0) << endEntry; // Flat output
}
}
os.endBlock();
}
// ************************************************************************* //

View File

@ -0,0 +1,279 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2020 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/>.
Class
Foam::ensightCells
Description
Sorting/classification of cells (3D) into corresponding ensight element
types.
\*---------------------------------------------------------------------------*/
#ifndef ensightCells_H
#define ensightCells_H
#include "ensightPart.H"
#include "FixedList.H"
#include "Map.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class bitSet;
class polyMesh;
/*---------------------------------------------------------------------------*\
Class ensightCells Declaration
\*---------------------------------------------------------------------------*/
class ensightCells
:
public ensightPart
{
public:
// Public Data
//- Supported ensight 'Cell' element types
// Must be zero-based since they are also for internal bookkeeping.
enum elemType
{
TETRA4 = 0, //!< "tetra4"
PYRAMID5, //!< "pyramid5"
PENTA6, //!< "penta6"
HEXA8, //!< "hexa8"
NFACED //!< "nfaced"
};
//- Number of 'Cell' element types (5)
static constexpr int nTypes = 5;
//- The ensight 'Cell' element type names
static const char* elemNames[nTypes];
// Static Functions
//- The ensight element name for the specified 'Cell' type
inline static const char* key(const elemType etype);
private:
// Private Data
//- Begin/end offsets for address of each element type
FixedList<label, nTypes+1> offsets_;
//- List of global sizes for each element type.
// Used temporarily for local sizes when building the element lists.
FixedList<label, nTypes> sizes_;
// Private Member Functions
//- Low-level internal addition routine
inline void add(const elemType etype, label id);
//- Use temporarily stored sizes to redimension the element lists
void resizeAll();
//- Classify cell types, set element lists for selection (implemention)
template<class Addressing>
void classifyImpl(const polyMesh& mesh, const Addressing& cellIds);
label meshPointMapppings
(
const polyMesh& mesh,
labelList& pointToGlobal, // Can also be labelList::null()
labelList& uniqueMeshPointLabels,
bool parallel
) const;
//- Write cell connectivity for polyhedral cells
static void writePolysConnectivity
(
ensightGeoFile& os,
const polyMesh& mesh,
const ensightCells& part,
const labelList& pointToGlobal,
bool parallel
);
//- Write cell connectivity for specified (non-poly) type
static void writeShapeConnectivity
(
ensightGeoFile& os,
const polyMesh& mesh,
const ensightCells::elemType etype,
const ensightCells& part,
const labelList& pointToGlobal,
bool parallel
);
public:
//- Declare type-name, virtual type (with debug switch)
TypeName("ensightCells");
// Constructors
//- Default construct, with part index 0
ensightCells();
//- Default construct, with description/partName
explicit ensightCells(const string& description);
//- Destructor
virtual ~ensightCells() = default;
// Member Functions
// Access
//- Processor-local size of all elements.
using ensightPart::size;
//- Processor-local size of the specified element type.
inline label size(const elemType etype) const;
//- Processor-local offset/size of element type.
inline labelRange range(const elemType etype) const;
//- The global size of all element types.
// This value is only meaningful after a reduce operation.
label total() const;
//- The global size of the specified element type.
// This value is only meaningful after a reduce operation.
inline label total(const elemType etype) const;
//- The global sizes for each element type.
// This value is only meaningful after a reduce operation.
inline const FixedList<label, nTypes>& totals() const;
//- Processor-local sizes per element type.
FixedList<label, nTypes> sizes() const;
//- Processor-local cell ids of all elements
inline const labelList& cellIds() const;
//- Processor-local cell ids of the specified element type
inline const labelUList cellIds(const elemType etype) const;
// Addressing
//- Mesh point map.
// Map mesh point index to local (compact) point index
Map<label> meshPointMap(const polyMesh& mesh) const;
// Edit
//- Classify cell types and set the element lists.
void classify(const polyMesh& mesh);
//- Classify cell types and set element lists,
//- using a subgroup of cells (eg, from a cellZone etc).
void classify(const polyMesh& mesh, const labelUList& cellIds);
//- Classify cell types and set element lists,
//- using a subgroup of cells
void classify(const polyMesh& mesh, const bitSet& selection);
//- Clear any demand-driven data
void clearOut();
//- Set addressable sizes to zero, free up addressing memory.
void clear();
//- Sum element counts across all processes.
void reduce();
//- Sort element lists numerically.
void sort();
// Advanced (use with caution)
//- Increase cell ids by specified offset value
// Eg, to change zone local Ids to global Ids
inline void incrCellIds(const label off);
//- Decrease face ids by specified offset value
// Eg, to change global Ids to zone local Ids
inline void decrCellIds(const label off);
// Output
//- Globally unique mesh points. Required when writing point fields.
label uniqueMeshPoints
(
const polyMesh& mesh,
labelList& uniqueMeshPointLabels,
bool parallel
) const;
//- Write information about the object as a dictionary,
//- optionally write all element addresses
virtual void writeDict(Ostream& os, const bool full=false) const;
//- Write geometry, using a mesh reference (serial only)
virtual void write
(
ensightGeoFile& os,
const polyMesh& mesh,
bool parallel
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightCellsI.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,238 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightCells.H"
#include "polyMesh.H"
#include "globalIndex.H"
#include "globalMeshData.H"
#include "ListOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::Map<Foam::label>
Foam::ensightCells::meshPointMap(const polyMesh& mesh) const
{
const label nEstimate = 8*this->size();
Map<label> pointMap(nEstimate);
// Pass 1: markup used points from cells
for (const label celli : this->cellIds())
{
for (const label facei : mesh.cells()[celli])
{
for (const label pointi : mesh.faces()[facei])
{
pointMap.insert(pointi, 0);
}
}
}
// Compact point numbering, preserves the original order
label nPoints = 0;
for (const label pointi : pointMap.sortedToc())
{
pointMap(pointi) = nPoints++;
}
return pointMap;
}
Foam::label Foam::ensightCells::meshPointMapppings
(
const polyMesh& mesh,
labelList& pointToGlobalRequest,
labelList& uniqueMeshPointLabels,
bool parallel
) const
{
labelList pointToGlobal;
const bool rewritePointMap = notNull(pointToGlobalRequest);
if (notNull(pointToGlobalRequest))
{
pointToGlobal.transfer(pointToGlobalRequest);
}
const ensightCells& part = *this;
parallel = parallel && Pstream::parRun();
// Renumber the points/faces into unique points
label nPoints = 0; // Total number of points
bool allCells = (part.size() == mesh.nCells());
if (parallel)
{
Foam::reduce(allCells, andOp<bool>());
if (allCells)
{
// All cells used, and thus all points
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
pointToGlobal,
uniqueMeshPointLabels
);
nPoints = globalPointsPtr().size(); // nPoints (global)
}
else
{
// Map mesh point index to local (compact) point index
Map<label> meshPointMap(part.meshPointMap(mesh));
labelList meshPoints(meshPointMap.sortedToc());
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
meshPoints,
meshPointMap,
pointToGlobal,
uniqueMeshPointLabels
);
nPoints = globalPointsPtr().size(); // nPoints (global)
meshPointMap.clear();
// The mergePoints returns pointToGlobal under the
// assumption of local addressing
// (eg, patch localFaces).
// Recast as original mesh points to new global points
if (rewritePointMap)
{
labelList oldToNew(mesh.nPoints(), -1);
forAll(meshPoints, i)
{
const label orig = meshPoints[i];
const label glob = pointToGlobal[i];
oldToNew[orig] = glob;
}
pointToGlobal.transfer(oldToNew);
}
}
}
else
{
// Non-parallel
nPoints = mesh.nPoints();
pointToGlobal.resize(nPoints);
if (allCells)
{
// All cells used, and thus all points
uniqueMeshPointLabels.resize(nPoints);
ListOps::identity(pointToGlobal);
ListOps::identity(uniqueMeshPointLabels);
}
else
{
// Mark up with -1 for unused entries
pointToGlobal = -1;
nPoints = 0;
// Pass 1: markup used points from cells
for (const label celli : this->cellIds())
{
for (const label facei : mesh.cells()[celli])
{
for (const label pointi : mesh.faces()[facei])
{
if (pointToGlobal[pointi] == -1)
{
pointToGlobal[pointi] = nPoints++;
}
}
}
}
// Pass 2:
//
// Compact point numbering, preserving original point order
uniqueMeshPointLabels.resize(nPoints);
nPoints = 0;
forAll(pointToGlobal, pointi)
{
if (pointToGlobal[pointi] != -1)
{
pointToGlobal[pointi] = nPoints;
uniqueMeshPointLabels[nPoints] = pointi;
++nPoints;
}
}
}
}
if (notNull(pointToGlobalRequest))
{
pointToGlobalRequest.transfer(pointToGlobal);
}
return nPoints;
}
Foam::label Foam::ensightCells::uniqueMeshPoints
(
const polyMesh& mesh,
labelList& uniqueMeshPointLabels,
bool parallel
) const
{
return meshPointMapppings
(
mesh,
const_cast<labelList&>(labelList::null()), // Ignore pointToGlobal
uniqueMeshPointLabels,
parallel
);
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,31 +25,22 @@ License
\*---------------------------------------------------------------------------*/
#include "error.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline const char* Foam::ensightCells::key(const enum elemType what)
inline void Foam::ensightCells::add(const elemType etype, label id)
{
return elemNames[what];
// Linear addressing location
const label index = offsets_[etype] + sizes_[etype]++;
addressing()[index] = id;
}
inline Foam::label Foam::ensightCells::index() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const char* Foam::ensightCells::key(const elemType etype)
{
return index_;
}
inline Foam::label& Foam::ensightCells::index()
{
return index_;
}
inline Foam::label Foam::ensightCells::size() const
{
return address_.size();
return elemNames[etype];
}
@ -59,42 +50,46 @@ inline const Foam::FixedList<Foam::label,5>& Foam::ensightCells::totals() const
}
inline Foam::label Foam::ensightCells::total(const enum elemType what) const
inline Foam::label Foam::ensightCells::total(const elemType etype) const
{
return sizes_[what];
return sizes_[etype];
}
inline Foam::label Foam::ensightCells::size(const enum elemType what) const
inline Foam::label Foam::ensightCells::size(const elemType etype) const
{
return slices_[what].size();
return (offsets_[etype+1] - offsets_[etype]);
}
inline Foam::label Foam::ensightCells::offset(const enum elemType what) const
inline Foam::labelRange Foam::ensightCells::range(const elemType etype) const
{
return slices_[what].start();
return labelRange(offsets_[etype], offsets_[etype+1] - offsets_[etype]);
}
inline const Foam::labelUList Foam::ensightCells::cellIds
(
const enum elemType what
) const
inline const Foam::labelList& Foam::ensightCells::cellIds() const
{
return address_[slices_[what]];
return addressing();
}
inline const Foam::labelUList& Foam::ensightCells::cellIds() const
inline const Foam::labelUList
Foam::ensightCells::cellIds(const elemType etype) const
{
return address_;
return addressing()[range(etype)];
}
inline Foam::label Foam::ensightCells::operator[](const label i) const
inline void Foam::ensightCells::incrCellIds(const label off)
{
return address_[i];
incrAddressing(off);
}
inline void Foam::ensightCells::decrCellIds(const label off)
{
decrAddressing(off);
}

View File

@ -0,0 +1,322 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightCells.H"
#include "ensightOutput.H"
#include "polyMesh.H"
#include "globalIndex.H"
#include "globalMeshData.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightCells::writePolysConnectivity
(
ensightGeoFile& os,
const polyMesh& mesh,
const ensightCells& part,
const labelList& pointToGlobal,
const bool parallel
)
{
constexpr ensightCells::elemType etype(ensightCells::NFACED);
// Slaves
const label nSlaves = (parallel ? Pstream::nProcs() : 0);
const label nTotal = part.total(etype);
const labelUList& addr = part.cellIds(etype);
if (!nTotal)
{
return;
}
if (Pstream::master())
{
os.writeKeyword(ensightCells::key(etype));
os.write(nTotal);
os.newline();
}
// Number of faces per polyhedral (1/line in ASCII)
{
labelList send
(
ensightOutput::Detail::getPolysNFaces(mesh, addr)
);
if (Pstream::master())
{
// Master
os.writeLabels(send);
// Slaves
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList recv(fromSlave);
os.writeLabels(recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << send;
}
}
// Number of points for each polyhedral face (1/line in ASCII)
{
labelList send
(
ensightOutput::Detail::getPolysNPointsPerFace(mesh, addr)
);
if (Pstream::master())
{
// Master
os.writeLabels(send);
// Slaves
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
labelList recv(fromSlave);
os.writeLabels(recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << send;
}
}
// List of points id for each face of the above list
if (Pstream::master())
{
// Master
ensightOutput::writePolysPoints
(
os,
mesh,
addr,
pointToGlobal
);
// Slaves
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
cellList cells(fromSlave);
labelList addr(fromSlave);
faceList faces(fromSlave);
labelList owner(fromSlave);
ensightOutput::writePolysPoints
(
os,
cells,
addr,
faces,
owner
);
}
}
else if (nSlaves)
{
// Renumber faces to use global point numbers
faceList faces(mesh.faces());
ListListOps::inplaceRenumber(pointToGlobal, faces);
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster
<< mesh.cells()
<< addr
<< faces
<< mesh.faceOwner();
}
}
void Foam::ensightCells::writeShapeConnectivity
(
ensightGeoFile& os,
const polyMesh& mesh,
const ensightCells::elemType etype,
const ensightCells& part,
const labelList& pointToGlobal,
const bool parallel
)
{
if (etype == ensightCells::NFACED)
{
FatalErrorInFunction
<< "Called for ensight NFACED cell. Programming error\n"
<< exit(FatalError);
}
// Slaves
const label nSlaves = (parallel ? Pstream::nProcs() : 0);
const label nTotal = part.total(etype);
const labelUList& addr = part.cellIds(etype);
if (!nTotal)
{
return;
}
if (Pstream::master())
{
os.writeKeyword(ensightCells::key(etype));
os.write(nTotal);
os.newline();
}
// Primitive shape - get subset and renumber
cellShapeList shapes(mesh.cellShapes(), addr);
ListListOps::inplaceRenumber(pointToGlobal, shapes);
if (Pstream::master())
{
ensightOutput::writeCellShapes(os, shapes);
for (int slave=1; slave < nSlaves; ++slave)
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
cellShapeList recv(fromSlave);
ensightOutput::writeCellShapes(os, recv);
}
}
else if (nSlaves)
{
OPstream toMaster
(
Pstream::commsTypes::scheduled,
Pstream::masterNo()
);
toMaster << shapes;
}
}
void Foam::ensightCells::write
(
ensightGeoFile& os,
const polyMesh& mesh,
bool parallel
) const
{
const ensightCells& part = *this;
parallel = parallel && Pstream::parRun();
// Renumber the points/faces into unique points
label nPoints = 0; // Total number of points
labelList pointToGlobal; // local point to unique global index
labelList uniqueMeshPointLabels; // unique global points
nPoints = meshPointMapppings
(
mesh,
pointToGlobal,
uniqueMeshPointLabels,
parallel
);
ensightOutput::Detail::writeCoordinates
(
os,
part.index(),
part.name(),
nPoints, // nPoints (global)
UIndirectList<point>(mesh.points(), uniqueMeshPointLabels),
parallel //!< Collective write?
);
for (label typei=0; typei < ensightCells::nTypes; ++typei)
{
const auto etype = ensightCells::elemType(typei);
if (etype == ensightCells::NFACED)
{
writePolysConnectivity
(
os,
mesh,
part,
pointToGlobal,
parallel
);
}
else
{
writeShapeConnectivity
(
os,
mesh,
etype,
part,
pointToGlobal,
parallel
);
}
}
}
// ************************************************************************* //

View File

@ -1,215 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 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/>.
Class
Foam::ensightCells
Description
Sorting/classification of cells (3D) into corresponding ensight element
types.
\*---------------------------------------------------------------------------*/
#ifndef ensightCells_H
#define ensightCells_H
#include "labelList.H"
#include "FixedList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class bitSet;
class polyMesh;
/*---------------------------------------------------------------------------*\
Class ensightCells Declaration
\*---------------------------------------------------------------------------*/
class ensightCells
{
public:
// Public data
//- Addressable ensight element types
enum elemType
{
TETRA4, //!< "tetra4"
PYRAMID5, //!< "pyramid5"
PENTA6, //!< "penta6"
HEXA8, //!< "hexa8"
NFACED //!< "nfaced"
};
//- Number of element types (5)
static constexpr int nTypes = 5;
//- The ensight element type names
static const char* elemNames[5];
// Static Member Functions
//- Return the ensight element name for the specified type
inline static const char* key(const enum elemType);
private:
// Private Data
//- Location within a list.
// The ensight part number is typically this value +1.
label index_;
//- Linear list of ids, sub-sectioned per element type by sub-lists
labelList address_;
//- Slices (sub-lists) of the address ids for each element type.
FixedList<labelRange, 5> slices_;
//- List of global sizes for each element type.
// Used temporarily for local sizes when building the element lists.
FixedList<label, 5> sizes_;
// Private Member Functions
//- Use temporarily stored sizes to redimension the element lists
void resizeAll();
//- Classify cell types, set element lists for selection (implemention)
template<class Addressing>
void classifyImpl(const polyMesh& mesh, const Addressing& cellIds);
//- No copy assignment
void operator=(const ensightCells&) = delete;
public:
// Constructors
//- Construct null, with part index 0
ensightCells();
//- Construct null, with specified part index
explicit ensightCells(const label partIndex);
//- Copy constructor. Needed for lists etc.
ensightCells(const ensightCells& obj);
//- Destructor
~ensightCells() = default;
// Member Functions
// Access
//- The index in a list.
inline label index() const;
//- The index in a list, non-const access.
inline label& index();
//- The processor local size of all elements.
inline label size() const;
//- The processor local size of the specified element type.
inline label size(const enum elemType) const;
//- The global number of the specified element type.
// This value is only meaningful after a reduce operation.
inline label total(const enum elemType) const;
//- The global number of all element types.
// This value is only meaningful after a reduce operation.
label total() const;
//- The global numbers per element type.
// This value is only meaningful after a reduce operation.
inline const FixedList<label, 5>& totals() const;
//- The processor local sizes per element type.
FixedList<label, 5> sizes() const;
//- Processor local starting offset of element type.
inline label offset(const enum elemType what) const;
//- Return the (local) cell ids of the specified element type
inline const labelUList cellIds(const enum elemType) const;
//- Return the cell ids of all elements
inline const labelUList& cellIds() const;
// Edit
//- Classify cell types and set the element lists.
void classify(const polyMesh& mesh);
//- Classify cell types and set element lists,
//- using a subgroup of cells (eg, from a cellZone etc).
void classify(const polyMesh& mesh, const labelUList& cellIds);
//- Classify cell types and set element lists,
//- using a subgroup of cells
void classify(const polyMesh& mesh, const bitSet& selection);
//- Set addressable sizes to zero, free up addressing memory.
void clear();
//- Sum element counts across all processes.
void reduce();
//- Sort element lists numerically.
void sort();
// Member Operators
//- Return id from linear list of addressing.
inline label operator[](const label i) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightCellsI.H"
#endif
// ************************************************************************* //

View File

@ -1,222 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2018 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/>.
Class
Foam::ensightFaces
Description
Sorting/classification of faces (2D) into corresponding ensight types
\*---------------------------------------------------------------------------*/
#ifndef ensightFaces_H
#define ensightFaces_H
#include "boolList.H"
#include "labelList.H"
#include "faceList.H"
#include "FixedList.H"
#include "bitSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightFaces Declaration
\*---------------------------------------------------------------------------*/
class ensightFaces
{
public:
// Public Data
//- Addressable ensight element types
enum elemType
{
TRIA3, //!< "tria3"
QUAD4, //!< "quad4"
NSIDED //!< "nsided"
};
//- Number of element types (3)
static constexpr int nTypes = 3;
//- The ensight element type names
static const char* elemNames[3];
// Static Member Functions
//- Return the ensight element name for the specified type
static inline const char* key(const enum elemType);
private:
// Private data
//- Location within a list.
// The ensight part number is typically this value +1.
label index_;
//- Linear list of ids, sub-sectioned per element type by sub-lists
labelList address_;
//- Linear list of face-flips
boolList flipMap_;
//- Slices (sub-lists) of the address and flips for each element type.
FixedList<labelRange, 3> slices_;
//- List of global sizes for each element type.
// Used temporarily for local sizes when building the element lists.
FixedList<label, 3> sizes_;
// Private Member Functions
//- Low-level internal addition routine
inline void add(const face& f, const label id, const bool flip = false);
//- Use temporarily stored sizes to redimension the element lists
void resizeAll();
//- No copy assignment
void operator=(const ensightFaces&) = delete;
public:
// Constructors
//- Construct null, with part index 0
ensightFaces();
//- Construct null, with specified part index
explicit ensightFaces(const label partIndex);
//- Copy constructor. Needed for lists etc.
ensightFaces(const ensightFaces& obj);
//- Destructor
~ensightFaces() = default;
// Member Functions
// Access
//- The index in a list.
inline label index() const;
//- The index in a list, non-const access.
inline label& index();
//- The processor local size of all elements.
inline label size() const;
//- The processor local size of the specified element type.
inline label size(const enum elemType) const;
//- The global number of all element types.
// This value is only meaningful after a reduce operation.
label total() const;
//- The global number of the specified element type.
// This value is only meaningful after a reduce operation.
inline label total(const enum elemType) const;
//- The global numbers per element type.
// This value is only meaningful after a reduce operation.
inline const FixedList<label, 3>& totals() const;
//- The processor local sizes per element type.
FixedList<label, 3> sizes() const;
//- Processor local starting offset of element type.
inline label offset(const enum elemType what) const;
//- Return the (local) face ids of the specified element type
inline const labelUList faceIds(const enum elemType) const;
//- Return the processor local face ids of all elements
inline const labelUList& faceIds() const;
//- Return the processor local flip-map of all elements
inline const boolList& flipMap() const;
// Edit
//- Classify the face types, set element list.
void classify(const faceList& faces);
//- Classify the face types, set element list.
// The indirect addressing can be used when classifying groups of
// face (eg, from a faceZone etc) with an optional flipMap.
// The optional exclude marker can be used to skip faces on particular
// boundary types or regions.
void classify
(
const faceList& faces,
const labelUList& addressing,
const boolList& flipMap = boolList(),
const bitSet& exclude = bitSet()
);
//- Set addressable sizes to zero, free up addressing memory.
void clear();
//- Sum element counts across all processes.
void reduce();
//- Sort element lists numerically.
void sort();
// Member Operators
//- Return element from linear-list.
inline label operator[](const label i) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightFacesI.H"
#endif
// ************************************************************************* //

View File

@ -1,183 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
Class
Foam::ensightPart
Description
Base class for ensightPartCells and ensightPartFaces
SourceFiles
ensightPart.C
\*---------------------------------------------------------------------------*/
#ifndef ensightPart_H
#define ensightPart_H
#include "ensightGeoFile.H"
#include "typeInfo.H"
#include "labelList.H"
#include "polyMesh.H"
#include "Field.H"
#include "IOstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPart Declaration
\*---------------------------------------------------------------------------*/
class ensightPart
{
// Private Data
//- Part name (or description)
string name_;
// Private Member Functions
//- No copy construct
ensightPart(const ensightPart&) = delete;
//- No copy assignment
void operator=(const ensightPart&) = delete;
protected:
// Protected Classes
//- Track the points used by the part and map global to local indices
struct localPoints
{
//- Number of points used
label nPoints;
//- Map global to local indices
labelList list;
//- Null constructor
localPoints()
:
nPoints(0),
list()
{}
//- Construct for mesh points
localPoints(const pointField& pts)
:
nPoints(0),
list(pts.size(), -1)
{}
};
public:
//- Runtime type information
TypeName("ensightPart");
// Constructors
//- Construct with description
explicit ensightPart(const string& description);
//- Destructor
virtual ~ensightPart() = default;
// Access
//- Part index (0-based)
virtual label index() const = 0;
//- Number of elements in this part
virtual label size() const
{
return 0;
}
//- Return the part name or description
const string& name() const
{
return name_;
}
//- Change the part name or description
void rename(string value)
{
name_ = std::move(value);
}
// Output
//- Write summary information about the object
virtual void writeSummary(Ostream& os) const = 0;
//- Print various types of debugging information
virtual void dumpInfo(Ostream& os) const = 0;
//- Write geometry
virtual void write(ensightGeoFile& os) const = 0;
//- Helper: write geometry with given pointField
virtual void write(ensightGeoFile& os, const pointField&) const = 0;
// Housekeeping
//- Deprecated(2019-12) - use rename() method
// \deprecated(2019-12) - use rename() method
void FOAM_DEPRECATED_FOR(2019-12, "rename() method")
name(string value)
{
name_ = std::move(value);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- IOstream Operator to write geometry
ensightGeoFile& operator<<(ensightGeoFile& os, const ensightPart& part);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,344 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightPartCells.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightPartCells, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::ensightPart::localPoints Foam::ensightPartCells::calcLocalPoints() const
{
localPoints ptList(mesh_.points());
labelList& usedPoints = ptList.list;
label nPoints = 0;
// Add all points from cells
const labelUList& idList = this->cellIds();
for (const label id : idList)
{
const labelUList& cFaces = mesh_.cells()[id];
forAll(cFaces, cFacei)
{
const face& f = mesh_.faces()[cFaces[cFacei]];
forAll(f, fp)
{
if (usedPoints[f[fp]] == -1)
{
usedPoints[f[fp]] = nPoints++;
}
}
}
}
// this is not absolutely necessary, but renumber anyhow
nPoints = 0;
forAll(usedPoints, ptI)
{
if (usedPoints[ptI] > -1)
{
usedPoints[ptI] = nPoints++;
}
}
ptList.nPoints = nPoints;
return ptList;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const string& partName
)
:
ensightCells(partIndex),
ensightPart(partName),
mesh_(mesh)
{
classify(mesh);
}
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const labelUList& cellIds,
const string& partName
)
:
ensightCells(partIndex),
ensightPart(partName),
mesh_(mesh)
{
classify(mesh, cellIds);
}
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const bitSet& selection,
const string& partName
)
:
ensightCells(partIndex),
ensightPart(partName),
mesh_(mesh)
{
classify(mesh, selection);
}
Foam::ensightPartCells::ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const cellZone& zn,
const string& partName
)
:
ensightPartCells
(
partIndex,
mesh,
static_cast<const labelList&>(zn),
zn.name()
)
{
if (!partName.empty())
{
rename(partName);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightPartCells::writeConnectivity
(
ensightGeoFile& os,
const word& key,
const labelUList& idList,
const labelUList& pointMap
) const
{
if (idList.empty()) return;
os.writeKeyword(key);
os.write(idList.size());
os.newline();
// write polyhedral
if (key == "nfaced")
{
const faceList& meshFaces = mesh_.faces();
const labelUList& owner = mesh_.faceOwner();
// write the number of faces per element
forAll(idList, i)
{
const label id = idList[i];
const labelUList& cFace = mesh_.cells()[id];
os.write(cFace.size());
os.newline();
}
// write the number of points per element face
forAll(idList, i)
{
const label id = idList[i];
const labelUList& cFace = mesh_.cells()[id];
forAll(cFace, facei)
{
const face& cf = meshFaces[cFace[facei]];
os.write(cf.size());
os.newline();
}
}
// write the points describing each element face
forAll(idList, i)
{
const label id = idList[i];
const labelUList& cFace = mesh_.cells()[id];
forAll(cFace, cFacei)
{
const label faceId = cFace[cFacei];
const face& cf = meshFaces[faceId];
// convert global -> local index
// (note: Ensight indices start with 1)
// ensight >= 9 needs consistently oriented nfaced cells
if (id == owner[faceId])
{
forAll(cf, ptI)
{
os.write(pointMap[cf[ptI]] + 1);
}
}
else
{
// as per face::reverseFace(), but without copying
os.write(pointMap[cf[0]] + 1);
for (label ptI = cf.size()-1; ptI > 0; --ptI)
{
os.write(pointMap[cf[ptI]] + 1);
}
}
os.newline();
}
}
}
else
{
// write primitive
const cellShapeList& shapes = mesh_.cellShapes();
forAll(idList, i)
{
const label id = idList[i];
const cellShape& cellPoints = shapes[id];
// convert global -> local index
// (note: Ensight indices start with 1)
forAll(cellPoints, ptI)
{
os.write(pointMap[cellPoints[ptI]] + 1);
}
os.newline();
}
}
}
void Foam::ensightPartCells::write
(
ensightGeoFile& os,
const pointField& points
) const
{
if (size())
{
const localPoints ptList = calcLocalPoints();
const labelUList& pointMap = ptList.list;
os.beginPart(index(), name());
os.beginCoordinates(ptList.nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
forAll(pointMap, ptI)
{
if (pointMap[ptI] > -1)
{
os.write(points[ptI].component(cmpt));
os.newline();
}
}
}
// Write each element type
for (int typei=0; typei < ensightCells::nTypes; ++typei)
{
const ensightCells::elemType what = ensightCells::elemType(typei);
writeConnectivity
(
os,
ensightCells::key(what),
cellIds(what),
pointMap
);
}
}
}
void Foam::ensightPartCells::write(ensightGeoFile& os) const
{
this->write(os, mesh_.points());
}
void Foam::ensightPartCells::writeSummary(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("size", size());
os.endBlock();
}
void Foam::ensightPartCells::dumpInfo(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("size", size());
for (int typei=0; typei < ensightCells::nTypes; ++typei)
{
const ensightCells::elemType what = ensightCells::elemType(typei);
const labelUList& addr = this->cellIds(what);
os.writeKeyword(ensightCells::key(what));
addr.writeList(os, 0) << endEntry; // Flat output
}
os.endBlock();
}
// ************************************************************************* //

View File

@ -1,180 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
Class
Foam::ensightPartCells
Description
An implementation of ensightPart to hold volume mesh cells.
SourceFiles
ensightPartCells.C
\*---------------------------------------------------------------------------*/
#ifndef ensightPartCells_H
#define ensightPartCells_H
#include "ensightPart.H"
#include "ensightCells.H"
#include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPartCells Declaration
\*---------------------------------------------------------------------------*/
class ensightPartCells
:
public ensightCells,
public ensightPart
{
// Private Data
//- The referenced mesh
const polyMesh& mesh_;
// Private Member Functions
//- Track points used
localPoints calcLocalPoints() const;
//- Element connectivity
void writeConnectivity
(
ensightGeoFile&,
const word& key,
const labelUList& idList,
const labelUList& pointMap
) const;
//- No copy construct
ensightPartCells(const ensightPartCells&) = delete;
//- No copy assignment
void operator=(const ensightPartCells&) = delete;
public:
//- Runtime type information
TypeName("ensightCells");
// Constructors
//- Construct from entire polyMesh without zones.
//- Part receives the specified name (default: "cells").
ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const string& partName = "cells"
);
//- Construct a part from polyMesh and list of cells.
//- Part receives the specified name (default: "cells").
ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const labelUList& cellIds,
const string& partName = "cells"
);
//- Construct a part from polyMesh and selection of cells.
//- Part receives the specified name (default: "cells").
ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const bitSet& selection,
const string& partName = "cells"
);
//- Construct from polyMesh and cellZone.
//- Part receives the name of the zone unless otherwise specified.
ensightPartCells
(
label partIndex,
const polyMesh& mesh,
const cellZone& zn,
const string& partName = ""
);
//- Destructor
virtual ~ensightPartCells() = default;
// Member Functions
// Access
//- Part index (0-based)
virtual label index() const
{
return ensightCells::index();
}
//- Number of elements in this part
virtual label size() const
{
return ensightCells::size();
}
// Output
//- Write summary information about the object
virtual void writeSummary(Ostream& os) const;
//- Print various types of debugging information
virtual void dumpInfo(Ostream& os) const;
//- Write geometry
virtual void write(ensightGeoFile& os) const;
//- Helper: write geometry with given pointField
virtual void write(ensightGeoFile& os, const pointField& points) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,302 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightPartFaces.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightPartFaces, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::ensightPart::localPoints Foam::ensightPartFaces::calcLocalPoints() const
{
if (contiguousPoints_)
{
localPoints ptList;
ptList.list = identity(points_.size());
ptList.nPoints = points_.size();
return ptList;
}
localPoints ptList(points_);
labelList& usedPoints = ptList.list;
label nPoints = 0;
// Add all points from faces
const labelUList& idList = this->faceIds();
// Add all points from faces
forAll(idList, i)
{
const label id = idList[i] + start_;
const face& f = faces_[id];
forAll(f, fp)
{
if (usedPoints[f[fp]] == -1)
{
usedPoints[f[fp]] = nPoints++;
}
}
}
// This is not absolutely necessary, but renumber anyhow
nPoints = 0;
forAll(usedPoints, ptI)
{
if (usedPoints[ptI] > -1)
{
usedPoints[ptI] = nPoints++;
}
}
ptList.nPoints = nPoints;
return ptList;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPartFaces::ensightPartFaces
(
label partIndex,
const string& description,
const pointField& points,
const faceList& faces,
const bool contiguousPoints
)
:
ensightFaces(partIndex),
ensightPart(description),
start_(0),
patchIndex_(-1),
faces_(faces),
points_(points),
contiguousPoints_(contiguousPoints)
{
// Classify the face shapes
classify(faces);
}
Foam::ensightPartFaces::ensightPartFaces
(
label partIndex,
const polyMesh& mesh,
const polyPatch& patch,
const string& partName
)
:
ensightFaces(partIndex),
ensightPart(patch.name()),
start_(patch.start()),
patchIndex_(patch.index()),
faces_(mesh.faces()),
points_(mesh.points()),
contiguousPoints_(false)
{
if (!partName.empty())
{
rename(partName);
}
// Classify the face shapes
classify(patch);
}
Foam::ensightPartFaces::ensightPartFaces
(
label partIndex,
const polyPatch& patch,
const string& partName
)
:
ensightPartFaces(partIndex, patch.boundaryMesh().mesh(), patch, partName)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightPartFaces::writeConnectivity
(
ensightGeoFile& os,
const word& key,
const faceList& faces,
const labelUList& idList,
const labelUList& pointMap
) const
{
if (idList.empty()) return;
os.writeKeyword(key);
os.write(idList.size());
os.newline();
// Write (polygon) face sizes
if (key == "nsided")
{
// Write the number of points per face
forAll(idList, i)
{
const label id = idList[i] + start_;
const face& f = faces[id];
os.write(f.size());
os.newline();
}
}
// Write the points describing the face
forAll(idList, i)
{
const label id = idList[i] + start_;
const face& f = faces[id];
// Convert global -> local index
// (note: Ensight indices start with 1)
forAll(f, fp)
{
os.write(pointMap[f[fp]] + 1);
}
os.newline();
}
}
void Foam::ensightPartFaces::writeConnectivity
(
ensightGeoFile& os,
const word& key,
const labelUList& idList,
const labelUList& pointMap
) const
{
writeConnectivity
(
os,
key,
faces_,
idList,
pointMap
);
}
void Foam::ensightPartFaces::write
(
ensightGeoFile& os,
const pointField& points
) const
{
if (size())
{
const localPoints ptList = calcLocalPoints();
const labelUList& pointMap = ptList.list;
os.beginPart(index(), name());
os.beginCoordinates(ptList.nPoints);
for (direction cmpt=0; cmpt < point::nComponents; ++cmpt)
{
forAll(pointMap, ptI)
{
if (pointMap[ptI] > -1)
{
os.write(points[ptI].component(cmpt));
os.newline();
}
}
}
// Write part
for (int typei=0; typei < ensightFaces::nTypes; ++typei)
{
const ensightFaces::elemType what = ensightFaces::elemType(typei);
writeConnectivity
(
os,
ensightFaces::key(what),
faceIds(what),
pointMap
);
}
}
}
void Foam::ensightPartFaces::write(ensightGeoFile& os) const
{
this->write(os, points_);
}
void Foam::ensightPartFaces::writeSummary(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("start", start_);
os.writeEntry("size", size());
os.endBlock();
}
void Foam::ensightPartFaces::dumpInfo(Ostream& os) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("start", start_);
os.writeEntry("size", size());
for (int typei=0; typei < ensightFaces::nTypes; ++typei)
{
const ensightFaces::elemType what = ensightFaces::elemType(typei);
const labelUList& addr = this->faceIds(what);
os.writeKeyword(ensightFaces::key(what));
addr.writeList(os, 0) << endEntry; // Flat output
}
os.endBlock();
}
// ************************************************************************* //

View File

@ -1,202 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
Class
Foam::ensightPartFaces
Description
An implementation of ensightPart to hold mesh faces.
SourceFiles
ensightPartFaces.C
\*---------------------------------------------------------------------------*/
#ifndef ensightPartFaces_H
#define ensightPartFaces_H
#include "ensightPart.H"
#include "ensightFaces.H"
#include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPartFaces Declaration
\*---------------------------------------------------------------------------*/
class ensightPartFaces
:
public ensightFaces,
public ensightPart
{
// Private data
//- Start offset for patch
const label start_;
//- Patch index
const label patchIndex_;
//- The referenced faces
const faceList& faces_;
//- The referenced pointField
const pointField& points_;
//- Can skip local point renumbering when points are contiguous
const bool contiguousPoints_;
// Private Member Functions
//- Track points used
localPoints calcLocalPoints() const;
//- Element connectivity
void writeConnectivity
(
ensightGeoFile&,
const word& key,
const labelUList& idList,
const labelUList& pointMap
) const;
//- Helper: write connectivity
void writeConnectivity
(
ensightGeoFile&,
const word& key,
const faceList&,
const labelUList& idList,
const labelUList& pointMap
) const;
//- No copy construct
ensightPartFaces(const ensightPartFaces&) = delete;
//- No copy assignment
void operator=(const ensightPartFaces&) = delete;
public:
//- Runtime type information
TypeName("ensightFaces");
// Constructors
//- Construct part with 0-based index, description, points and faces
// Can skip local point renumbering when points are contiguous
ensightPartFaces
(
label partIndex,
const string& description,
const pointField& points,
const faceList& faces,
const bool contiguousPoints = false
);
//- Construct from polyMesh and polyPatch
//- Part receives the name of the patch unless otherwise specified.
ensightPartFaces
(
label partIndex,
const polyMesh& mesh,
const polyPatch& patch,
const string& partName = ""
);
//- Construct from polyPatch
//- Part receives the name of the patch unless otherwise specified.
ensightPartFaces
(
label partIndex,
const polyPatch& patch,
const string& partName = ""
);
//- Destructor
virtual ~ensightPartFaces() = default;
// Member Functions
// Access
//- Part index (0-based)
virtual label index() const
{
return ensightFaces::index();
}
//- Number of elements in this part
virtual label size() const
{
return ensightFaces::size();
}
//- Return the patch index, -1 when not in use.
inline label patchIndex() const
{
return patchIndex_;
}
// Output
//- Write summary information about the object
virtual void writeSummary(Ostream& os) const;
//- Print various types of debugging information
virtual void dumpInfo(Ostream& os) const;
//- Write geometry
virtual void write(ensightGeoFile& os) const;
//- Helper: write geometry given the pointField
virtual void write(ensightGeoFile& os, const pointField& points) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,134 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightParts.H"
#include "bitSet.H"
#include "emptyPolyPatch.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightParts::ensightParts(const polyMesh& mesh)
:
StorageType()
{
recalculate(mesh);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightParts::recalculate(const polyMesh& mesh)
{
StorageType::clear();
label nPart = 0;
// Track which cells are in a zone or not
bitSet selection(mesh.nCells());
// Do all cell zones
for (const cellZone& zn : mesh.cellZones())
{
if (returnReduce(!zn.empty(), orOp<bool>()))
{
selection.set(zn);
this->append(new ensightPartCells(nPart++, mesh, zn));
}
}
if (!nPart)
{
// No zones at all? - do entire mesh. Name as per ensightMesh
this->append(new ensightPartCells(nPart++, mesh, "internalMesh"));
}
else
{
// Flip from zoned to unzoned
selection.flip();
if (returnReduce(selection.any(), orOp<bool>()))
{
this->append
(
new ensightPartCells(nPart++, mesh, selection, "__internal__")
);
}
}
// Do boundaries, skipping empty and processor patches
for (const polyPatch& p : mesh.boundaryMesh())
{
if (isA<processorPolyPatch>(p))
{
// No processor patches
break;
}
if (returnReduce(!p.empty(), orOp<bool>()))
{
this->append(new ensightPartFaces(nPart++, mesh, p));
}
}
}
void Foam::ensightParts::write(ensightGeoFile& os) const
{
// Some feedback
Info<< "Write geometry part (" << flush;
for (const ensightPart& part : *this)
{
Info<< ' ' << part.index() << flush;
part.write(os);
}
Info<< " )" << endl;
}
void Foam::ensightParts::writeSummary(Ostream& os) const
{
for (const ensightPart& part : *this)
{
part.writeSummary(os);
}
}
void Foam::ensightParts::dumpInfo(Ostream& os) const
{
for (const ensightPart& part : *this)
{
part.dumpInfo(os);
}
}
// ************************************************************************* //

View File

@ -1,120 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2019 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/>.
Class
Foam::ensightParts
Description
A collection of several ensightPart elements
SourceFiles
ensightParts.C
\*---------------------------------------------------------------------------*/
#ifndef ensightParts_H
#define ensightParts_H
#include "SLPtrList.H"
#include "ensightPart.H"
#include "ensightPartFaces.H"
#include "ensightPartCells.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightParts Declaration
\*---------------------------------------------------------------------------*/
class ensightParts
:
public SLPtrList<ensightPart>
{
// Private Member Functions
//- No copy construct
ensightParts(const ensightParts&) = delete;
//- No copy assignment
void operator=(const ensightParts&) = delete;
public:
//- Storage type used
typedef SLPtrList<ensightPart> StorageType;
// Constructors
//- Construct from polyMesh
explicit ensightParts(const polyMesh& mesh);
//- Destructor
~ensightParts() = default;
// Member Functions
//- Number of parts
using StorageType::size;
//- Clear old information and construct anew from polyMesh
void recalculate(const polyMesh& mesh);
// Output
//- Write summary information about the objects
void writeSummary(Ostream& os) const;
//- Print various types of debugging information
void dumpInfo(Ostream& os) const;
//- Write the geometry to file
void write(autoPtr<ensightGeoFile>& os) const
{
write(os.ref());
}
//- Write the geometry to file
void write(ensightGeoFile& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,16 +31,27 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(ensightFaces, 0);
}
const char* Foam::ensightFaces::elemNames[3] =
{ "tria3", "quad4", "nsided" };
static_assert
(
Foam::ensightFaces::nTypes == 3,
"Support exactly 3 face types (tria3, quad4, nsided)"
);
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace
{
// Simple shape classifier
// Trivial shape classifier
static inline Foam::ensightFaces::elemType whatType(const Foam::face& f)
{
return
@ -58,48 +69,26 @@ static inline Foam::ensightFaces::elemType whatType(const Foam::face& f)
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Only used in this file-scope
inline void Foam::ensightFaces::add
(
const face& f,
const label id,
const bool flip
)
{
const enum elemType what = whatType(f);
// linear addressing:
const label index = offset(what) + sizes_[what]++;
address_[index] = id;
if (flipMap_.size())
{
flipMap_[index] = flip;
}
}
void Foam::ensightFaces::resizeAll()
{
// overall required size
label n = 0;
forAll(sizes_, typei)
{
n += sizes_[typei];
}
address_.setSize(n, Zero);
// Assign sub-list offsets, determine overall size
// assign corresponding sub-lists
n = 0;
forAll(sizes_, typei)
{
slices_[typei].setStart(n);
slices_[typei].setSize(sizes_[typei]);
label len = 0;
n += sizes_[typei];
auto iter = offsets_.begin();
*iter = 0;
for (const label n : sizes_)
{
len += n;
*(++iter) = len;
}
// normally assume no flipMap
// The addressing space
addressing().resize(len, Zero);
// Normally assume no flipMap
flipMap_.clear();
}
@ -108,40 +97,18 @@ void Foam::ensightFaces::resizeAll()
Foam::ensightFaces::ensightFaces()
:
ensightFaces(0)
ensightPart(),
flipMap_(),
offsets_(Zero),
sizes_(Zero)
{}
Foam::ensightFaces::ensightFaces(const label partIndex)
Foam::ensightFaces::ensightFaces(const string& description)
:
index_(partIndex),
address_(),
flipMap_(),
slices_(),
sizes_(Zero)
ensightFaces()
{
resizeAll(); // adjust allocation/sizing
}
Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
:
index_(obj.index_),
address_(obj.address_),
flipMap_(obj.flipMap_),
slices_(),
sizes_()
{
// Save the total (reduced) sizes
FixedList<label, 3> totSizes = obj.sizes_;
// Need local sizes for the resize operation
this->sizes_ = obj.sizes();
resizeAll(); // adjust allocation/sizing
// Restore total (reduced) sizes
this->sizes_ = totSizes;
rename(description);
}
@ -150,9 +117,10 @@ Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
{
FixedList<label, 3> count;
forAll(slices_, typei)
forAll(count, typei)
{
count[typei] = slices_[typei].size();
count[typei] = size(elemType(typei));
}
return count;
@ -172,17 +140,26 @@ Foam::label Foam::ensightFaces::total() const
void Foam::ensightFaces::clear()
{
sizes_ = Zero; // reset sizes
resizeAll();
clearOut();
ensightPart::clear();
flipMap_.clear();
sizes_ = Zero;
offsets_ = Zero;
}
void Foam::ensightFaces::clearOut()
{}
void Foam::ensightFaces::reduce()
{
// No listCombineGather, listCombineScatter for FixedList
forAll(sizes_, typei)
{
sizes_[typei] = slices_[typei].size();
sizes_[typei] = size(elemType(typei));
Foam::reduce(sizes_[typei], sumOp<label>());
}
}
@ -190,89 +167,116 @@ void Foam::ensightFaces::reduce()
void Foam::ensightFaces::sort()
{
if (flipMap_.size() == address_.size())
const bool useFlip = (size() == flipMap_.size());
if (useFlip)
{
// Must sort flip map as well
labelList order;
forAll(slices_, typei)
for (int typei=0; typei < nTypes; ++typei)
{
if (slices_[typei].size())
const labelRange sub(range(elemType(typei)));
if (!sub.empty())
{
SubList<label> idLst(address_, slices_[typei]);
SubList<bool> flip(flipMap_, slices_[typei]);
SubList<label> ids(addressing(), sub);
SubList<bool> flips(flipMap_, sub);
Foam::sortedOrder(idLst, order);
Foam::sortedOrder(ids, order);
idLst = reorder<labelList>(order, idLst);
flip = reorder<boolList>(order, flip);
ids = reorder<labelList>(order, ids);
flips = reorder<boolList>(order, flips);
}
}
}
else
{
// no flip-maps, simpler to sort
forAll(slices_, typei)
{
if (slices_[typei].size())
{
SubList<label> idLst(address_, slices_[typei]);
Foam::sort(idLst);
}
}
flipMap_.clear(); // Extra safety
flipMap_.clear(); // for extra safety
// No flip-maps, simply sort addresses
for (int typei=0; typei < nTypes; ++typei)
{
const labelRange sub(range(elemType(typei)));
if (!sub.empty())
{
SubList<label> ids(addressing(), sub);
Foam::sort(ids);
}
}
}
}
void Foam::ensightFaces::classify(const faceList& faces)
void Foam::ensightFaces::classify(const UList<face>& faces)
{
const label sz = faces.size();
const label len = faces.size();
// Pass 1: Count the shapes
sizes_ = Zero; // reset sizes
for (label listi = 0; listi < sz; ++listi)
for (label listi = 0; listi < len; ++listi)
{
const enum elemType what = whatType(faces[listi]);
sizes_[what]++;
const auto etype = whatType(faces[listi]);
++sizes_[etype];
}
resizeAll(); // adjust allocation
sizes_ = Zero; // reset sizes - use for local indexing here
// Pass 2: Assign face-id per shape type
for (label listi = 0; listi < sz; ++listi)
for (label listi = 0; listi < len; ++listi)
{
add(faces[listi], listi);
const auto etype = whatType(faces[listi]);
add(etype, listi);
}
}
void Foam::ensightFaces::classify
(
const faceList& faces,
const labelUList& addressing,
const UList<face>& faces,
const labelRange& range
)
{
const labelRange slice(range.subset0(faces.size()));
// Operate on a local slice
classify(SubList<face>(slice, faces));
// Fixup to use the real faceIds instead of the 0-based slice
incrAddressing(slice.start());
}
void Foam::ensightFaces::classify
(
const UList<face>& faces,
const labelUList& addr,
const boolList& flipMap,
const bitSet& exclude
)
{
const label sz = addressing.size();
const bool useFlip = (addressing.size() == flipMap.size());
const label len = addr.size();
const bool useFlip = (len == flipMap.size());
// Pass 1: Count the shapes
sizes_ = Zero; // reset sizes
for (label listi = 0; listi < sz; ++listi)
for (label listi = 0; listi < len; ++listi)
{
const label faceId = addressing[listi];
const label faceId = addr[listi];
if (!exclude.test(faceId))
{
const enum elemType what = whatType(faces[faceId]);
sizes_[what]++;
const auto etype = whatType(faces[faceId]);
++sizes_[etype];
}
}
@ -281,22 +285,53 @@ void Foam::ensightFaces::classify
if (useFlip)
{
flipMap_.setSize(address_.size(), false);
flipMap_.resize(len);
flipMap_ = false;
}
else
{
flipMap_.clear(); // Extra safety
}
// Pass 2: Assign face-id per shape type
for (label listi = 0; listi < sz; ++listi)
for (label listi = 0; listi < len; ++listi)
{
const label faceId = addressing[listi];
const label faceId = addr[listi];
const bool doFlip = useFlip && flipMap[listi];
if (!exclude.test(faceId))
{
add(faces[faceId], faceId, doFlip);
const auto etype = whatType(faces[faceId]);
add(etype, faceId, doFlip);
}
}
}
void Foam::ensightFaces::writeDict(Ostream& os, const bool full) const
{
os.beginBlock(type());
os.writeEntry("id", index()+1); // Ensight starts with 1
os.writeEntry("name", name());
os.writeEntry("size", size());
if (full)
{
for (int typei=0; typei < ensightFaces::nTypes; ++typei)
{
const auto etype = ensightFaces::elemType(typei);
os.writeKeyword(ensightFaces::key(etype));
faceIds(etype).writeList(os, 0) << endEntry; // Flat output
}
}
os.endBlock();
}
// ************************************************************************* //

View File

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2020 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/>.
Class
Foam::ensightFaces
Description
Sorting/classification of faces (2D) into corresponding ensight types.
Some caution may be required when handling face addressing into a
boundaryField. Since the face addressing is absolute, it will be
necessary to work on a copy with local ids. For example,
\code
// Operate on a copy
ensightFaces localPart(part);
// Change from global faceIds to patch-local faceIds
localPart.decrFaceIds(patchStart);
// Can now address into boundaryField
\endcode
\*---------------------------------------------------------------------------*/
#ifndef ensightFaces_H
#define ensightFaces_H
#include "ensightPart.H"
#include "boolList.H"
#include "faceList.H"
#include "FixedList.H"
#include "bitSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class polyMesh;
/*---------------------------------------------------------------------------*\
Class ensightFaces Declaration
\*---------------------------------------------------------------------------*/
class ensightFaces
:
public ensightPart
{
public:
// Public Data
//- Supported ensight 'Face' element types.
// Must be zero-based since they are also for internal bookkeeping.
enum elemType
{
TRIA3 = 0, //!< "tria3"
QUAD4, //!< "quad4"
NSIDED //!< "nsided"
};
//- Number of 'Face' element types (3)
static constexpr int nTypes = 3;
//- The ensight 'Face' element type names
static const char* elemNames[nTypes];
// Static Functions
//- The ensight element name for the specified 'Face' type
static inline const char* key(const elemType etype);
private:
// Private Data
//- Linear list of face-flips
boolList flipMap_;
//- Begin/end offsets for address/flips of each element type
FixedList<label, nTypes+1> offsets_;
//- List of global sizes for each element type.
// Used temporarily for local sizes when building the element lists.
FixedList<label, nTypes> sizes_;
// Private Member Functions
//- Low-level internal addition routine
inline void add(const elemType etype, label id, bool flip=false);
//- Use temporarily stored sizes to redimension the element lists
void resizeAll();
public:
//- Declare type-name, virtual type (with debug switch)
TypeName("ensightFaces");
// Constructors
//- Default construct, with part index 0
ensightFaces();
//- Default construct, with description/partName
explicit ensightFaces(const string& description);
//- Destructor
virtual ~ensightFaces() = default;
// Member Functions
// Access
//- Processor-local size of all elements.
using ensightPart::size;
//- Processor-local size of the specified element type.
inline label size(const elemType etype) const;
//- Processor-local offset/size of element type.
inline labelRange range(const elemType etype) const;
//- The global size of all element types.
// This value is only meaningful after a reduce operation.
label total() const;
//- The global size of the specified element type.
// This value is only meaningful after a reduce operation.
inline label total(const elemType etype) const;
//- The global sizes for each element type.
// This value is only meaningful after a reduce operation.
inline const FixedList<label, nTypes>& totals() const;
//- Processor-local sizes per element type.
FixedList<label, nTypes> sizes() const;
//- Processor-local face ids of all elements
inline const labelList& faceIds() const;
//- Processor-local face ids of the specified element type
inline const labelUList faceIds(const elemType etype) const;
//- Processor-local flip-map of all elements
inline const boolList& flipMap() const;
//- True for non-zero flip-map that spans the addresses
inline bool usesFlipMap() const;
// Edit
//- Classify the face types and set the element lists.
void classify(const UList<face>& faces);
//- Classify face types (for a sublist) and set element lists.
void classify(const UList<face>& faces, const labelRange& range);
//- Classify the face types and set the element lists.
// The indirect addressing can be used when classifying groups of
// face (eg, from a faceZone etc) with an optional flipMap.
// The optional exclude marker can be used to skip faces on particular
// boundary types or regions.
void classify
(
const UList<face>& faces,
const labelUList& addr,
const boolList& flipMap = boolList(),
const bitSet& exclude = bitSet()
);
//- Clear any demand-driven data
void clearOut();
//- Set addressable sizes to zero, free up addressing memory.
void clear();
//- Sum element counts across all processes.
void reduce();
//- Sort element lists numerically.
void sort();
// Advanced (use with caution)
//- Increase face ids by specified offset value
// Eg, to change patch local Ids to global Ids
void incrFaceIds(const label off);
//- Decrease face ids by specified offset value
// Eg, to change global Ids to patch local Ids
void decrFaceIds(const label off);
// Output
//- Globally unique mesh points.
//- Required when writing point fields.
label uniqueMeshPoints
(
const polyMesh& mesh,
labelList& uniqueMeshPointLabels,
bool parallel
) const;
//- Write information about the object as a dictionary,
//- optionally write all element addresses
virtual void writeDict(Ostream& os, const bool full=false) const;
//- Write geometry, using a mesh reference (serial only)
virtual void write
(
ensightGeoFile& os,
const polyMesh& mesh,
bool parallel
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightFacesI.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightFaces.H"
#include "ensightOutput.H"
#include "polyMesh.H"
#include "globalIndex.H"
#include "globalMeshData.H"
#include "uindirectPrimitivePatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::ensightFaces::uniqueMeshPoints
(
const polyMesh& mesh,
labelList& uniqueMeshPointLabels,
bool parallel
) const
{
const ensightFaces& part = *this;
parallel = parallel && Pstream::parRun();
// Renumber the patch points/faces into unique points
label nPoints = 0; // Total number of points
labelList pointToGlobal; // local point to unique global index
const pointField& points = mesh.points();
const faceList& faces = mesh.faces();
// Use the properly sorted faceIds (ensightFaces) and do NOT use
// the faceZone or anything else directly, otherwise the
// point-maps will not correspond.
// - perform face-flipping later
uindirectPrimitivePatch pp
(
UIndirectList<face>(faces, part.faceIds()),
points
);
if (parallel)
{
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
pp.meshPoints(),
pp.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
nPoints = globalPointsPtr().size(); // nPoints (global)
}
else
{
// Non-parallel
// - all information already available from PrimitivePatch
nPoints = pp.meshPoints().size();
uniqueMeshPointLabels = pp.meshPoints();
// Not neaded: pointToGlobal
}
return nPoints;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,31 +25,27 @@ License
\*---------------------------------------------------------------------------*/
#include "error.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline const char* Foam::ensightFaces::key(const enum elemType what)
inline void Foam::ensightFaces::add(const elemType etype, label id, bool flip)
{
return elemNames[what];
// Linear addressing location
const label index = offsets_[etype] + sizes_[etype]++;
addressing()[index] = id;
if (flipMap_.size())
{
flipMap_[index] = flip;
}
}
inline Foam::label Foam::ensightFaces::index() const
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const char* Foam::ensightFaces::key(const elemType etype)
{
return index_;
}
inline Foam::label& Foam::ensightFaces::index()
{
return index_;
}
inline Foam::label Foam::ensightFaces::size() const
{
return address_.size();
return elemNames[etype];
}
@ -59,36 +55,34 @@ inline const Foam::FixedList<Foam::label,3>& Foam::ensightFaces::totals() const
}
inline Foam::label Foam::ensightFaces::total(const enum elemType what) const
inline Foam::label Foam::ensightFaces::total(const elemType etype) const
{
return sizes_[what];
return sizes_[etype];
}
inline Foam::label Foam::ensightFaces::size(const enum elemType what) const
inline Foam::label Foam::ensightFaces::size(const elemType etype) const
{
return slices_[what].size();
return (offsets_[etype+1] - offsets_[etype]);
}
inline Foam::label Foam::ensightFaces::offset(const enum elemType what) const
inline Foam::labelRange Foam::ensightFaces::range(const elemType etype) const
{
return slices_[what].start();
return labelRange(offsets_[etype], offsets_[etype+1] - offsets_[etype]);
}
inline const Foam::labelUList Foam::ensightFaces::faceIds
(
const enum elemType what
) const
inline const Foam::labelList& Foam::ensightFaces::faceIds() const
{
return address_[slices_[what]];
return addressing();
}
inline const Foam::labelUList& Foam::ensightFaces::faceIds() const
inline const Foam::labelUList
Foam::ensightFaces::faceIds(const elemType etype) const
{
return address_;
return addressing()[range(etype)];
}
@ -98,9 +92,21 @@ inline const Foam::boolList& Foam::ensightFaces::flipMap() const
}
inline Foam::label Foam::ensightFaces::operator[](const label i) const
inline bool Foam::ensightFaces::usesFlipMap() const
{
return address_[i];
return (!flipMap_.empty() && flipMap_.size() == size());
}
inline void Foam::ensightFaces::incrFaceIds(const label off)
{
incrAddressing(off);
}
inline void Foam::ensightFaces::decrFaceIds(const label off)
{
decrAddressing(off);
}

View File

@ -0,0 +1,138 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
\*---------------------------------------------------------------------------*/
#include "ensightFaces.H"
#include "ensightOutput.H"
#include "polyMesh.H"
#include "globalIndex.H"
#include "globalMeshData.H"
#include "uindirectPrimitivePatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::ensightFaces::write
(
ensightGeoFile& os,
const polyMesh& mesh,
bool parallel
) const
{
const ensightFaces& part = *this;
parallel = parallel && Pstream::parRun();
// Renumber the patch points/faces into unique points
label nPoints = 0; // Total number of points
labelList pointToGlobal; // local point to unique global index
labelList uniqueMeshPointLabels; // unique global points
const pointField& points = mesh.points();
const faceList& faces = mesh.faces();
// Use the properly sorted faceIds (ensightFaces) and do NOT use
// the faceZone or anything else directly, otherwise the
// point-maps will not correspond.
// - perform face-flipping later
uindirectPrimitivePatch pp
(
UIndirectList<face>(faces, part.faceIds()),
points
);
if (parallel)
{
autoPtr<globalIndex> globalPointsPtr =
mesh.globalData().mergePoints
(
pp.meshPoints(),
pp.meshPointMap(),
pointToGlobal,
uniqueMeshPointLabels
);
nPoints = globalPointsPtr().size(); // nPoints (global)
}
else
{
// Non-parallel
// - all information already available from PrimitivePatch
nPoints = pp.meshPoints().size();
uniqueMeshPointLabels = pp.meshPoints();
pointToGlobal.resize(nPoints);
ListOps::identity(pointToGlobal);
}
ensightOutput::Detail::writeCoordinates
(
os,
part.index(),
part.name(),
nPoints, // nPoints (global)
UIndirectList<point>(points, uniqueMeshPointLabels),
parallel //!< Collective write?
);
// Renumber the faces belonging to the faceZone,
// from local numbering to unique global index.
faceList patchFaces(pp.localFaces());
ListListOps::inplaceRenumber(pointToGlobal, patchFaces);
// Also a good place to perform face flipping
if (part.usesFlipMap())
{
const boolList& flip = part.flipMap();
forAll(patchFaces, facei)
{
face& f = patchFaces[facei];
if (flip[facei])
{
f.flip();
}
}
}
ensightOutput::writeFaceConnectivityPresorted
(
os,
part,
patchFaces,
parallel //!< Collective write?
);
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,28 +32,49 @@ License
namespace Foam
{
defineTypeNameAndDebug(ensightPart, 0);
defineTypeName(ensightPart);
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::ensightPart::incrAddressing(const label off)
{
for (label& val : address_)
{
val += off;
}
}
void Foam::ensightPart::decrAddressing(const label off)
{
for (label& val : address_)
{
val -= off;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightPart::ensightPart(const string& description)
Foam::ensightPart::ensightPart() noexcept
:
name_(description)
index_(0),
identifier_(-1),
name_(),
address_()
{}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::ensightGeoFile& Foam::operator<<
(
ensightGeoFile& os,
const ensightPart& part
)
Foam::ensightPart::ensightPart(const string& description)
:
ensightPart()
{
part.write(os);
return os;
if (!description.empty())
{
name_ = description;
}
}

View File

@ -0,0 +1,214 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2020 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/>.
Class
Foam::ensightPart
Description
Base class for ensightCells, ensightFaces, ensightOutputSurfaces.
SourceFiles
ensightPart.C
\*---------------------------------------------------------------------------*/
#ifndef ensightPart_H
#define ensightPart_H
#include "ensightGeoFile.H"
#include "labelList.H"
#include "typeInfo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightPart Declaration
\*---------------------------------------------------------------------------*/
class ensightPart
{
// Private Data
//- Part index within a list.
// The ensight part number is typically this value +1.
label index_;
//- OpenFOAM identifier (patch index, zone index, etc).
// An unused identifier is -1
label identifier_;
//- Part name (or description)
string name_;
//- Linear list of element ids (face/cell)
// Sub-sectioning by element type is done by derived classes
labelList address_;
protected:
//- Element addressing
const labelList& addressing() const
{
return address_;
}
//- Element addressing
labelList& addressing()
{
return address_;
}
//- Clear element addressing
void clear()
{
address_.clear();
}
//- Increase addressing by specified offset value
// Eg, change local to global id
void incrAddressing(const label off);
//- Decrease addressing by specified offset value
// Eg, change global to local id
void decrAddressing(const label off);
public:
//- Declare type-name, virtual type (without debug switch)
TypeNameNoDebug("ensightPart");
// Constructors
//- Default construct. Index=0, identifier = -1
ensightPart() noexcept;
//- Default construct, with description/partName
explicit ensightPart(const string& description);
//- Destructor
virtual ~ensightPart() = default;
// Member Functions
//- The index in a list (0-based)
label index() const
{
return index_;
}
//- The index in a list (0-based)
label& index()
{
return index_;
}
//- OpenFOAM identifier (patch, zone, etc), -1 when not in use.
label identifier() const
{
return identifier_;
}
//- OpenFOAM identifier (patch, zone, etc), -1 when not in use.
label& identifier()
{
return identifier_;
}
//- Processor-local test for any elements.
bool empty() const
{
return address_.empty();
}
//- Processor-local size of all elements.
label size() const
{
return address_.size();
}
//- The part name or description
const string& name() const
{
return name_;
}
//- Change the part name or description
void rename(const string& value)
{
name_ = value;
}
//- Change the part name or description
void rename(string&& value)
{
name_ = std::move(value);
}
// Output
//- Write information about the object as a dictionary,
//- optionally write all element addresses
virtual void writeDict(Ostream& os, const bool full=false) const
{}
// Member Operators
//- Processor-local element id from linear-list of addresses.
label operator[](const label i) const
{
return address_[i];
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Housekeeping
//- Deprecated(2020-02) - use ensightOutput or member write() methods
// \deprecated(2020-02) - use ensightOutput or member write() methods
void operator<<(ensightGeoFile&, const ensightPart&) = delete;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -23,35 +23,57 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Code chunk for converting volume and dimensioned fields
included by foamToEnsightParts.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ensightOutputSurface.H"
#include "ensightOutput.H"
// Cell field data output
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightOutputSurface::ensightOutputSurface
(
const pointField& points,
const faceList& faces,
const string& description
)
:
ensightFaces(description),
points_(points),
faces_(faces)
{
Info<< "Write volume field (";
// Classify face types
classify(faces);
}
writeAllVolFields
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ensightOutputSurface::write(ensightGeoFile& os) const
{
if (!total())
{
return;
}
// Coordinates
ensightOutput::Detail::writeCoordinates
(
ensCase,
ensParts,
mesh,
objects
os,
index(),
name(),
points_.size(),
points_,
false // serial
);
writeAllDimFields
// Faces
ensightOutput::writeFaceConnectivity
(
ensCase,
ensParts,
mesh,
objects
os,
*this,
faces_,
false // serial
);
Info<< " )" << nl;
}

View File

@ -0,0 +1,137 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
Class
Foam::ensightOutputSurface
Description
A variant of ensightFaces that holds references to contiguous
points/faces with its own encapsulated write methods.
The surface is assumed to have been merged prior, thus the output is
serial-only.
Note
The primary use is for the Foam::surfaceWriters::ensightWriter
but can be used independently as well.
SourceFiles
ensightOutputSurface.C
ensightOutputSurfaceTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef ensightOutputSurface_H
#define ensightOutputSurface_H
#include "ensightFaces.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ensightOutputSurface Declaration
\*---------------------------------------------------------------------------*/
class ensightOutputSurface
:
public ensightFaces
{
// Private Data
//- The referenced pointField
const pointField& points_;
//- The referenced faces
const faceList& faces_;
// Private Member Functions
//- No copy construct
ensightOutputSurface(const ensightOutputSurface&) = delete;
//- No copy assignment
void operator=(const ensightOutputSurface&) = delete;
public:
// Constructors
//- Construct from points and faces.
//- Part receives the specified name (default: "surface").
ensightOutputSurface
(
const pointField& points,
const faceList& faces,
const string& description = "surface"
);
//- Destructor
virtual ~ensightOutputSurface() = default;
// Member Functions
//- Write processor-local geometry (serial-only)
void write(ensightGeoFile& os) const;
//- Write a field of face or point values (serial-only)
template<class Type>
void writeData
(
ensightFile& os,
const Field<Type>& fld,
const bool isPointData = false
) const;
//- Write a field of face values (serial-only)
template<class Type>
void writeFaceData(ensightFile& os, const Field<Type>& fld) const;
//- Write a field of point values (serial-only)
template<class Type>
void writePointData(ensightFile& os, const Field<Type>& fld) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "ensightOutputSurfaceTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,56 +25,72 @@ License
\*---------------------------------------------------------------------------*/
#include "readFields.H"
#include "volFields.H"
#include "ensightOutputSurface.H"
#include "ensightOutput.H"
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::checkData
template<class Type>
void Foam::ensightOutputSurface::writeData
(
const fvMesh& mesh,
const instantList& timeDirs,
wordList& objectNames
)
ensightFile& os,
const Field<Type>& fld,
const bool isPointData
) const
{
// Assume prune_0() was used prior to calling this
wordHashSet goodFields;
for (const word& fieldName : objectNames)
if (isPointData)
{
bool good = false;
for (const instant& inst : timeDirs)
this->writePointData(os, fld);
}
else
{
good =
IOobject
this->writeFaceData(os, fld);
}
}
template<class Type>
void Foam::ensightOutputSurface::writeFaceData
(
ensightFile& os,
const Field<Type>& fld
) const
{
ensightOutput::writeField
(
fieldName,
inst.name(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false // no register
).typeHeaderOk<volScalarField>(false, false);
os,
fld,
*this,
false /* serial only! */
);
}
if (!good)
template<class Type>
void Foam::ensightOutputSurface::writePointData
(
ensightFile& os,
const Field<Type>& fld
) const
{
const ensightOutputSurface& part = *this;
// No geometry or field
if (part.empty() || fld.empty())
{
break;
}
return;
}
reduce(good, andOp<bool>());
if (good)
{
goodFields.insert(fieldName);
}
}
os.beginPart(part.index());
objectNames = goodFields.sortedToc();
return objectNames.size();
ensightOutput::Detail::writeFieldComponents
(
os,
ensightFile::coordinates,
fld,
false /* serial only! */
);
}

View File

@ -77,7 +77,8 @@ Foam::functionObjects::ensightWrite::ensightWrite
)
:
fvMeshFunctionObject(name, runTime, dict),
writeOpts_
writeOpts_(),
caseOpts_
(
IOstreamOption::formatNames.lookupOrDefault
(
@ -87,7 +88,6 @@ Foam::functionObjects::ensightWrite::ensightWrite
true // Failsafe behaviour
)
),
caseOpts_(writeOpts_.format()),
outputDir_(),
consecutive_(false),
meshState_(polyMesh::TOPO_CHANGE),

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2019 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -58,9 +58,9 @@ Foam::label Foam::functionObjects::ensightWrite::writeVolFields
ensightOutput::writeVolField<Type>
(
os.ref(),
field,
ensMesh(),
os.ref(),
caseOpts_.nodeValues()
);

View File

@ -31,8 +31,8 @@ License
#include "Fstream.H"
#include "OSspecific.H"
#include "ensightCase.H"
#include "ensightPartFaces.H"
#include "ensightOutput.H"
#include "ensightOutputSurface.H"
#include "ensightPTraits.H"
#include "surfaceWriterMethods.H"
#include "addToRunTimeSelectionTable.H"

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -405,29 +405,28 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
const fileName meshFile(baseDir/geometryName);
// Write geometry
ensightPartFaces ensPart
// Ensight Geometry
ensightOutputSurface part
(
0,
meshFile.name(),
surf.points(),
surf.faces(),
true // contiguous points
meshFile.name()
);
if (!exists(meshFile))
{
if (verbose_)
{
Info<< "Writing mesh file to " << meshFile.name() << endl;
}
// Use two-argument form for path-name to avoid validating base-dir
// Two-argument form for path-name to avoid validating base-dir
ensightGeoFile osGeom
(
meshFile.path(),
meshFile.name(),
writeFormat_
);
osGeom << ensPart;
part.write(osGeom); // serial
}
// Write field
@ -443,31 +442,11 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeCollated
Info<< "Writing field file to " << osField.name() << endl;
}
// Write field
// Write field (serial only)
osField.writeKeyword(ensightPTraits<Type>::typeName);
part.writeData(osField, tfield(), this->isPointData());
if (this->isPointData())
{
ensightOutput::Serial::writePointField
(
tfield(),
ensPart,
osField
// serial
);
}
else
{
ensightOutput::Detail::writeFaceField
(
tfield(),
ensPart,
osField,
false // serial
);
}
// Place a timestamp in the directory for future reference
// Timestamp in the directory for future reference
{
OFstream timeStamp(dataDir/"time");
timeStamp

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -87,15 +87,13 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated()
printTimeset(osCase, 1, 0.0);
ensightPartFaces ensPart
ensightOutputSurface part
(
0,
osGeom.name().name(),
surf.points(),
surf.faces(),
true // contiguous points
osGeom.name().name()
);
osGeom << ensPart;
part.write(osGeom); // serial
}
wroteGeom_ = true;
@ -173,6 +171,7 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
osCase.setf(ios_base::scientific, ios_base::floatfield);
osCase.precision(5);
// Two-argument form for path-name to avoid validating base-dir
ensightGeoFile osGeom
(
baseDir,
@ -212,39 +211,18 @@ Foam::fileName Foam::surfaceWriters::ensightWriter::writeUncollated
osCase << "# end" << nl;
ensightPartFaces ensPart
// Ensight Geometry
ensightOutputSurface part
(
0,
osGeom.name().name(),
surf.points(),
surf.faces(),
true // contiguous points
osGeom.name().name()
);
osGeom << ensPart;
part.write(osGeom); // serial
// Write field
// Write field (serial)
osField.writeKeyword(ensightPTraits<Type>::typeName);
if (this->isPointData())
{
ensightOutput::Serial::writePointField
(
tfield(),
ensPart,
osField
// serial
);
}
else
{
ensightOutput::Detail::writeFaceField
(
tfield(),
ensPart,
osField,
false // serial
);
}
part.writeData(osField, tfield(), this->isPointData());
}
wroteGeom_ = true;

View File

@ -6,7 +6,6 @@ cd "${0%/*}" || exit # Run from this directory
runApplication ansysToFoam flange.ans -scale 0.001
runApplication $(getApplication)
runApplication foamToEnsight -noZero
runApplication foamToEnsightParts -noZero
runApplication foamToVTK
#------------------------------------------------------------------------------