Commit 2fb382bf authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: multiple zone selection for fvMeshSubsetProxy (#973)

- handle tmp fields in interpolate methods

- special method interpolateInternal() for creating a volume field
  with zero-gradient treatment for patches from an internal field.

  This method was previously also called interpolate(), but that
  masked the ability to subset the internal field only.

  Ensight output needs the volume field:
      uses interpolateInternal().

  VTK output has separate handling of internal and patch fields:
      uses interpolate().

ENH: added fvMeshSubset mesh() method for baseMesh or subMesh.

- simplies coding when the fvMeshSubset may or may not be in active use.

ENH: update foamToEnsight to use newer methods in wrapped form

- static interpolate functions with renaming for manual use with
  fvMeshSubset (when fvMeshSubsetProxy may be too limiting in
  functionality)
parent 94951939
......@@ -88,15 +88,49 @@ Note
#include "ensightGeoFile.H"
#include "ensightMesh.H"
#include "ensightOutput.H"
#include "fvMeshSubsetProxy.H"
// local files
#include "fvMeshSubsetProxy.H"
#include "ensightOutputCloud.H"
#include "memInfo.H"
using namespace Foam;
//- Get the field and subset it
template<class GeoField>
tmp<GeoField> getField(IOobject& io, const fvMeshSubsetProxy& proxy)
{
auto tfield = tmp<GeoField>::New(io, proxy.baseMesh());
return proxy.interpolate(tfield);
}
//- Get the field and subset it, or return nullptr
template<class GeoField>
tmp<GeoField> getField(const IOobject* io, const fvMeshSubsetProxy& proxy)
{
if (io)
{
auto tfield = tmp<GeoField>::New(*io, proxy.baseMesh());
return proxy.interpolate(tfield);
}
return nullptr;
}
//- 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[])
......@@ -256,12 +290,12 @@ int main(int argc, char *argv[])
if (args.readIfPresent("cellZone", cellZoneName))
{
Info<< "Converting cellZone " << cellZoneName
<< " only. Places new outside faces into \"oldInternalFaces\"."
<< " only, with new outside faces as \"oldInternalFaces\"."
<< nl;
}
// fvMeshSubset is ignored if cellZoneName is empty
fvMeshSubsetProxy meshRef(mesh, fvMeshSubsetProxy::ZONE, cellZoneName);
// Ignored (unproxied) if cellZoneName is empty
fvMeshSubsetProxy meshProxy(mesh, fvMeshSubsetProxy::ZONE, cellZoneName);
//
// Open new ensight case file, initialize header etc.
......@@ -275,7 +309,7 @@ int main(int argc, char *argv[])
// Construct the Ensight mesh
ensightMesh ensMesh(meshRef.mesh(), writeOpts);
ensightMesh ensMesh(meshProxy.mesh(), writeOpts);
if (Pstream::master())
{
......@@ -344,7 +378,7 @@ int main(int argc, char *argv[])
polyMesh::readUpdateState meshState = mesh.readUpdate();
if (meshState != polyMesh::UNCHANGED)
{
meshRef.correct();
meshProxy.correct();
ensMesh.expire();
ensMesh.correct();
}
......@@ -396,10 +430,9 @@ int main(int argc, char *argv[])
fieldName
);
volScalarField vf(fieldObject, mesh);
wrote = ensightOutput::writeField<scalar>
(
meshRef.interpolate(vf),
getField<volScalarField>(fieldObject, meshProxy),
ensMesh,
os,
nodeValues
......@@ -412,10 +445,9 @@ int main(int argc, char *argv[])
fieldName
);
volVectorField vf(fieldObject, mesh);
wrote = ensightOutput::writeField<vector>
(
meshRef.interpolate(vf),
getField<volVectorField>(fieldObject, meshProxy),
ensMesh,
os,
nodeValues
......@@ -428,10 +460,13 @@ int main(int argc, char *argv[])
fieldObject.name()
);
volSphericalTensorField vf(fieldObject, mesh);
wrote = ensightOutput::writeField<sphericalTensor>
(
meshRef.interpolate(vf),
getField<volSphericalTensorField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......@@ -444,10 +479,13 @@ int main(int argc, char *argv[])
fieldName
);
volSymmTensorField vf(fieldObject, mesh);
wrote = ensightOutput::writeField<symmTensor>
(
meshRef.interpolate(vf),
getField<volSymmTensorField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......@@ -460,10 +498,9 @@ int main(int argc, char *argv[])
fieldName
);
volTensorField vf(fieldObject, mesh);
wrote = ensightOutput::writeField<tensor>
(
meshRef.interpolate(vf),
getField<volTensorField>(fieldObject, meshProxy),
ensMesh,
os,
nodeValues
......@@ -481,14 +518,13 @@ int main(int argc, char *argv[])
fieldName
);
volScalarField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<scalar>
(
meshRef.interpolate<scalar>(df),
getZeroGradInternalField<volScalarField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......@@ -505,14 +541,13 @@ int main(int argc, char *argv[])
fieldName
);
volVectorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<vector>
(
meshRef.interpolate<vector>(df),
getZeroGradInternalField<volVectorField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......@@ -529,14 +564,13 @@ int main(int argc, char *argv[])
fieldName
);
volSphericalTensorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<sphericalTensor>
(
meshRef.interpolate<sphericalTensor>(df),
getZeroGradInternalField<volSphericalTensorField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......@@ -553,14 +587,13 @@ int main(int argc, char *argv[])
fieldName
);
volSymmTensorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<symmTensor>
(
meshRef.interpolate<symmTensor>(df),
getZeroGradInternalField<volSymmTensorField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......@@ -577,14 +610,13 @@ int main(int argc, char *argv[])
fieldName
);
volTensorField::Internal df
(
fieldObject,
mesh
);
wrote = ensightOutput::writeField<tensor>
(
meshRef.interpolate<tensor>(df),
getZeroGradInternalField<volTensorField>
(
fieldObject,
meshProxy
),
ensMesh,
os,
nodeValues
......
......@@ -554,7 +554,7 @@ int main(int argc, char *argv[])
instantList timeDirs = timeSelector::select0(runTime, args);
// Mesh wrapper: does subsetting and decomposition
fvMeshSubsetProxy meshRef(mesh, cellSubsetType, cellSubsetName);
fvMeshSubsetProxy meshProxy(mesh, cellSubsetType, cellSubsetName);
// Collect decomposition information etc.
vtk::vtuCells vtuMeshCells(fmtType, decomposePoly);
......@@ -616,9 +616,9 @@ int main(int argc, char *argv[])
// Check for new polyMesh/ and update mesh, fvMeshSubset and cell
// decomposition.
polyMesh::readUpdateState meshState = meshRef.readUpdate();
polyMesh::readUpdateState meshState = meshProxy.readUpdate();
const fvMesh& mesh = meshRef.mesh();
const fvMesh& mesh = meshProxy.mesh();
if
(
meshState == polyMesh::TOPO_CHANGE
......@@ -649,7 +649,7 @@ int main(int argc, char *argv[])
vtk::writeFaceSet
(
meshRef.mesh(),
meshProxy.mesh(),
set,
outputName,
fmtType
......@@ -677,7 +677,7 @@ int main(int argc, char *argv[])
vtk::writePointSet
(
meshRef.mesh(),
meshProxy.mesh(),
set,
outputName,
fmtType
......@@ -718,8 +718,8 @@ int main(int argc, char *argv[])
{
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
vScalarFld
......@@ -728,8 +728,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
vVectorFld
......@@ -738,8 +738,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
vSphTensorf
......@@ -748,8 +748,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
vSymTensorFld
......@@ -758,8 +758,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
vTensorFld
......@@ -797,8 +797,8 @@ int main(int argc, char *argv[])
{
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
dScalarFld
......@@ -807,8 +807,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
dVectorFld
......@@ -817,8 +817,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
dSphTensorFld
......@@ -827,8 +827,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
dSymTensorFld
......@@ -837,8 +837,8 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
dTensorFld
......@@ -865,7 +865,7 @@ int main(int argc, char *argv[])
const bool throwing = FatalError.throwExceptions();
try
{
aMeshPtr.reset(new faMesh(meshRef.baseMesh()));
aMeshPtr.reset(new faMesh(meshProxy.baseMesh()));
}
catch (Foam::error& err)
{
......@@ -992,11 +992,11 @@ int main(int argc, char *argv[])
).size()
)
{
const pointMesh& ptMesh = pointMesh::New(meshRef.baseMesh());
const pointMesh& ptMesh = pointMesh::New(meshProxy.baseMesh());
readFields
(
meshRef,
meshProxy,
ptMesh,
objects,
selectedFields,
......@@ -1006,7 +1006,7 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshProxy,
ptMesh,
objects,
selectedFields,
......@@ -1016,7 +1016,7 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshProxy,
ptMesh,
objects,
selectedFields,
......@@ -1026,7 +1026,7 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshProxy,
ptMesh,
objects,
selectedFields,
......@@ -1036,7 +1036,7 @@ int main(int argc, char *argv[])
readFields
(
meshRef,
meshProxy,
ptMesh,
objects,
selectedFields,
......@@ -1057,7 +1057,7 @@ int main(int argc, char *argv[])
if (vtuMeshCells.empty())
{
// subMesh or baseMesh
vtuMeshCells.reset(meshRef.mesh());
vtuMeshCells.reset(meshProxy.mesh());
}
// Create file and write header
......@@ -1073,7 +1073,7 @@ int main(int argc, char *argv[])
// Write mesh
vtk::internalWriter writer
(
meshRef.mesh(),
meshProxy.mesh(),
vtuMeshCells,
outputName,
fmtType
......@@ -1147,8 +1147,8 @@ int main(int argc, char *argv[])
PtrList<const surfaceScalarField> sScalarFld;
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
sScalarFld
......@@ -1158,8 +1158,8 @@ int main(int argc, char *argv[])
PtrList<const surfaceVectorField> sVectorFld;
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
sVectorFld
......@@ -1199,7 +1199,7 @@ int main(int argc, char *argv[])
vtk::writeSurfFields
(
meshRef.mesh(),
meshProxy.mesh(),
outputName,
fmtType,
sVectorFld
......@@ -1223,7 +1223,7 @@ int main(int argc, char *argv[])
fileName outputName
(
fvPath/"allPatches"
/ (meshRef.useSubMesh() ? cellSubsetName : "allPatches")
/ (meshProxy.useSubMesh() ? cellSubsetName : "allPatches")
+ "_"
+ timeDesc
);
......@@ -1232,7 +1232,7 @@ int main(int argc, char *argv[])
vtk::patchWriter writer
(
meshRef.mesh(),
meshProxy.mesh(),
outputName,
fmtType,
nearCellValue,
......@@ -1293,7 +1293,7 @@ int main(int argc, char *argv[])
fileName outputName
(
fvPath/pp.name()
/ (meshRef.useSubMesh() ? cellSubsetName : pp.name())
/ (meshProxy.useSubMesh() ? cellSubsetName : pp.name())
+ "_"
+ timeDesc
);
......@@ -1302,7 +1302,7 @@ int main(int argc, char *argv[])
vtk::patchWriter writer
(
meshRef.mesh(),
meshProxy.mesh(),
outputName,
fmtType,
nearCellValue,
......@@ -1368,8 +1368,8 @@ int main(int argc, char *argv[])
PtrList<const surfaceScalarField> sScalarFld;
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
sScalarFld
......@@ -1379,8 +1379,8 @@ int main(int argc, char *argv[])
PtrList<const surfaceVectorField> sVectorFld;
readFields
(
meshRef,
meshRef.baseMesh(),
meshProxy,
meshProxy.baseMesh(),
objects,
selectedFields,
sVectorFld
......@@ -1394,7 +1394,7 @@ int main(int argc, char *argv[])
fileName outputName =
(
fvPath/fz.name()
/ (meshRef.useSubMesh() ? cellSubsetName : fz.name())
/ (meshProxy.useSubMesh() ? cellSubsetName : fz.name())
+ "_"
+ timeDesc
);
......@@ -1528,7 +1528,7 @@ int main(int argc, char *argv[])
vtk::lagrangianWriter writer
(
meshRef.mesh(),
meshProxy.mesh(),
cloudName,
outputName,
fmtType
......@@ -1553,7 +1553,7 @@ int main(int argc, char *argv[])
{
vtk::lagrangianWriter writer
(
meshRef.mesh(),
meshProxy.mesh(),
cloudName,
outputName,
fmtType,
......
......@@ -213,6 +213,9 @@ public:
//- Original mesh
inline const fvMesh& baseMesh() const;
//- Return baseMesh or subMesh, depending on the current state.
inline const fvMesh& mesh() const;
//- Have subMesh?
inline bool hasSubMesh() const;
......@@ -244,10 +247,10 @@ public:
void clear();
//- Define the cell subset based on the selectedCells.
//- Define cell subset based on the selectedCells.
// Create "oldInternalFaces" patch for exposed
// internal faces (patchID==-1) or use supplied patch.
// Handles coupled patches by if necessary making coupled patch
// Handles coupled patches if necessary by making coupled patch
// face part of patchID (so uncoupled)
void setCellSubset
(
......@@ -256,7 +259,7 @@ public:
const bool syncPar = true
);
//- Define the cell subset, using the specified cells
//- Define cell subset, using the specified cells
//- to define the selection
void setCellSubset
(
......@@ -265,7 +268,7 @@ public:
const bool syncPar = true
);