Commit c4079684 authored by Andrew Heather's avatar Andrew Heather
Browse files

Merge branch 'feature-momErrSubMesh' into 'develop'

ENH: Adding subMesh option to momentumError and div FOs

See merge request !463
parents 6595429f acd8e533
......@@ -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
\endverbatim