ENH: update polySurface and sampledSurfaces

- surfaceWriter TryNew() factory methods for more failure tolerant
  handling

- reduce communication for sampledSurfaces.
  Track non-empty surfaces as bool, only updated on change
  (expire/update).
This commit is contained in:
Mark Olesen
2024-02-14 14:22:48 +01:00
parent 8b85e5c932
commit ec3bca90fc
18 changed files with 539 additions and 291 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -36,12 +36,12 @@ Foam::polySurface* Foam::sampledSurface::getRegistrySurface
word lookupName
) const
{
if (lookupName.empty())
{
lookupName = this->name();
}
return obr.getObjectPtr<polySurface>(lookupName);
return
(
lookupName.empty()
? obr.getObjectPtr<polySurface>(this->name())
: obr.getObjectPtr<polySurface>(lookupName)
);
}
@ -56,15 +56,16 @@ Foam::polySurface* Foam::sampledSurface::storeRegistrySurface
lookupName = this->name();
}
polySurface* surfptr = getRegistrySurface(obr, lookupName);
auto* surfptr = obr.getObjectPtr<polySurface>(lookupName);
if (!surfptr)
{
// Default construct and add to registry (owned by registry)
surfptr = new polySurface(lookupName, obr, true);
surfptr = new polySurface(lookupName, obr);
regIOobject::store(surfptr);
}
surfptr->copySurface(*this); // Copy in geometry (removes old fields)
// Copy in geometry (removes existing fields if sizes have changed)
surfptr->copySurface(*this);
return surfptr;
}
@ -76,8 +77,12 @@ bool Foam::sampledSurface::removeRegistrySurface
word lookupName
) const
{
polySurface* surfptr = getRegistrySurface(obr, lookupName);
return obr.checkOut(surfptr);
return
(
lookupName.empty()
? polySurface::Delete(this->name(), obr)
: polySurface::Delete(lookupName, obr)
);
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd.
Copyright (C) 2016-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -57,41 +57,15 @@ Foam::scalar Foam::sampledSurfaces::mergeTol_ = 1e-10;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::polySurface* Foam::sampledSurfaces::getRegistrySurface
(
const sampledSurface& s
) const
{
return s.getRegistrySurface
(
storedObjects(),
IOobject::groupName(name(), s.name())
);
}
Foam::polySurface* Foam::sampledSurfaces::storeRegistrySurface
void Foam::sampledSurfaces::storeRegistrySurface
(
const sampledSurface& s
)
{
return s.storeRegistrySurface
s.storeRegistrySurface
(
storedObjects(),
IOobject::groupName(name(), s.name())
);
}
bool Foam::sampledSurfaces::removeRegistrySurface
(
const sampledSurface& s
)
{
return s.removeRegistrySurface
(
storedObjects(),
IOobject::groupName(name(), s.name())
IOobject::groupName(name(), s.name()) // surfaceName
);
}
@ -129,7 +103,7 @@ Foam::IOobjectList Foam::sampledSurfaces::preCheckFields()
{
if (!ListOps::found(allFields, fieldSelection_[i]))
{
missed.append(i);
missed.push_back(i);
}
}
@ -153,11 +127,11 @@ Foam::IOobjectList Foam::sampledSurfaces::preCheckFields()
const word& clsName = iter.key();
const label n = iter.val().size();
if (fieldTypes::volume.found(clsName))
if (fieldTypes::volume.contains(clsName))
{
nVolumeFields += n;
}
else if (fieldTypes::surface.found(clsName))
else if (fieldTypes::surface.contains(clsName))
{
nSurfaceFields += n;
}
@ -224,13 +198,7 @@ Foam::sampledSurfaces::sampledSurfaces
outputPath_
(
time_.globalPath()/functionObject::outputPrefix/name
),
fieldSelection_(),
sampleFaceScheme_(),
sampleNodeScheme_(),
writers_(),
actions_(),
nFaces_()
)
{
outputPath_.clean(); // Remove unneeded ".."
@ -254,13 +222,7 @@ Foam::sampledSurfaces::sampledSurfaces
outputPath_
(
time_.globalPath()/functionObject::outputPrefix/name
),
fieldSelection_(),
sampleFaceScheme_(),
sampleNodeScheme_(),
writers_(),
actions_(),
nFaces_()
)
{
outputPath_.clean(); // Remove unneeded ".."
@ -270,7 +232,7 @@ Foam::sampledSurfaces::sampledSurfaces
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::sampledSurfaces::verbose(const bool on) noexcept
bool Foam::sampledSurfaces::verbose(bool on) noexcept
{
bool old(verbose_);
verbose_ = on;
@ -285,7 +247,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
PtrList<sampledSurface>::clear();
writers_.clear();
actions_.clear();
nFaces_.clear();
hasFaces_.clear();
fieldSelection_.clear();
verbose_ = dict.getOrDefault("verbose", false);
@ -312,7 +274,6 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
actions_.resize(surfs.size(), ACTION_WRITE); // Default action
writers_.resize(surfs.size());
nFaces_.resize(surfs.size(), Zero);
label surfi = 0;
@ -385,7 +346,6 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
actions_.resize(surfs.size(), ACTION_WRITE); // Default action
writers_.resize(surfs.size());
nFaces_.resize(surfs.size(), Zero);
label surfi = 0;
@ -436,10 +396,11 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
// Have some surfaces, so sort out which fields are needed and report
hasFaces_.resize_nocopy(surfs.size());
hasFaces_ = false;
if (surfs.size())
{
nFaces_.resize(surfs.size(), Zero);
dict.readEntry("fields", fieldSelection_);
fieldSelection_.uniq();
@ -466,7 +427,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
Info<< nl;
}
if (debug && Pstream::master())
if (debug && UPstream::master())
{
Pout<< "sample fields:" << fieldSelection_ << nl
<< "sample surfaces:" << nl << '(' << nl;
@ -499,12 +460,15 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
if (s.update())
{
writers_[surfi].expire();
hasFaces_[surfi] = false;
}
nFaces_[surfi] = returnReduce(s.faces().size(), sumOp<label>());
ok = ok || nFaces_[surfi];
if (!hasFaces_[surfi])
{
hasFaces_[surfi] = returnReduceOr(s.faces().size());
}
ok = ok || hasFaces_[surfi];
// Store surfaces (even empty ones) otherwise we miss geometry
// updates.
@ -536,7 +500,7 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
{
const sampledSurface& s = (*this)[surfi];
if (((request & actions_[surfi]) & ACTION_WRITE) && nFaces_[surfi])
if (((request & actions_[surfi]) & ACTION_WRITE) && hasFaces_[surfi])
{
surfaceWriter& outWriter = writers_[surfi];
@ -589,7 +553,7 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
testAny
(
surfaces(),
[] (const sampledSurface& s) { return s.withSurfaceFields(); }
[](const sampledSurface& s) { return s.withSurfaceFields(); }
)
)
{
@ -604,7 +568,7 @@ bool Foam::sampledSurfaces::performAction(unsigned request)
// Finish this time step
forAll(writers_, surfi)
{
if (((request & actions_[surfi]) & ACTION_WRITE) && nFaces_[surfi])
if (((request & actions_[surfi]) & ACTION_WRITE) && hasFaces_[surfi])
{
// Write geometry if no fields were written so that we still
// can have something to look at
@ -688,7 +652,7 @@ bool Foam::sampledSurfaces::expire(const bool force)
// Dimension as fraction of mesh bounding box
const scalar mergeDim = mergeTol_ * mesh_.bounds().mag();
label nChanged = 0;
bool changed = false;
forAll(*this, surfi)
{
@ -701,16 +665,16 @@ bool Foam::sampledSurfaces::expire(const bool force)
}
if (s.expire())
{
++nChanged;
changed = true;
}
writers_[surfi].expire();
writers_[surfi].mergeDim(mergeDim);
nFaces_[surfi] = 0;
hasFaces_[surfi] = false;
}
// True if any surfaces just expired
return nChanged;
return changed;
}
@ -721,7 +685,7 @@ bool Foam::sampledSurfaces::update()
return false;
}
label nUpdated = 0;
bool changed = false;
forAll(*this, surfi)
{
@ -729,14 +693,13 @@ bool Foam::sampledSurfaces::update()
if (s.update())
{
++nUpdated;
changed = true;
writers_[surfi].expire();
hasFaces_[surfi] = returnReduceOr(s.faces().size());
}
nFaces_[surfi] = returnReduce(s.faces().size(), sumOp<label>());
}
return nUpdated;
return changed;
}
@ -746,9 +709,9 @@ Foam::scalar Foam::sampledSurfaces::mergeTol() noexcept
}
Foam::scalar Foam::sampledSurfaces::mergeTol(const scalar tol) noexcept
Foam::scalar Foam::sampledSurfaces::mergeTol(scalar tol) noexcept
{
const scalar old(mergeTol_);
scalar old(mergeTol_);
mergeTol_ = tol;
return old;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2022 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -205,8 +205,8 @@ class sampledSurfaces
//- Per-surface selection of store/write actions
List<unsigned> actions_;
//- Cached values of the global number of faces per-surface
labelList nFaces_;
//- Per-surface status of the surfaces
List<bool> hasFaces_;
// Private Member Functions
@ -266,21 +266,12 @@ class sampledSurfaces
);
//- Get surface from registry if available.
// \return surface or nullptr
polySurface* getRegistrySurface(const sampledSurface& s) const;
//- Put surface onto registry
void storeRegistrySurface(const sampledSurface& s);
//- Put surface onto registry, when enabled.
// \return surface or nullptr it surface should not be stored
polySurface* storeRegistrySurface(const sampledSurface& s);
//- Remove surface from registry.
// \return True if surface existed and was removed
bool removeRegistrySurface(const sampledSurface& s);
//- Store sampled field onto surface registry if it exists
//- Store sampled field onto surface registry (if surface exists)
template<class Type, class GeoMeshType>
bool storeRegistryField
void storeRegistryField
(
const sampledSurface& s,
const word& fieldName,
@ -288,7 +279,8 @@ class sampledSurfaces
Field<Type>&& values
);
//- Test surfaces for condition
//- Test surfaces for condition.
//- Like std::any_of() but without any iterator requirements
template<class Container, class Predicate>
static bool testAny(const Container& items, const Predicate& pred);
@ -347,7 +339,7 @@ public:
//- Enable/disable verbose output
// \return old value
bool verbose(const bool on) noexcept;
bool verbose(bool on) noexcept;
//- Return names of fields to sample
const wordRes& fieldNames() const noexcept { return fieldSelection_; }
@ -374,7 +366,7 @@ public:
static scalar mergeTol() noexcept;
//- Set merge tolerance and return old value
static scalar mergeTol(const scalar tol) noexcept;
static scalar mergeTol(scalar tol) noexcept;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -56,7 +56,7 @@ void Foam::sampledSurfaces::writeSurface
template<class Type, class GeoMeshType>
bool Foam::sampledSurfaces::storeRegistryField
void Foam::sampledSurfaces::storeRegistryField
(
const sampledSurface& s,
const word& fieldName,
@ -64,13 +64,13 @@ bool Foam::sampledSurfaces::storeRegistryField
Field<Type>&& values
)
{
return s.storeRegistryField<Type, GeoMeshType>
s.storeRegistryField<Type, GeoMeshType>
(
storedObjects(),
fieldName,
dims,
std::move(values),
IOobject::groupName(name(), s.name())
IOobject::groupName(name(), s.name()) // surfaceName
);
}
@ -94,13 +94,10 @@ void Foam::sampledSurfaces::performAction
forAll(*this, surfi)
{
const sampledSurface& s = operator[](surfi);
// Skip empty surfaces (eg, failed cut-plane)
if (!hasFaces_[surfi]) continue;
// Skip surface without faces (eg, failed cut-plane)
if (!nFaces_[surfi])
{
continue;
}
const sampledSurface& s = operator[](surfi);
Field<Type> values;
@ -170,13 +167,10 @@ void Foam::sampledSurfaces::performAction
forAll(*this, surfi)
{
const sampledSurface& s = (*this)[surfi];
// Skip empty surfaces (eg, failed cut-plane)
if (!hasFaces_[surfi]) continue;
// Skip surface without faces (eg, failed cut-plane)
if (!nFaces_[surfi])
{
continue;
}
const sampledSurface& s = (*this)[surfi];
Field<Type> values(s.sample(fld));

View File

@ -27,7 +27,7 @@ Class
Foam::polySurfaceGeoMesh
Description
The polySurface GeoMesh (for holding fields).
The polySurface GeoMesh for face fields.
\*---------------------------------------------------------------------------*/
@ -74,6 +74,13 @@ public:
{
return size(mesh_);
}
// FUTURE?
// //- Return the object registry for face fields
// const objectRegistry& thisDb() const
// {
// return mesh_.faceData();
// }
};

View File

@ -27,7 +27,7 @@ Class
Foam::polySurfacePointGeoMesh
Description
The polySurface GeoMesh (for holding point fields).
The polySurface GeoMesh for point fields.
\*---------------------------------------------------------------------------*/
@ -74,6 +74,13 @@ public:
{
return size(mesh_);
}
// FUTURE?
// //- Return the object registry for point fields
// const objectRegistry& thisDb() const
// {
// return mesh_.pointData();
// }
};

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,15 +52,12 @@ void Foam::polySurface::calculateZoneIds(const UList<surfZone>& zones)
// Extra safety, ensure we have at some zones
// and they cover all the faces - fix start silently
zoneIds_.resize(size(), Zero);
zoneIds_.resize_nocopy(size());
label off = 0;
for (const surfZone& zn : zones)
{
const label sz = zn.size();
SubList<label>(zoneIds_, sz, off) = zn.index();
SubList<label>(zoneIds_, zn.size(), off) = zn.index();
off += zn.size();
}
@ -69,7 +66,7 @@ void Foam::polySurface::calculateZoneIds(const UList<surfZone>& zones)
WarningInFunction
<< "More faces " << size() << " than zones " << off << endl;
SubList<label>(zoneIds_, size()-off, off) = zones.back().index();
zoneIds_.slice(off) = (zones.empty() ? 0 : zones.back().index());
}
else if (size() < off)
{
@ -96,8 +93,7 @@ Foam::polySurface::polySurface(const IOobject& io, bool doCheckIn)
IOobjectOption::REGISTER
)
),
MeshReference(faceList(), pointField()),
zoneIds_()
MeshReference(faceList(), pointField())
{
// Created without a point field sub-registry
@ -157,6 +153,36 @@ Foam::polySurface::polySurface
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::polySurface& Foam::polySurface::New
(
const word& surfName,
const objectRegistry& obr
)
{
auto* ptr = obr.getObjectPtr<polySurface>(surfName);
if (!ptr)
{
ptr = new polySurface(surfName, obr);
regIOobject::store(ptr);
}
return *ptr;
}
bool Foam::polySurface::Delete
(
const word& surfName,
const objectRegistry& obr
)
{
return obr.checkOut(obr.getObjectPtr<polySurface>(surfName));
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::polySurface::~polySurface()
@ -169,21 +195,19 @@ Foam::polySurface::~polySurface()
Foam::label Foam::polySurface::nFaceData() const
{
label count = objectRegistry::size();
// Remove PointData sub-registry from being included in the count
// Do not include sub-registry in the count
if (objectRegistry::foundObject<objectRegistry>(pointDataName))
{
--count;
return (objectRegistry::size() - 1);
}
return count;
return objectRegistry::size();
}
Foam::label Foam::polySurface::nPointData() const
{
const objectRegistry* subreg =
const auto* subreg =
objectRegistry::cfindObject<objectRegistry>(pointDataName);
if (subreg)
@ -213,11 +237,13 @@ Foam::polySurface::queryFieldAssociation(const word& fieldName) const
{
unsigned where(FieldAssociation::NO_DATA);
const objectRegistry* subreg = nullptr;
// Face Data
{
const objectRegistry* regptr = this;
subreg = this;
if (regptr && regptr->found(fieldName))
if (subreg && subreg->contains(fieldName))
{
where |= FieldAssociation::FACE_DATA;
}
@ -225,10 +251,9 @@ Foam::polySurface::queryFieldAssociation(const word& fieldName) const
// Point Data
{
const objectRegistry* regptr =
cfindObject<objectRegistry>(pointDataName);
subreg = cfindObject<objectRegistry>(pointDataName);
if (regptr && regptr->found(fieldName))
if (subreg && subreg->contains(fieldName))
{
where |= FieldAssociation::POINT_DATA;
}
@ -248,13 +273,14 @@ const Foam::regIOobject* Foam::polySurface::findFieldObject
const regIOobject* ioptr = nullptr;
const objectRegistry* subreg = nullptr;
// Face Data
if (where & FieldAssociation::FACE_DATA)
{
const objectRegistry* regptr = this;
subreg = this;
if (regptr && (ioptr = regptr->cfindObject<regIOobject>(fieldName)))
if (subreg && (ioptr = subreg->cfindObject<regIOobject>(fieldName)))
{
return ioptr;
}
@ -263,10 +289,9 @@ const Foam::regIOobject* Foam::polySurface::findFieldObject
// Point Data
if (where & FieldAssociation::POINT_DATA)
{
const objectRegistry* regptr =
cfindObject<objectRegistry>(pointDataName);
subreg = cfindObject<objectRegistry>(pointDataName);
if (regptr && (ioptr = regptr->cfindObject<regIOobject>(fieldName)))
if (subreg && (ioptr = subreg->cfindObject<regIOobject>(fieldName)))
{
return ioptr;
}
@ -466,7 +491,7 @@ const regIOobject* polySurface::findFieldObject<polySurfacePointGeoMesh>
{
// Point Data (sub-registry)
const objectRegistry* subreg =
const auto* subreg =
objectRegistry::cfindObject<objectRegistry>(pointDataName);
if (subreg)
@ -488,7 +513,7 @@ const objectRegistry* polySurface::whichRegistry<polySurfaceGeoMesh>
// Face Data (main registry)
const objectRegistry* subreg = this;
if (subreg->found(fieldName))
if (subreg->contains(fieldName))
{
return subreg;
}
@ -505,10 +530,10 @@ const objectRegistry* polySurface::whichRegistry<polySurfacePointGeoMesh>
{
// Point Data (sub registry)
const objectRegistry* subreg =
const auto* subreg =
objectRegistry::cfindObject<objectRegistry>(pointDataName);
if (subreg && subreg->found(fieldName))
if (subreg && subreg->contains(fieldName))
{
return subreg;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -87,7 +87,8 @@ private:
// Private Typedefs
//- Internal mesh storage type
typedef PrimitivePatch<::Foam::List<face>, pointField>
typedef
PrimitivePatch<::Foam::List<face>, pointField>
MeshReference;
@ -102,12 +103,6 @@ private:
//- Calculate per-face zone/region information
void calculateZoneIds(const UList<surfZone>& zones);
//- No copy construct
polySurface(const polySurface&) = delete;
//- No copy assignment
void operator=(const polySurface&) = delete;
protected:
@ -122,7 +117,11 @@ protected:
//- Non-const access to the faces
faceList& storedFaces()
{
return static_cast<faceList&>(static_cast<MeshReference&>(*this));
return
static_cast<faceList&>
(
static_cast<MeshReference&>(*this)
);
}
//- Const access to the faces
@ -154,14 +153,23 @@ public:
TypeName("polySurface");
// Generated Methods
//- No copy construct
polySurface(const polySurface&) = delete;
//- No copy assignment
void operator=(const polySurface&) = delete;
// Constructors
//- Construct null with NO_READ, NO_WRITE
//- Default construct with NO_READ, NO_WRITE
//- optionally with a checkIn on the parent registry.
// Created without a PointData sub-registry
explicit polySurface(const IOobject& io, bool doCheckIn = false);
//- Construct null with specified name on the given registry,
//- Default construct with specified name on the given registry,
//- optionally with a checkIn on the parent registry.
// Created without a PointData sub-registry
polySurface
@ -198,6 +206,15 @@ public:
virtual ~polySurface();
// Factory Methods
//- Get or create (NO_READ, NO_WRITE) named surface on registry
static polySurface& New(const word& surfName, const objectRegistry&);
//- Remove named surface from specified registry
static bool Delete(const word& surfName, const objectRegistry&);
// Member Functions
// Resolve iterator ambiguity in favour of Patch (not registry)
@ -268,30 +285,36 @@ public:
// Modification
//- Update with new contents
//- Update with new contents.
//- Removes existing fields if sizes have changed
void copySurface
(
const pointField& points,
const faceList& faces,
//! validate the zone coverage (ignored)
bool unused=false
);
//- Update with new contents
//- Update with new contents.
//- Removes existing fields if sizes have changed
void copySurface
(
const meshedSurf& surf,
//! validate the zone coverage (ignored)
bool unused=false
);
//- Update with new contents
//- Update with new contents.
//- Removes existing fields if sizes have changed
void copySurface
(
const MeshedSurface<face>& surf,
//! validate the zone coverage (ignored)
bool unused=false
);
//- Transfer the contents of the argument and annul the argument
// Optionally validate the zone coverage.
//- Transfer the contents (and annul the parameters).
//- Removes existing fields.
void transfer
(
pointField&& points,
@ -299,11 +322,12 @@ public:
labelList&& zoneIds = labelList()
);
//- Transfer the contents of the argument and annul the argument
// Optionally validate the zone coverage.
//- Transfer the contents (and annul the parameters).
//- Removes existing fields.
void transfer
(
MeshedSurface<face>& surf,
//! validate the zone coverage
bool validate=false
);
@ -353,19 +377,37 @@ public:
const objectRegistry& faceData() const;
//- Point data are stored in a sub-registry
// Note that this method with automatically create the corresponding
// Note that this method will automatically create the corresponding
// sub-registry if it did not previously exist.
// Use the nPointData() methods instead if you wish to test for
// content without this side-effect.
const objectRegistry& pointData() const;
//- Create/store named zero field as face or point data
//- (template parameter).
//
// - Default is face-data (polySurfaceGeoMesh as template).
// - For point-data use polySurfacePointGeoMesh as template.
//
// \return reference to the field
template<class Type, class GeoMeshType = polySurfaceGeoMesh>
DimensionedField<Type, GeoMeshType>&
newField
(
const word& fieldName,
const dimensionSet& dims
);
//- Copy/store named field as face or point data (template parameter).
//
// Default is face-data (polySurfaceGeoMesh as template).
// For point data use (polySurfacePointGeoMesh as template).
// - Default is face-data (polySurfaceGeoMesh as template).
// - For point-data use polySurfacePointGeoMesh as template.
//
// \return reference to the field
template<class Type, class GeoMeshType = polySurfaceGeoMesh>
void storeField
DimensionedField<Type, GeoMeshType>&
storeField
(
const word& fieldName,
const dimensionSet& dims,
@ -374,10 +416,13 @@ public:
//- Move/store named field as face or point data (template parameter).
//
// Default is face-data (polySurfaceGeoMesh as template).
// For point data use (polySurfacePointGeoMesh as template).
// - Default is face-data (polySurfaceGeoMesh as template).
// - For point-data use polySurfacePointGeoMesh as template.
//
// \return reference to the field
template<class Type, class GeoMeshType = polySurfaceGeoMesh>
void storeField
DimensionedField<Type, GeoMeshType>&
storeField
(
const word& fieldName,
const dimensionSet& dims,

View File

@ -26,7 +26,6 @@ License
\*---------------------------------------------------------------------------*/
#include "polySurface.H"
#include "globalMeshData.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -49,7 +49,7 @@ const Foam::regIOobject* Foam::polySurface::findFieldObject
forAllConstIters(obr, iter)
{
const objectRegistry* subreg = isA<objectRegistry>(iter.val());
const auto* subreg = isA<objectRegistry>(iter.val());
if (subreg && (ioptr = subreg->cfindObject<regIOobject>(fieldName)))
{
@ -71,16 +71,16 @@ const Foam::objectRegistry* Foam::polySurface::whichRegistry
const objectRegistry& obr = *this;
if (obr.found(fieldName))
if (obr.contains(fieldName))
{
return this;
}
forAllConstIters(obr, iter)
{
const objectRegistry* subreg = isA<objectRegistry>(iter.val());
const auto* subreg = isA<objectRegistry>(iter.val());
if (subreg && subreg->found(fieldName))
if (subreg && subreg->contains(fieldName))
{
return subreg;
}
@ -91,32 +91,76 @@ const Foam::objectRegistry* Foam::polySurface::whichRegistry
template<class Type, class GeoMeshType>
void Foam::polySurface::storeField
Foam::DimensionedField<Type, GeoMeshType>&
Foam::polySurface::newField
(
const word& fieldName,
const dimensionSet& dims
)
{
typedef DimensionedField<Type, GeoMeshType> fieldType;
// Force creates field database if needed.
const objectRegistry& fieldDb = this->fieldData<GeoMeshType>();
auto* fldptr = fieldDb.getObjectPtr<fieldType>(fieldName);
if (fldptr)
{
fldptr->dimensions().reset(dims); // Dimensions may have changed
fldptr->field() = Foam::zero{};
}
else
{
fldptr = new fieldType
(
fieldDb.newIOobject
(
fieldName,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
),
*this,
Foam::zero{},
dims
);
regIOobject::store(fldptr);
}
return *fldptr;
}
template<class Type, class GeoMeshType>
Foam::DimensionedField<Type, GeoMeshType>&
Foam::polySurface::storeField
(
const word& fieldName,
const dimensionSet& dims,
const Field<Type>& values
)
{
typedef DimensionedField<Type, GeoMeshType> fieldType;
// Force creates field database if needed.
const objectRegistry& fieldDb = this->fieldData<GeoMeshType>();
auto* dimfield =
fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
auto* fldptr = fieldDb.getObjectPtr<fieldType>(fieldName);
if (dimfield)
if (fldptr)
{
dimfield->dimensions().reset(dims); // Dimensions may have changed
dimfield->field() = values;
fldptr->dimensions().reset(dims); // Dimensions may have changed
fldptr->field() = values;
}
else
{
dimfield = new DimensionedField<Type, GeoMeshType>
fldptr = new fieldType
(
IOobject
fieldDb.newIOobject
(
fieldName,
fieldDb,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
@ -126,38 +170,41 @@ void Foam::polySurface::storeField
values
);
dimfield->store();
regIOobject::store(fldptr);
}
return *fldptr;
}
template<class Type, class GeoMeshType>
void Foam::polySurface::storeField
Foam::DimensionedField<Type, GeoMeshType>&
Foam::polySurface::storeField
(
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values
)
{
typedef DimensionedField<Type, GeoMeshType> fieldType;
// Force creates field database if needed.
const objectRegistry& fieldDb = this->fieldData<GeoMeshType>();
auto* dimfield =
fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
auto* fldptr = fieldDb.getObjectPtr<fieldType>(fieldName);
if (dimfield)
if (fldptr)
{
dimfield->dimensions().reset(dims); // Dimensions may have changed
dimfield->field() = std::move(values);
fldptr->dimensions().reset(dims); // Dimensions may have changed
fldptr->field() = std::move(values);
}
else
{
dimfield = new DimensionedField<Type, GeoMeshType>
fldptr = new fieldType
(
IOobject
fieldDb.newIOobject
(
fieldName,
fieldDb,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
@ -167,8 +214,10 @@ void Foam::polySurface::storeField
std::move(values)
);
dimfield->store();
regIOobject::store(fldptr);
}
return *fldptr;
}

View File

@ -28,7 +28,7 @@ Class
Foam::surfGeoMesh
Description
The surfMesh GeoMesh (for holding fields).
The surfMesh GeoMesh for face fields.
\*---------------------------------------------------------------------------*/

View File

@ -28,7 +28,7 @@ Class
Foam::surfPointGeoMesh
Description
The surfMesh GeoMesh (for holding fields).
The surfMesh GeoMesh for point fields.
Similar to surfGeoMesh, but refers to the surface points.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2022 OpenCFD Ltd.
Copyright (C) 2016-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,6 +31,9 @@ Description
A surface mesh consisting of general polygon faces that has
IO capabilities and a registry for storing fields.
Note
In many places the Foam::polySurface class may be more flexible.
SourceFiles
surfMesh.C
surfMeshClear.C
@ -88,10 +91,13 @@ private:
// Private Typedefs
//- Memory and IO management
typedef Detail::MeshedSurfaceIOAllocator Allocator;
typedef
Detail::MeshedSurfaceIOAllocator
Allocator;
//- Internal mesh storage type
typedef PrimitivePatch<::Foam::UList<face>, const pointField&>
typedef
PrimitivePatch<::Foam::UList<face>, const pointField&>
MeshReference;
@ -101,15 +107,6 @@ private:
surfZoneIOList surfZones_;
// Private Member Functions
//- No copy construct
surfMesh(const surfMesh&) = delete;
//- No copy assignment
void operator=(const surfMesh&) = delete;
protected:
// Protected Member Functions
@ -154,6 +151,15 @@ public:
static word meshSubDir;
// Generated Methods
//- No copy construct
surfMesh(const surfMesh&) = delete;
//- No copy assignment
void operator=(const surfMesh&) = delete;
// Constructors
//- Read construct from IOobject.
@ -164,7 +170,7 @@ public:
// Writing = NO_WRITE
surfMesh(const IOobject& io, const word& surfName);
//- Construct null with specified name on the given registry.
//- Construct empty with specified name on the given registry.
surfMesh(const word& surfName, const objectRegistry& obr);
//- Copy construct from MeshedSurface<face>
@ -301,7 +307,11 @@ public:
//- Transfer the contents of the argument and annul the argument
// Optionally validate the zone coverage.
void transfer(MeshedSurface<face>& surf, bool validate=false);
void transfer
(
MeshedSurface<face>& surf,
bool validate=false
);
//- Update mesh based on the files saved in time directories
virtual readUpdateState readUpdate();
@ -309,11 +319,30 @@ public:
// Fields
//- Create/store named zero field as face or point data
//- (template parameter).
//
// - Default is face-data (surfGeoMesh as template).
// - For point-data use surfPointGeoMesh as template.
//
// \return reference to the field
template<class Type, class GeoMeshType = surfGeoMesh>
DimensionedField<Type, GeoMeshType>&
newField
(
const word& fieldName,
const dimensionSet& dims
);
//- Copy/store named field as face or point data (template parameter).
//
// Default is face-data (surfGeoMesh as template).
// - Default is face-data (surfGeoMesh as template).
// - For point-data use surfPointGeoMesh as template.
//
// \return reference to the field
template<class Type, class GeoMeshType = surfGeoMesh>
void storeField
DimensionedField<Type, GeoMeshType>&
storeField
(
const word& fieldName,
const dimensionSet& dims,
@ -322,9 +351,13 @@ public:
//- Move/store named field as face or point data (template parameter).
//
// Default is face-data (surfGeoMesh as template).
// - Default is face-data (surfGeoMesh as template).
// - For point-data use surfPointGeoMesh as template.
//
// \return reference to the field
template<class Type, class GeoMeshType = surfGeoMesh>
void storeField
DimensionedField<Type, GeoMeshType>&
storeField
(
const word& fieldName,
const dimensionSet& dims,

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,31 +31,74 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, class GeoMeshType>
void Foam::surfMesh::storeField
Foam::DimensionedField<Type, GeoMeshType>&
Foam::surfMesh::newField
(
const word& fieldName,
const dimensionSet& dims
)
{
typedef DimensionedField<Type, GeoMeshType> fieldType;
const objectRegistry& fieldDb = *this;
auto* fldptr = fieldDb.getObjectPtr<fieldType>(fieldName);
if (fldptr)
{
fldptr->dimensions().reset(dims); // Dimensions may have changed
fldptr->field() = Foam::zero{};
}
else
{
fldptr = new fieldType
(
fieldDb.newIOobject
(
fieldName,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
),
*this,
Foam::zero{},
dims
);
regIOobject::store(fldptr);
}
return *fldptr;
}
template<class Type, class GeoMeshType>
Foam::DimensionedField<Type, GeoMeshType>&
Foam::surfMesh::storeField
(
const word& fieldName,
const dimensionSet& dims,
const Field<Type>& values
)
{
typedef DimensionedField<Type, GeoMeshType> fieldType;
const objectRegistry& fieldDb = *this;
auto* dimfield =
fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
auto* fldptr = fieldDb.getObjectPtr<fieldType>(fieldName);
if (dimfield)
if (fldptr)
{
dimfield->dimensions().reset(dims); // Dimensions may have changed
dimfield->field() = values;
fldptr->dimensions().reset(dims); // Dimensions may have changed
fldptr->field() = values;
}
else
{
dimfield = new DimensionedField<Type, GeoMeshType>
fldptr = new fieldType
(
IOobject
fieldDb.newIOobject
(
fieldName,
fieldDb,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
@ -65,37 +108,40 @@ void Foam::surfMesh::storeField
values
);
dimfield->store();
regIOobject::store(fldptr);
}
return *fldptr;
}
template<class Type, class GeoMeshType>
void Foam::surfMesh::storeField
Foam::DimensionedField<Type, GeoMeshType>&
Foam::surfMesh::storeField
(
const word& fieldName,
const dimensionSet& dims,
Field<Type>&& values
)
{
typedef DimensionedField<Type, GeoMeshType> fieldType;
const objectRegistry& fieldDb = *this;
auto* dimfield =
fieldDb.getObjectPtr<DimensionedField<Type, GeoMeshType>>(fieldName);
auto* fldptr = fieldDb.getObjectPtr<fieldType>(fieldName);
if (dimfield)
if (fldptr)
{
dimfield->dimensions().reset(dims); // Dimensions may have changed
dimfield->field() = std::move(values);
fldptr->dimensions().reset(dims); // Dimensions may have changed
fldptr->field() = std::move(values);
}
else
{
dimfield = new DimensionedField<Type, GeoMeshType>
fldptr = new fieldType
(
IOobject
fieldDb.newIOobject
(
fieldName,
fieldDb,
IOobjectOption::NO_READ,
IOobjectOption::NO_WRITE,
IOobjectOption::REGISTER
@ -105,8 +151,10 @@ void Foam::surfMesh::storeField
std::move(values)
);
dimfield->store();
regIOobject::store(fldptr);
}
return *fldptr;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2022 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -83,33 +83,76 @@ Foam::dictionary Foam::surfaceWriter::formatOptions
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::TryNew(const word& writeType)
{
// Without dictionary options
{
auto* ctorPtr = wordConstructorTable(writeType);
if (ctorPtr)
{
return autoPtr<surfaceWriter>(ctorPtr());
}
}
// Fallback to proxy writer...
return surfaceWriters::proxyWriter::TryNew(writeType);
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::TryNew
(
const word& writeType,
const dictionary& writeOpts
)
{
// With dictionary options
{
auto* ctorPtr = wordDictConstructorTable(writeType);
if (ctorPtr)
{
return autoPtr<surfaceWriter>(ctorPtr(writeOpts));
}
}
// Without dictionary options
{
auto* ctorPtr = wordConstructorTable(writeType);
if (ctorPtr)
{
return autoPtr<surfaceWriter>(ctorPtr());
}
}
// Fallback to proxy writer...
return surfaceWriters::proxyWriter::TryNew(writeType, writeOpts);
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New(const word& writeType)
{
// Constructors without dictionary options
auto* ctorPtr = wordConstructorTable(writeType);
autoPtr<surfaceWriter> writer
(
surfaceWriter::TryNew(writeType)
);
if (!ctorPtr)
if (!writer)
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Generally unknown, but handle via 'proxy' handler
return autoPtr<surfaceWriter>
(
new surfaceWriters::proxyWriter(writeType)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid write types : "
<< flatOutput(wordConstructorTablePtr_->sortedToc()) << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< flatOutput(MeshedSurfaceProxy<face>::writeTypes()) << endl
<< exit(FatalError);
}
return autoPtr<surfaceWriter>(ctorPtr());
return writer;
}
@ -120,41 +163,23 @@ Foam::surfaceWriter::New
const dictionary& writeOpts
)
{
// Constructors with dictionary options
autoPtr<surfaceWriter> writer
(
surfaceWriter::TryNew(writeType, writeOpts)
);
if (!writer)
{
auto* ctorPtr = wordDictConstructorTable(writeType);
if (ctorPtr)
{
return autoPtr<surfaceWriter>(ctorPtr(writeOpts));
}
}
// Constructors without dictionary options
auto* ctorPtr = wordConstructorTable(writeType);
if (!ctorPtr)
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Generally unknown, but handle via 'proxy' handler
return autoPtr<surfaceWriter>
(
new surfaceWriters::proxyWriter(writeType, writeOpts)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid write types : "
<< wordConstructorTablePtr_->sortedToc() << nl
<< flatOutput(wordConstructorTablePtr_->sortedToc()) << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< flatOutput(MeshedSurfaceProxy<face>::writeTypes()) << endl
<< exit(FatalError);
}
return autoPtr<surfaceWriter>(ctorPtr());
return writer;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2012 OpenFOAM Foundation
Copyright (C) 2015-2022 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -326,16 +326,27 @@ public:
);
// Selectors
// Factory Methods / Selectors
//- True if New is likely to succeed for this writeType
static bool supportedType(const word& writeType);
//- Return a reference to the selected surfaceWriter
//- Optional select construct surfaceWriter.
// Return nullptr if the specified type is not supported.
static autoPtr<surfaceWriter> TryNew(const word& writeType);
//- Optional select construct surfaceWriter with extra write options.
// Return nullptr if the specified type is not supported.
static autoPtr<surfaceWriter> TryNew
(
const word& writeType,
const dictionary& writeOptions
);
//- Select construct a surfaceWriter
static autoPtr<surfaceWriter> New(const word& writeType);
//- Return a reference to the selected surfaceWriter
// Select with extra write option
//- Select construct a surfaceWriter with extra write options.
static autoPtr<surfaceWriter> New
(
const word& writeType,

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2015-2020 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -98,6 +98,36 @@ Foam::surfaceWriters::proxyWriter::proxyWriter
}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriters::proxyWriter::TryNew(const word& writeType)
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
return autoPtr<surfaceWriter>(new proxyWriter(writeType));
}
return nullptr;
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriters::proxyWriter::TryNew
(
const word& writeType,
const dictionary& writeOpts
)
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
return autoPtr<surfaceWriter>(new proxyWriter(writeType, writeOpts));
}
return nullptr;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::fileName Foam::surfaceWriters::proxyWriter::write()

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2015-2022 OpenCFD Ltd.
Copyright (C) 2015-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -131,6 +131,21 @@ public:
virtual ~proxyWriter() = default;
// Factory Methods
//- Optional select construct proxy writer.
// Return nullptr if the specified type is not supported.
static autoPtr<surfaceWriter> TryNew(const word& writeType);
//- Optional select construct proxy writer with extra write options.
// Return nullptr if the specified type is not supported.
static autoPtr<surfaceWriter> TryNew
(
const word& writeType,
const dictionary& writeOptions
);
// Member Functions
//- A separate file is required for geometry.