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)
This commit is contained in:
@ -30,18 +30,19 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::fvMeshSubsetProxy::fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh
|
||||
)
|
||||
Foam::fvMeshSubsetProxy::fvMeshSubsetProxy(fvMesh& baseMesh)
|
||||
:
|
||||
baseMesh_(baseMesh),
|
||||
subsetter_(baseMesh),
|
||||
exposedPatchId_(-1),
|
||||
type_(NONE),
|
||||
name_(),
|
||||
exposedPatchId_(-1)
|
||||
names_()
|
||||
{
|
||||
correct();
|
||||
if (useSubMesh())
|
||||
{
|
||||
correct();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -49,17 +50,74 @@ Foam::fvMeshSubsetProxy::fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
const subsetType type,
|
||||
const word& name,
|
||||
const label exposedPatchId
|
||||
const word& selectionName,
|
||||
label exposedPatchId
|
||||
)
|
||||
:
|
||||
baseMesh_(baseMesh),
|
||||
subsetter_(baseMesh),
|
||||
type_(name.empty() ? NONE : type),
|
||||
name_(name),
|
||||
exposedPatchId_(exposedPatchId)
|
||||
exposedPatchId_(exposedPatchId),
|
||||
type_(selectionName.empty() ? NONE : type),
|
||||
name_(),
|
||||
names_()
|
||||
{
|
||||
correct();
|
||||
if (type_ == ZONES)
|
||||
{
|
||||
// Populate wordRes for ZONES
|
||||
names_.resize(1);
|
||||
names_.first() = selectionName;
|
||||
}
|
||||
else if (type_ != NONE)
|
||||
{
|
||||
name_ = selectionName;
|
||||
}
|
||||
|
||||
if (useSubMesh())
|
||||
{
|
||||
correct();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::fvMeshSubsetProxy::fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
const wordRes& zoneNames,
|
||||
label exposedPatchId
|
||||
)
|
||||
:
|
||||
baseMesh_(baseMesh),
|
||||
subsetter_(baseMesh),
|
||||
exposedPatchId_(exposedPatchId),
|
||||
type_(ZONES),
|
||||
name_(),
|
||||
names_(zoneNames)
|
||||
{
|
||||
if (useSubMesh())
|
||||
{
|
||||
correct();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::fvMeshSubsetProxy::fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
wordRes&& zoneNames,
|
||||
label exposedPatchId
|
||||
)
|
||||
:
|
||||
baseMesh_(baseMesh),
|
||||
subsetter_(baseMesh),
|
||||
exposedPatchId_(exposedPatchId),
|
||||
type_(ZONES),
|
||||
name_(),
|
||||
names_(std::move(zoneNames))
|
||||
{
|
||||
if (useSubMesh())
|
||||
{
|
||||
correct();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -67,6 +125,16 @@ Foam::fvMeshSubsetProxy::fvMeshSubsetProxy
|
||||
|
||||
void Foam::fvMeshSubsetProxy::correct(bool verbose)
|
||||
{
|
||||
if (type_ == NONE)
|
||||
{
|
||||
subsetter_.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
const label nCells = baseMesh_.nCells();
|
||||
|
||||
bitSet selectedCells;
|
||||
|
||||
if (type_ == SET)
|
||||
{
|
||||
if (verbose)
|
||||
@ -74,11 +142,13 @@ void Foam::fvMeshSubsetProxy::correct(bool verbose)
|
||||
Info<< "Subsetting mesh based on cellSet " << name_ << endl;
|
||||
}
|
||||
|
||||
subsetter_.setCellSubset
|
||||
(
|
||||
cellSet(baseMesh_, name_),
|
||||
exposedPatchId_
|
||||
);
|
||||
cellSet cset(baseMesh_, name_);
|
||||
|
||||
selectedCells.resize(nCells);
|
||||
for (const label idx : cset)
|
||||
{
|
||||
selectedCells.set(idx);
|
||||
}
|
||||
}
|
||||
else if (type_ == ZONE)
|
||||
{
|
||||
@ -87,12 +157,21 @@ void Foam::fvMeshSubsetProxy::correct(bool verbose)
|
||||
Info<< "Subsetting mesh based on cellZone " << name_ << endl;
|
||||
}
|
||||
|
||||
subsetter_.setCellSubset
|
||||
(
|
||||
baseMesh_.cellZones()[name_],
|
||||
exposedPatchId_
|
||||
);
|
||||
selectedCells.resize(nCells);
|
||||
selectedCells.set(baseMesh_.cellZones()[name_]);
|
||||
}
|
||||
else if (type_ == ZONES)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
Info<< "Subsetting mesh based on cellZones "
|
||||
<< flatOutput(names_) << endl;
|
||||
}
|
||||
|
||||
selectedCells = baseMesh_.cellZones().selection(names_);
|
||||
}
|
||||
|
||||
subsetter_.setCellSubset(selectedCells, exposedPatchId_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ SourceFiles
|
||||
#ifndef fvMeshSubsetProxy_H
|
||||
#define fvMeshSubsetProxy_H
|
||||
|
||||
#include "wordRes.H"
|
||||
#include "fvMeshSubset.H"
|
||||
#include "zeroGradientFvPatchField.H"
|
||||
|
||||
@ -56,33 +57,37 @@ class fvMeshSubsetProxy
|
||||
{
|
||||
public:
|
||||
|
||||
//- Internal book-keeping for subset type
|
||||
//- Internal bookkeeping for subset type
|
||||
enum subsetType
|
||||
{
|
||||
NONE = 0, //<! Not a subset
|
||||
SET, //<! Using a cellSet for the subset
|
||||
ZONE //<! Using a cellZone for the subset
|
||||
NONE, //<! No subset
|
||||
SET, //<! Subset with a cellSet
|
||||
ZONE, //<! Subset with a cellZone
|
||||
ZONES //<! Subset with multiple cellZones
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
//- Reference to mesh
|
||||
fvMesh& baseMesh_;
|
||||
|
||||
//- Subsetting engine + sub-fvMesh
|
||||
//- Subsetting engine
|
||||
fvMeshSubset subsetter_;
|
||||
|
||||
//- Subset type if any.
|
||||
const subsetType type_;
|
||||
|
||||
//- Name of current cellSet/cellZone (or empty)
|
||||
const word name_;
|
||||
|
||||
//- Patch ID for exposed internal faces
|
||||
const label exposedPatchId_;
|
||||
label exposedPatchId_;
|
||||
|
||||
//- The subsetting type
|
||||
subsetType type_;
|
||||
|
||||
//- Name of the cellSet/cellZone (or empty)
|
||||
word name_;
|
||||
|
||||
//- Selection for multiple cell zones
|
||||
wordRes names_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
@ -98,16 +103,32 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
fvMeshSubsetProxy(fvMesh& baseMesh);
|
||||
//- Construct a pass-through proxy. No correct() invoked or required.
|
||||
explicit fvMeshSubsetProxy(fvMesh& baseMesh);
|
||||
|
||||
//- Construct from components
|
||||
fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
const subsetType,
|
||||
const word& name,
|
||||
const label exposedPatchId = -1
|
||||
const subsetType type,
|
||||
const word& selectionName,
|
||||
label exposedPatchId = -1
|
||||
);
|
||||
|
||||
//- Construct from components. The subsetType is ZONES.
|
||||
fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
const wordRes& zoneNames,
|
||||
label exposedPatchId = -1
|
||||
);
|
||||
|
||||
//- Construct from components. The subsetType is ZONES.
|
||||
fvMeshSubsetProxy
|
||||
(
|
||||
fvMesh& baseMesh,
|
||||
wordRes&& zoneNames,
|
||||
label exposedPatchId = -1
|
||||
);
|
||||
|
||||
|
||||
@ -153,55 +174,90 @@ public:
|
||||
|
||||
// Edit
|
||||
|
||||
//- Update mesh subset
|
||||
//- Update of mesh subset
|
||||
void correct(bool verbose = false);
|
||||
|
||||
//- Read mesh. Correct on topo-change
|
||||
polyMesh::readUpdateState readUpdate();
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Construct volField (with zeroGradient) from an internal field
|
||||
template<class Type>
|
||||
static tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
zeroGradientField
|
||||
(
|
||||
const typename GeometricField
|
||||
<
|
||||
Type,
|
||||
fvPatchField,
|
||||
volMesh
|
||||
>::Internal& fld
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
);
|
||||
|
||||
//- Convert an internal field to a volume field (with zeroGradient)
|
||||
template<class Type>
|
||||
static tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
interpolateInternal
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
);
|
||||
|
||||
//- Convert an internal field to a volume field (with zeroGradient)
|
||||
// Currently no proper memory reuse
|
||||
template<class Type>
|
||||
static tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
interpolateInternal
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const tmp<DimensionedField<Type, volMesh>>& tdf
|
||||
);
|
||||
|
||||
//- Wrapper for field or the subsetted field.
|
||||
// Pass through or forward to fvMeshSubset::interpolate()
|
||||
template<class GeoField>
|
||||
static tmp<GeoField> interpolate
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const GeoField& fld
|
||||
);
|
||||
|
||||
//- Wrapper for field or the subsetted field.
|
||||
// Pass through or forward to fvMeshSubset::interpolate()
|
||||
template<class GeoField>
|
||||
static tmp<GeoField> interpolate
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const tmp<GeoField>& fld
|
||||
);
|
||||
|
||||
|
||||
// Fields
|
||||
|
||||
//- Convert an internal field to a volume field (with zeroGradient)
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
interpolateInternal
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
) const;
|
||||
|
||||
//- Convert an internal field to a volume field (with zeroGradient)
|
||||
// Currently no proper memory reuse
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
interpolateInternal
|
||||
(
|
||||
const tmp<DimensionedField<Type, volMesh>>& tdf
|
||||
) const;
|
||||
|
||||
|
||||
//- Wrapper for field or the subsetted field.
|
||||
// Map volume field (does in fact do very little interpolation;
|
||||
// just copied from fvMeshSubset)
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
interpolate
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld
|
||||
) const;
|
||||
|
||||
|
||||
//- Convert an internal field to a volume field
|
||||
template<class Type>
|
||||
tmp<GeometricField<Type, fvPatchField, volMesh>>
|
||||
interpolate
|
||||
(
|
||||
const typename GeometricField
|
||||
<
|
||||
Type,
|
||||
fvPatchField,
|
||||
volMesh
|
||||
>::Internal& fld
|
||||
) const;
|
||||
|
||||
|
||||
//- Map volume field. Just forwards to fvMeshSubset
|
||||
// Pass through or forward to fvMeshSubset::interpolate()
|
||||
template<class GeoField>
|
||||
tmp<GeoField> interpolate(const GeoField& fld) const;
|
||||
|
||||
//- Wrapper for field or the subsetted field.
|
||||
// Pass through or forward to fvMeshSubset::interpolate()
|
||||
template<class GeoField>
|
||||
tmp<GeoField> interpolate(const tmp<GeoField>& fld) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -26,18 +26,16 @@ License
|
||||
#include "fvMeshSubsetProxy.H"
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::tmp
|
||||
<
|
||||
Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>
|
||||
>
|
||||
Foam::fvMeshSubsetProxy::zeroGradientField
|
||||
(
|
||||
const typename GeometricField
|
||||
<
|
||||
Type,
|
||||
fvPatchField,
|
||||
volMesh
|
||||
>::Internal& df
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
)
|
||||
{
|
||||
IOobject io(df);
|
||||
@ -62,44 +60,55 @@ Foam::fvMeshSubsetProxy::zeroGradientField
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::fvMeshSubsetProxy::interpolate
|
||||
Foam::fvMeshSubsetProxy::interpolateInternal
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||
) const
|
||||
const fvMeshSubset& subsetter,
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
)
|
||||
{
|
||||
if (subsetter_.hasSubMesh())
|
||||
{
|
||||
auto tfield(subsetter_.interpolate(vf));
|
||||
auto tfield = zeroGradientField<Type>(df);
|
||||
|
||||
tfield.ref().checkOut();
|
||||
tfield.ref().rename(vf.name());
|
||||
return tfield;
|
||||
if (subsetter.hasSubMesh())
|
||||
{
|
||||
return interpolate(subsetter, tfield());
|
||||
}
|
||||
|
||||
return vf;
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::fvMeshSubsetProxy::interpolate
|
||||
Foam::fvMeshSubsetProxy::interpolateInternal
|
||||
(
|
||||
const typename GeometricField
|
||||
<
|
||||
Type,
|
||||
fvPatchField,
|
||||
volMesh
|
||||
>::Internal& df
|
||||
) const
|
||||
const fvMeshSubset& subsetter,
|
||||
const tmp<DimensionedField<Type, volMesh>>& tdf
|
||||
)
|
||||
{
|
||||
auto tfield = zeroGradientField<Type>(df);
|
||||
// TODO - move dimensioned mesh into internal,
|
||||
// but needs different GeometricField constructors
|
||||
|
||||
if (subsetter_.hasSubMesh())
|
||||
if (tdf.valid())
|
||||
{
|
||||
return interpolate<Type>(tfield());
|
||||
if (subsetter.hasSubMesh())
|
||||
{
|
||||
auto tproxied = interpolate(subsetter, tdf);
|
||||
auto tfield = zeroGradientField<Type>(tproxied());
|
||||
|
||||
tdf.clear();
|
||||
tproxied.clear();
|
||||
return tfield;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto tfield = zeroGradientField<Type>(tdf());
|
||||
|
||||
tdf.clear();
|
||||
return tfield;
|
||||
}
|
||||
}
|
||||
|
||||
return tfield;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -107,12 +116,14 @@ template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::fvMeshSubsetProxy::interpolate
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const GeoField& fld
|
||||
) const
|
||||
)
|
||||
{
|
||||
if (subsetter_.hasSubMesh())
|
||||
if (subsetter.hasSubMesh())
|
||||
{
|
||||
tmp<GeoField> tfield = subsetter_.interpolate(fld);
|
||||
auto tfield = subsetter.interpolate(fld);
|
||||
|
||||
tfield.ref().checkOut();
|
||||
tfield.ref().rename(fld.name());
|
||||
return tfield;
|
||||
@ -122,4 +133,65 @@ Foam::fvMeshSubsetProxy::interpolate
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::fvMeshSubsetProxy::interpolate
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const tmp<GeoField>& tfield
|
||||
)
|
||||
{
|
||||
if (tfield.valid() && subsetter.hasSubMesh())
|
||||
{
|
||||
auto tproxied = interpolate(subsetter, tfield());
|
||||
tfield.clear();
|
||||
|
||||
return tproxied;
|
||||
}
|
||||
|
||||
// Nothing to be done
|
||||
return tfield;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::fvMeshSubsetProxy::interpolateInternal
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& df
|
||||
) const
|
||||
{
|
||||
return interpolateInternal(subsetter_, df);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
|
||||
Foam::fvMeshSubsetProxy::interpolateInternal
|
||||
(
|
||||
const tmp<DimensionedField<Type, volMesh>>& tdf
|
||||
) const
|
||||
{
|
||||
return interpolateInternal(subsetter_, tdf);
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::fvMeshSubsetProxy::interpolate(const GeoField& fld) const
|
||||
{
|
||||
return interpolate(subsetter_, fld);
|
||||
}
|
||||
|
||||
|
||||
template<class GeoField>
|
||||
Foam::tmp<GeoField>
|
||||
Foam::fvMeshSubsetProxy::interpolate(const tmp<GeoField>& tfield) const
|
||||
{
|
||||
return interpolate(subsetter_, tfield);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
Reference in New Issue
Block a user