Commit 61012721 authored by sergio's avatar sergio Committed by Mattijs Janssens
Browse files

ENH: Adding subMesh option to momentumError and div FOs

1) Adding subMesh capabilities to momentumError and div FOs.
	- A subMesh is created from cellZones.
	- The operators (div, etc) are only calculated in the subMesh.

2) Optionally, halo cells can be added to the cellZones.

3) New helper class to handle the subMesh creation and field mapping.
parent 6595429f
......@@ -6,4 +6,5 @@ EXE_INC = \
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-ldynamicMesh \
-lfieldFunctionObjects
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -74,7 +74,6 @@ class regionFunctionObject
:
public stateFunctionObject
{
protected:
// Protected Member Data
......@@ -147,6 +146,15 @@ protected:
bool cacheable = false
);
//- Store the field in an optional objectRegistry under the given name
template<class ObjectType>
bool storeInDb
(
const word& fieldName,
const tmp<ObjectType>& tfield,
const objectRegistry& obr
);
//- Write field if present in the (sub) objectRegistry
bool writeObject(const word& fieldName);
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenFOAM Foundation
Copyright (C) 2016-2018 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -122,16 +122,20 @@ bool Foam::functionObjects::regionFunctionObject::store
return false;
}
if (fieldName.size() && foundObject<ObjectType>(fieldName))
{
const ObjectType& field = lookupObject<ObjectType>(fieldName);
ObjectType* fieldptr;
if
(
!fieldName.empty()
&& (fieldptr = getObjectPtr<ObjectType>(fieldName)) != nullptr
)
{
// If there is a result field already registered, assign to the new
// result field. Otherwise transfer ownership of the new result field to
// the object registry
if (&field != &tfield())
if (fieldptr != &tfield())
{
const_cast<ObjectType&>(field) = tfield;
(*fieldptr) = tfield;
}
else
{
......@@ -156,4 +160,31 @@ bool Foam::functionObjects::regionFunctionObject::store
}
template<class ObjectType>
bool Foam::functionObjects::regionFunctionObject::storeInDb
(
const word& fieldName,
const tmp<ObjectType>& tfield,
const objectRegistry& obr
)
{
ObjectType* fieldptr;
if
(
!fieldName.empty()
&& (fieldptr = obr.getObjectPtr<ObjectType>(fieldName)) != nullptr
)
{
(*fieldptr) = tfield;
}
else
{
tfield.ref().rename(fieldName);
obr.objectRegistry::store(tfield.ptr());
}
return true;
}
// ************************************************************************* //
......@@ -138,4 +138,6 @@ polyMeshFilter/polyMeshFilter.C
pointPatchDist/externalPointEdgePoint.C
pointPatchDist/pointPatchDist.C
zoneSubSet/zoneSubSet.C
LIB = $(FOAM_LIBBIN)/libdynamicMesh
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
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 "zoneSubSet.H"
#include "cellBitSet.H"
#include "haloToCell.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace Detail
{
defineTypeNameAndDebug(zoneSubSet, 0);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::Detail::zoneSubSet::correct()
{
subsetter_.clear();
haloCells_.clearStorage();
if (zoneMatcher_.empty())
{
return false;
}
// Select named zones
cellBitSet selectedCells
(
subsetter_.baseMesh(),
subsetter_.baseMesh().cellZones().selection(zoneMatcher_)
);
if (debug)
{
Pout<< "Subsetting "
<< selectedCells.addressing().count()
<< " cells based on cellZones "
<< flatOutput(zoneMatcher_) << endl;
}
if (nLayers_ > 0)
{
// Add halo layer(s)
haloToCell haloSource(subsetter_.baseMesh(), nLayers_);
haloSource.verbose(false);
// Before adding halo cells
haloCells_ = selectedCells.addressing();
haloSource.applyToSet(topoSetSource::ADD, selectedCells);
// Halo cells: anything new, not in the original set
haloCells_ ^= selectedCells.addressing();
}
if (debug)
{
const label nHalo = haloCells_.count();
const label nSubCell = selectedCells.addressing().count();
Info<< " overall "
<< returnReduce(nSubCell, sumOp<label>())
<< " cells after adding " << nLayers_ << " layers with "
<< returnReduce(nHalo, sumOp<label>())
<< " halo cells"
<< endl;
}
subsetter_.setCellSubset(selectedCells.addressing());
return true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::Detail::zoneSubSet::zoneSubSet
(
const fvMesh& mesh,
const wordRes& zoneSelector,
const label nZoneLayers
)
:
subsetter_(mesh),
zoneMatcher_(zoneSelector),
nLayers_(nZoneLayers),
haloCells_()
{
correct();
}
Foam::Detail::zoneSubSet::zoneSubSet
(
const fvMesh& mesh,
const dictionary& dict
)
:
subsetter_(mesh),
zoneMatcher_(),
nLayers_(dict.getOrDefault<label>("nLayers", 0)),
haloCells_()
{
dict.readIfPresent("cellZones", zoneMatcher_);
correct();
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
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::zoneSubSet
Description
Intermediate tool for handling \c cellZones
for function objects (e.g. \c momentumError)
wherein the sub-mesh option is available.
Usage
Minimal example by using \c system/controlDict.functions:
\verbatim
<functionObject>
{
// Mandatory and optional entries
...
// Inherited entries
cellZones ( <cellZone1> <cellZone2> ... <cellZoneN> );
nLayers <label>;
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Reqd | Deflt
cellZones | Names of cellZones | wordRes | no | -
nLayers | Number of cell layers around cellZones | label | no | 0
\endtable
See also
- Foam::functionObjects::momentumError
- Foam::functionObjects::div
SourceFiles
zoneSubSet.C
zoneSubSetTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef zoneSubSet_H
#define zoneSubSet_H
#include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class zoneSubSet Declaration
\*---------------------------------------------------------------------------*/
class zoneSubSet
{
// Private Data
//- Subsetting engine
fvMeshSubset subsetter_;
//- Matcher for zones
wordRes zoneMatcher_;
//- Number of layers around zones
label nLayers_;
//- The halo cells
bitSet haloCells_;
// Private Members Functions
//- Initialise the sub-mesh
bool correct();
//- No copy construct
zoneSubSet(const zoneSubSet&) = delete;
//- No copy assignment
void operator=(const zoneSubSet&) = delete;
public:
//- Runtime type information
TypeName("zoneSubSet");
// Constructors
//- Construct from components
zoneSubSet
(
const fvMesh& mesh,
const wordRes& zoneSelector,
const label nZoneLayers = 0
);
//- Construct from mesh and dictionary
zoneSubSet
(
const fvMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~zoneSubSet() = default;
// Member Functions
// Access
//- The entire base mesh
const fvMesh& baseMesh() const noexcept
{
return subsetter_.baseMesh();
}
//- The mesh subsetter
const fvMeshSubset& subsetter() const
{
return subsetter_;
}
//- The mesh subsetter
fvMeshSubset& subsetter()
{
return subsetter_;
}
//- True if sub-mesh is expected to be used
bool useSubMesh() const noexcept
{
return !zoneMatcher_.empty();
}
//- Return the current zones selector
const wordRes& zones() const noexcept
{
return zoneMatcher_;
}
//- Return number of layers around cell zones
label nLayers() const noexcept
{
return nLayers_;
}
// Fields
//- Map from the sub-mesh to original cell zones
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh>> mapToZone
(
const GeometricField<Type, fvPatchField, volMesh>& subVolField
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Detail
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "zoneSubSetTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
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 "volFieldsFwd.H"
// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>>
Foam::Detail::zoneSubSet::mapToZone
(
const GeometricField<Type, fvPatchField, volMesh>& subVolField
) const
{
typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
// The full-mesh field, with zero for non-zoned areas
auto tcellZonesField = volFieldType::New
(
subVolField.name(),
subsetter_.baseMesh(),
dimensioned<Type>(subVolField.dimensions())
);
auto& cellZonesField = tcellZonesField.ref();
// Map field in global mesh on original zones
// - without any halo cells
const labelList& cellMap = subsetter_.cellMap();
forAll(cellMap, subCelli)
{
const label celli = cellMap[subCelli];
if (!haloCells_.test(celli))
{
cellZonesField[celli] = subVolField[subCelli];
}
}
return tcellZonesField;
}
// ************************************************************************* //
......@@ -4,6 +4,7 @@ EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/surfMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
......@@ -27,6 +28,7 @@ LIB_LIBS = \
-lfileFormats \
-lsurfMesh \
-lmeshTools \
-ldynamicMesh \
-lsampling \
-llagrangian \
-ldistributionModels \
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -47,12 +47,26 @@ namespace functionObjects
bool Foam::functionObjects::div::calc()
{
bool processed = false;
return
(
calcDiv<surfaceScalarField>()
|| calcDiv<volVectorField>()
);
}
processed = processed || calcDiv<surfaceScalarField>();
processed = processed || calcDiv<volVectorField>();
return processed;
bool Foam::functionObjects::div::write()
{
if (zoneSubSetPtr_)
{
return
(
writeField<scalar>()
|| writeField<vector>()
);
}
return writeObject(resultName_);
}
......
......@@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2012-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
Copyright (C) 2020-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -53,15 +53,15 @@ Usage
// Mandatory (inherited) entry (runtime modifiable)
field \<field\>;
// Optional (inherited) entries
// Inherited entries
...
}
\endverbatim
where the entries mean:
\table
Property | Description | Type | Req'd | Dflt
type | Type name: add | word | yes | -
Property | Description | Type | Reqd | Deflt
type | Type name: div | word | yes | -
libs | Library name: fieldFunctionObjects | word | yes | -
field | Name of the operand field | word | yes | -
\endtable
......@@ -69,6 +69,7 @@ Usage
The inherited entries are elaborated in:
- \link functionObject.H \endlink
- \link fieldExpression.H \endlink
- \link zoneSubSet.H \endlink
Minimal example by using the \c postProcess utility:
\verbatim
......@@ -76,8 +77,10 @@ Usage