mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support creation of boundaries/zones from list of entries
- this makes it easier to split creation into a two-stage process as required - extend handling for polyBoundaryMeshEntries, faBoundaryMeshEntries with more functionality. Ensure that these are never registered. ENH: addition writeEntry methods for polyBoundaryMesh - simplifies streaming and collating into other files ENH: polyMesh rereading - update owner/neighbour header information - this avoids accidentally reading the "cells" file if the mesh has been created with NO_READ and then updated STYLE: less vertical space when outputting empty PtrList
This commit is contained in:
3
applications/test/boundaryMeshEntries/Make/files
Normal file
3
applications/test/boundaryMeshEntries/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-boundaryMeshEntries.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-boundaryMeshEntries
|
||||
2
applications/test/boundaryMeshEntries/Make/options
Normal file
2
applications/test/boundaryMeshEntries/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
146
applications/test/boundaryMeshEntries/Test-boundaryMeshEntries.C
Normal file
146
applications/test/boundaryMeshEntries/Test-boundaryMeshEntries.C
Normal file
@ -0,0 +1,146 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2023 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/>.
|
||||
|
||||
Application
|
||||
Test-boundaryMeshEntries
|
||||
|
||||
Description
|
||||
Find and print "boundary" information
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
|
||||
#include "fileName.H"
|
||||
#include "IOstreams.H"
|
||||
#include "polyMesh.H"
|
||||
#include "polyBoundaryMeshEntries.H"
|
||||
#include "OSspecific.H"
|
||||
#include "Time.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noFunctionObjects(); // Disallow function objects
|
||||
argList::addVerboseOption("additional verbosity");
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
fileName coherentInst;
|
||||
coherentInst =
|
||||
(
|
||||
runTime.findInstance
|
||||
(
|
||||
polyMesh::meshSubDir,
|
||||
"coherent",
|
||||
IOobject::READ_IF_PRESENT
|
||||
)
|
||||
);
|
||||
|
||||
// Unfortunately with READ_IF_PRESENT, cannot tell if the file
|
||||
// was actually found or not
|
||||
|
||||
Info<< "check: " << (coherentInst/polyMesh::meshSubDir/"coherent") << nl;
|
||||
|
||||
if (!Foam::isFile(coherentInst/polyMesh::meshSubDir/"coherent"))
|
||||
{
|
||||
coherentInst.clear();
|
||||
}
|
||||
|
||||
Info<< "found coherent: " << coherentInst << nl;
|
||||
|
||||
PtrList<entry> entries;
|
||||
|
||||
if (!coherentInst.empty())
|
||||
{
|
||||
IOdictionary coherent
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"coherent",
|
||||
coherentInst,
|
||||
polyMesh::meshSubDir,
|
||||
runTime,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
);
|
||||
|
||||
ITstream& is = coherent.lookup("boundary");
|
||||
is >> entries;
|
||||
}
|
||||
|
||||
Info<< "entries: " << entries << nl;
|
||||
|
||||
Info<< "type: " << polyBoundaryMeshEntries::types(entries) << nl;
|
||||
Info<< "start: " << polyBoundaryMeshEntries::patchStarts(entries) << nl;
|
||||
Info<< "size: " << polyBoundaryMeshEntries::patchSizes(entries) << nl;
|
||||
Info<< nl;
|
||||
|
||||
fileName boundaryInst;
|
||||
boundaryInst =
|
||||
(
|
||||
runTime.findInstance
|
||||
(
|
||||
polyMesh::meshSubDir,
|
||||
"boundary",
|
||||
IOobject::MUST_READ
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "found boundary: " << boundaryInst << nl;
|
||||
|
||||
polyBoundaryMeshEntries pbm
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boundary",
|
||||
boundaryInst,
|
||||
polyMesh::meshSubDir,
|
||||
runTime,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "type: " << flatOutput(pbm.types()) << nl;
|
||||
Info<< "start: " << flatOutput(pbm.patchStarts()) << nl;
|
||||
Info<< "size: " << flatOutput(pbm.patchSizes()) << nl;
|
||||
|
||||
pbm.writeEntry("boundary", Info);
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -40,8 +40,19 @@ Foam::Ostream& Foam::Detail::PtrListDetail<T>::write
|
||||
{
|
||||
const label len = this->size();
|
||||
|
||||
// The net length (after trimming any nullptr)
|
||||
const label netLen = (trimNull ? this->count() : len);
|
||||
|
||||
if (!netLen)
|
||||
{
|
||||
// 0-sized : can write with less vertical space
|
||||
os << nl << indent << netLen
|
||||
<< token::BEGIN_LIST << token::END_LIST << nl;
|
||||
return os;
|
||||
}
|
||||
|
||||
// The (output) size and start delimiter
|
||||
os << nl << indent << (trimNull ? this->count() : len) << nl
|
||||
os << nl << indent << netLen << nl
|
||||
<< indent << token::BEGIN_LIST << incrIndent << nl;
|
||||
|
||||
// Contents
|
||||
|
||||
@ -105,8 +105,40 @@ void Foam::polyBoundaryMesh::calcGroupIDs() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyBoundaryMesh::populate(PtrList<entry>&& entries)
|
||||
{
|
||||
clearLocalAddressing();
|
||||
|
||||
polyPatchList& patches = *this;
|
||||
|
||||
patches.resize_null(entries.size());
|
||||
|
||||
// Transcribe.
|
||||
// Does not handle nullptr at all (what could possibly be done?)
|
||||
forAll(patches, patchi)
|
||||
{
|
||||
patches.set
|
||||
(
|
||||
patchi,
|
||||
polyPatch::New
|
||||
(
|
||||
entries[patchi].keyword(),
|
||||
entries[patchi].dict(),
|
||||
patchi,
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::polyBoundaryMesh::readContents(const bool allowOptionalRead)
|
||||
{
|
||||
bool updated = false;
|
||||
PtrList<entry> entries;
|
||||
|
||||
if
|
||||
(
|
||||
this->isReadRequired()
|
||||
@ -116,37 +148,23 @@ bool Foam::polyBoundaryMesh::readContents(const bool allowOptionalRead)
|
||||
// Warn for MUST_READ_IF_MODIFIED
|
||||
warnNoRereading<polyBoundaryMesh>();
|
||||
|
||||
polyPatchList& patches = *this;
|
||||
|
||||
// Read entries
|
||||
Istream& is = readStream(typeName);
|
||||
|
||||
PtrList<entry> entries(is);
|
||||
patches.resize_null(entries.size());
|
||||
|
||||
// Transcribe
|
||||
forAll(patches, patchi)
|
||||
{
|
||||
patches.set
|
||||
(
|
||||
patchi,
|
||||
polyPatch::New
|
||||
(
|
||||
entries[patchi].keyword(),
|
||||
entries[patchi].dict(),
|
||||
patchi,
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
is >> entries;
|
||||
|
||||
is.check(FUNCTION_NAME);
|
||||
close();
|
||||
return true;
|
||||
updated = true;
|
||||
}
|
||||
// Future: support master-only and broadcast?
|
||||
|
||||
if (updated)
|
||||
{
|
||||
populate(std::move(entries));
|
||||
}
|
||||
|
||||
// Nothing read
|
||||
return false;
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
@ -217,6 +235,25 @@ Foam::polyBoundaryMesh::polyBoundaryMesh
|
||||
}
|
||||
|
||||
|
||||
Foam::polyBoundaryMesh::polyBoundaryMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const polyMesh& pm,
|
||||
PtrList<entry>&& entries
|
||||
)
|
||||
:
|
||||
polyPatchList(),
|
||||
regIOobject(io),
|
||||
mesh_(pm)
|
||||
{
|
||||
if (!readContents(true)) // allowOptionalRead = true
|
||||
{
|
||||
populate(std::move(entries));
|
||||
}
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::polyBoundaryMesh::clear()
|
||||
@ -237,11 +274,18 @@ void Foam::polyBoundaryMesh::clearGeom()
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyBoundaryMesh::clearAddressing()
|
||||
// Private until it is more generally required (and gets a better name?)
|
||||
void Foam::polyBoundaryMesh::clearLocalAddressing()
|
||||
{
|
||||
neighbourEdgesPtr_.reset(nullptr);
|
||||
patchIDPtr_.reset(nullptr);
|
||||
groupIDsPtr_.reset(nullptr);
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyBoundaryMesh::clearAddressing()
|
||||
{
|
||||
clearLocalAddressing();
|
||||
|
||||
polyPatchList& patches = *this;
|
||||
|
||||
@ -1367,22 +1411,56 @@ void Foam::polyBoundaryMesh::reorder
|
||||
}
|
||||
|
||||
|
||||
bool Foam::polyBoundaryMesh::writeData(Ostream& os) const
|
||||
void Foam::polyBoundaryMesh::writeEntry(Ostream& os) const
|
||||
{
|
||||
const polyPatchList& patches = *this;
|
||||
const polyPatchList& entries = *this;
|
||||
|
||||
os << patches.size() << nl << token::BEGIN_LIST << incrIndent << nl;
|
||||
os << entries.size();
|
||||
|
||||
for (const polyPatch& pp : patches)
|
||||
if (entries.empty())
|
||||
{
|
||||
os.beginBlock(pp.name());
|
||||
os << pp;
|
||||
os.endBlock();
|
||||
// 0-sized : can write with less vertical space
|
||||
os << token::BEGIN_LIST << token::END_LIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << nl << token::BEGIN_LIST << incrIndent << nl;
|
||||
|
||||
for (const auto& pp : entries)
|
||||
{
|
||||
os.beginBlock(pp.name());
|
||||
os << pp;
|
||||
os.endBlock();
|
||||
}
|
||||
os << decrIndent << token::END_LIST;
|
||||
}
|
||||
os.check(FUNCTION_NAME);
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyBoundaryMesh::writeEntry
|
||||
(
|
||||
const keyType& keyword,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
const polyPatchList& entries = *this;
|
||||
|
||||
if (!keyword.empty())
|
||||
{
|
||||
os.write(keyword);
|
||||
os << (entries.empty() ? token::SPACE : token::NL);
|
||||
}
|
||||
|
||||
os << decrIndent << token::END_LIST;
|
||||
writeEntry(os);
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
if (!keyword.empty()) os.endEntry();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::polyBoundaryMesh::writeData(Ostream& os) const
|
||||
{
|
||||
writeEntry(os);
|
||||
return os.good();
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,7 @@ Description
|
||||
|
||||
SourceFiles
|
||||
polyBoundaryMesh.C
|
||||
polyBoundaryMeshTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -50,6 +51,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class entry;
|
||||
class polyMesh;
|
||||
class wordRe;
|
||||
class wordRes;
|
||||
@ -91,6 +93,12 @@ class polyBoundaryMesh
|
||||
//- Calculate group name to patch ids lookup
|
||||
void calcGroupIDs() const;
|
||||
|
||||
//- Clear addressing at this level
|
||||
void clearLocalAddressing();
|
||||
|
||||
//- Populate/recreate from dictionary entries
|
||||
void populate(PtrList<entry>&& entries);
|
||||
|
||||
//- Return true if contents were read
|
||||
//- (controlled by IOobject readOption flags).
|
||||
bool readContents(const bool allowOptionalRead);
|
||||
@ -149,6 +157,15 @@ public:
|
||||
const polyPatchList& list
|
||||
);
|
||||
|
||||
//- Read construct (mandatory, optional) based on IOobject properties
|
||||
//- or fallback to constructing from a list of dictionary entries
|
||||
polyBoundaryMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const polyMesh& mesh,
|
||||
PtrList<entry>&& entries
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~polyBoundaryMesh() = default;
|
||||
@ -354,14 +371,24 @@ public:
|
||||
// sync in that case)
|
||||
void reorder(const labelUList& oldToNew, const bool validBoundary);
|
||||
|
||||
//- writeData member function required by regIOobject
|
||||
|
||||
// Write
|
||||
|
||||
//- Write as a plain list of entries
|
||||
void writeEntry(Ostream& os) const;
|
||||
|
||||
//- Write as a primitive entry with given name.
|
||||
//- If the keyword is empty, revert to a plain list.
|
||||
void writeEntry(const keyType& keyword, Ostream& os) const;
|
||||
|
||||
//- The writeData member function required by regIOobject
|
||||
virtual bool writeData(Ostream& os) const;
|
||||
|
||||
//- Write using stream options
|
||||
//- Write using stream options, but always UNCOMPRESSED
|
||||
virtual bool writeObject
|
||||
(
|
||||
IOstreamOption streamOpt,
|
||||
const bool writeOnProc
|
||||
const bool writeOnProc = true
|
||||
) const;
|
||||
|
||||
|
||||
|
||||
@ -37,12 +37,72 @@ namespace Foam
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::polyBoundaryMeshEntries::removeProcPatches()
|
||||
Foam::polyBoundaryMeshEntries::polyBoundaryMeshEntries(const IOobject& io)
|
||||
:
|
||||
regIOobject
|
||||
(
|
||||
IOobject(io, IOobjectOption::NO_REGISTER)
|
||||
)
|
||||
{
|
||||
// readContents()
|
||||
|
||||
if (isReadRequired() || (isReadOptional() && headerOk()))
|
||||
{
|
||||
// Read as entries
|
||||
Istream& is = readStream(typeName);
|
||||
|
||||
is >> *this;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
Foam::PtrList<Foam::entry>
|
||||
Foam::polyBoundaryMeshEntries::readContents(const IOobject& io)
|
||||
{
|
||||
polyBoundaryMeshEntries reader(io);
|
||||
|
||||
return PtrList<entry>(std::move(static_cast<PtrList<entry>&>(reader)));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Extract optional entry from dictionaries and return as a list
|
||||
template<class T>
|
||||
static inline List<T> extract
|
||||
(
|
||||
const word& key,
|
||||
const UPtrList<entry>& entries,
|
||||
const T& initValue
|
||||
)
|
||||
{
|
||||
List<T> result(entries.size(), initValue);
|
||||
|
||||
forAll(entries, i)
|
||||
{
|
||||
const dictionary& dict = entries[i].dict();
|
||||
dict.readIfPresent(key, result[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End namespace
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::polyBoundaryMeshEntries::removeProcPatches(PtrList<entry>& entries)
|
||||
{
|
||||
// Truncate at the first processor patch entry
|
||||
PtrList<entry>& entries = *this;
|
||||
|
||||
label nNonProcessor = entries.size();
|
||||
|
||||
@ -62,4 +122,132 @@ void Foam::polyBoundaryMeshEntries::removeProcPatches()
|
||||
}
|
||||
|
||||
|
||||
bool Foam::polyBoundaryMeshEntries::writeEntries
|
||||
(
|
||||
Ostream& os,
|
||||
const UPtrList<entry>& entries
|
||||
)
|
||||
{
|
||||
os << entries.size();
|
||||
|
||||
if (entries.empty())
|
||||
{
|
||||
// 0-sized : can write with less vertical space
|
||||
os << token::BEGIN_LIST << token::END_LIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << nl << token::BEGIN_LIST << incrIndent << nl;
|
||||
|
||||
forAll(entries, patchi)
|
||||
{
|
||||
const auto& key = entries[patchi].keyword();
|
||||
const auto& dict = entries[patchi].dict();
|
||||
|
||||
dict.writeEntry(key, os);
|
||||
}
|
||||
os << decrIndent << token::END_LIST;
|
||||
}
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
return os.good();
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::polyBoundaryMeshEntries::types
|
||||
(
|
||||
const UPtrList<entry>& entries
|
||||
)
|
||||
{
|
||||
return extract<word>("type", entries, "patch");
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::polyBoundaryMeshEntries::patchStarts
|
||||
(
|
||||
const UPtrList<entry>& entries
|
||||
)
|
||||
{
|
||||
return extract<label>("startFace", entries, 0);
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::polyBoundaryMeshEntries::patchSizes
|
||||
(
|
||||
const UPtrList<entry>& entries
|
||||
)
|
||||
{
|
||||
return extract<label>("nFaces", entries, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::polyBoundaryMeshEntries::removeProcPatches()
|
||||
{
|
||||
removeProcPatches(*this);
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::polyBoundaryMeshEntries::types() const
|
||||
{
|
||||
return extract<word>("type", *this, "patch");
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::polyBoundaryMeshEntries::patchStarts() const
|
||||
{
|
||||
return extract<label>("startFace", *this, 0);
|
||||
}
|
||||
|
||||
|
||||
Foam::labelList Foam::polyBoundaryMeshEntries::patchSizes() const
|
||||
{
|
||||
return extract<label>("nFaces", *this, 0);
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyBoundaryMeshEntries::writeEntry(Ostream& os) const
|
||||
{
|
||||
writeEntries(os, *this);
|
||||
}
|
||||
|
||||
|
||||
void Foam::polyBoundaryMeshEntries::writeEntry
|
||||
(
|
||||
const keyType& keyword,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
const PtrList<entry>& entries = *this;
|
||||
|
||||
if (!keyword.empty())
|
||||
{
|
||||
os.write(keyword);
|
||||
os << (entries.empty() ? token::SPACE : token::NL);
|
||||
}
|
||||
|
||||
writeEntries(os, entries);
|
||||
|
||||
if (!keyword.empty()) os.endEntry();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::polyBoundaryMeshEntries::writeData(Ostream& os) const
|
||||
{
|
||||
return writeEntries(os, *this);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::polyBoundaryMeshEntries::writeObject
|
||||
(
|
||||
IOstreamOption streamOpt,
|
||||
const bool writeOnProc
|
||||
) const
|
||||
{
|
||||
streamOpt.compression(IOstreamOption::UNCOMPRESSED);
|
||||
return regIOobject::writeObject(streamOpt, writeOnProc);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -29,6 +29,9 @@ Class
|
||||
|
||||
Description
|
||||
Read and store dictionary entries for boundary patches
|
||||
The object is *never* registered to avoid registry name clashes with
|
||||
polyBoundaryMesh, which may either already have been registered, or
|
||||
which should subsequently be registered.
|
||||
|
||||
SourceFiles
|
||||
polyBoundaryMeshEntries.C
|
||||
@ -41,6 +44,7 @@ SourceFiles
|
||||
#include "regIOobject.H"
|
||||
#include "PtrList.H"
|
||||
#include "entry.H"
|
||||
#include "wordList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -64,33 +68,70 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Read construct from IOobject
|
||||
explicit polyBoundaryMeshEntries(const IOobject& io)
|
||||
:
|
||||
regIOobject(io)
|
||||
{
|
||||
if (isReadRequired() || (isReadOptional() && headerOk()))
|
||||
{
|
||||
// Read as entries
|
||||
Istream& is = readStream(typeName);
|
||||
|
||||
is >> *this;
|
||||
close();
|
||||
}
|
||||
}
|
||||
//- Read construct from IOobject. Never register!
|
||||
explicit polyBoundaryMeshEntries(const IOobject& io);
|
||||
|
||||
|
||||
// Member Functions
|
||||
// Factory Methods
|
||||
|
||||
//- Read and return contents. The IOobject is never registered
|
||||
static PtrList<entry> readContents(const IOobject& io);
|
||||
|
||||
|
||||
// Static Functions
|
||||
|
||||
//- Truncate entries at the first processor patch entry
|
||||
static void removeProcPatches(PtrList<entry>& entries);
|
||||
|
||||
//- Write list of entries
|
||||
static bool writeEntries(Ostream& os, const UPtrList<entry>& entries);
|
||||
|
||||
//- Return a list of patch types, uses the "patch" entry
|
||||
static wordList types(const UPtrList<entry>& entries);
|
||||
|
||||
//- Return a list of patch start face indices, uses "startFace" entry
|
||||
static labelList patchStarts(const UPtrList<entry>& entries);
|
||||
|
||||
//- Return a list of patch sizes, uses "nFaces" entry
|
||||
static labelList patchSizes(const UPtrList<entry>& entries);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Truncate at the first processor patch entry
|
||||
void removeProcPatches();
|
||||
|
||||
//- The class is probably read-only
|
||||
bool writeData(Ostream&) const
|
||||
{
|
||||
NotImplemented;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Characteristics
|
||||
|
||||
//- Return a list of patch types, uses the "patch" entry
|
||||
wordList types() const;
|
||||
|
||||
//- Return a list of patch start face indices, uses "startFace" entry
|
||||
labelList patchStarts() const;
|
||||
|
||||
//- Return a list of patch sizes, uses "nFaces" entry
|
||||
labelList patchSizes() const;
|
||||
|
||||
|
||||
// Write
|
||||
|
||||
//- Write as a plain list of entries
|
||||
void writeEntry(Ostream& os) const;
|
||||
|
||||
//- Write as a primitive entry with given name.
|
||||
//- If the keyword is empty, revert to a plain list.
|
||||
void writeEntry(const keyType& keyword, Ostream& os) const;
|
||||
|
||||
//- The writeData member function required by regIOobject
|
||||
virtual bool writeData(Ostream& os) const;
|
||||
|
||||
//- Write using stream options, forces UNCOMPRESSED
|
||||
virtual bool writeObject
|
||||
(
|
||||
IOstreamOption streamOpt,
|
||||
const bool writeOnProc = true
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -259,7 +259,7 @@ Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
*this,
|
||||
PtrList<pointZone>()
|
||||
PtrList<entry>()
|
||||
),
|
||||
faceZones_
|
||||
(
|
||||
@ -273,7 +273,7 @@ Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
*this,
|
||||
PtrList<faceZone>()
|
||||
PtrList<entry>()
|
||||
),
|
||||
cellZones_
|
||||
(
|
||||
@ -287,7 +287,7 @@ Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
*this,
|
||||
PtrList<cellZone>()
|
||||
PtrList<entry>()
|
||||
),
|
||||
globalMeshDataPtr_(nullptr),
|
||||
moving_(false),
|
||||
|
||||
@ -135,39 +135,58 @@ Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate()
|
||||
)
|
||||
);
|
||||
|
||||
// NOTE: owner_.hasHeaderClass() is probably sticky from before.
|
||||
// Could potentially cause problems if constructed without reading
|
||||
// and then using readUpdate() to create a new mesh
|
||||
// owner
|
||||
{
|
||||
owner_.clear();
|
||||
|
||||
owner_.clear();
|
||||
owner_ = labelIOList
|
||||
(
|
||||
IOobject
|
||||
labelIOList list
|
||||
(
|
||||
"owner",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
);
|
||||
IOobject
|
||||
(
|
||||
"owner",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
);
|
||||
|
||||
neighbour_.clear();
|
||||
neighbour_ = labelIOList
|
||||
(
|
||||
IOobject
|
||||
// Update owner headerClassName.
|
||||
// The "cells" logic below may rely on it!
|
||||
|
||||
owner_ = std::move(static_cast<labelList&>(list));
|
||||
owner_.headerClassName() = std::move(list.headerClassName());
|
||||
owner_.note() = std::move(list.note());
|
||||
}
|
||||
|
||||
// neighbour
|
||||
{
|
||||
neighbour_.clear();
|
||||
|
||||
labelIOList list
|
||||
(
|
||||
"neighbour",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
);
|
||||
IOobject
|
||||
(
|
||||
"neighbour",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
);
|
||||
|
||||
// Update neighbour headerClassName.
|
||||
// - not currently needed, but for symmetry with owner
|
||||
// The "cells" logic below may rely on it!
|
||||
|
||||
neighbour_ = std::move(static_cast<labelList&>(list));
|
||||
neighbour_.headerClassName() = std::move(list.headerClassName());
|
||||
neighbour_.note() = std::move(list.note());
|
||||
}
|
||||
|
||||
// Reset the boundary patches
|
||||
polyBoundaryMesh newBoundary
|
||||
@ -290,117 +309,49 @@ Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate()
|
||||
// - this will be extremely fragile (not just here) if the names
|
||||
// or the order of the zones also change
|
||||
|
||||
// pointZones
|
||||
{
|
||||
pointZones_.clearAddressing();
|
||||
pointZones_.clearPrimitives();
|
||||
|
||||
pointZoneMesh newZones
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pointZones",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
),
|
||||
*this,
|
||||
PtrList<pointZone>()
|
||||
);
|
||||
pointZones_.resize(newZones.size());
|
||||
|
||||
forAll(pointZones_, zonei)
|
||||
{
|
||||
// Existing or new empty zone
|
||||
auto& zn =
|
||||
pointZones_.try_emplace
|
||||
(
|
||||
zonei,
|
||||
newZones[zonei], Foam::zero{}, pointZones_
|
||||
);
|
||||
|
||||
// Set addressing
|
||||
zn.resetAddressing(std::move(newZones[zonei]));
|
||||
}
|
||||
#undef update_meshZones
|
||||
#define update_meshZones(DataMember) \
|
||||
{ \
|
||||
(DataMember).clearAddressing(); \
|
||||
(DataMember).clearPrimitives(); \
|
||||
\
|
||||
decltype(DataMember) newZones \
|
||||
( \
|
||||
IOobject \
|
||||
( \
|
||||
(DataMember).name(), \
|
||||
facesInst, \
|
||||
meshSubDir, \
|
||||
*this, \
|
||||
IOobject::READ_IF_PRESENT, \
|
||||
IOobject::NO_WRITE, \
|
||||
IOobject::NO_REGISTER \
|
||||
), \
|
||||
*this, \
|
||||
PtrList<entry>() \
|
||||
); \
|
||||
const label numZones = newZones.size(); \
|
||||
(DataMember).resize(numZones); \
|
||||
\
|
||||
for (label zonei = 0; zonei < numZones; ++zonei) \
|
||||
{ \
|
||||
/* Existing or new empty zone */ \
|
||||
auto& zn = (DataMember).try_emplace \
|
||||
( \
|
||||
zonei, \
|
||||
newZones[zonei], Foam::zero{}, (DataMember) \
|
||||
); \
|
||||
\
|
||||
/* Set addressing */ \
|
||||
zn.resetAddressing(std::move(newZones[zonei])); \
|
||||
} \
|
||||
}
|
||||
|
||||
// faceZones
|
||||
{
|
||||
faceZones_.clearAddressing();
|
||||
faceZones_.clearPrimitives();
|
||||
update_meshZones(pointZones_);
|
||||
update_meshZones(faceZones_);
|
||||
update_meshZones(cellZones_);
|
||||
#undef update_meshZones
|
||||
|
||||
faceZoneMesh newZones
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"faceZones",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
),
|
||||
*this,
|
||||
PtrList<faceZone>()
|
||||
);
|
||||
faceZones_.resize(newZones.size());
|
||||
|
||||
forAll(faceZones_, zonei)
|
||||
{
|
||||
// Existing or new empty zone
|
||||
auto& zn =
|
||||
faceZones_.try_emplace
|
||||
(
|
||||
zonei,
|
||||
newZones[zonei], Foam::zero{}, faceZones_
|
||||
);
|
||||
|
||||
// Set addressing
|
||||
zn.resetAddressing(std::move(newZones[zonei]));
|
||||
}
|
||||
}
|
||||
|
||||
// cellZones
|
||||
{
|
||||
cellZones_.clearAddressing();
|
||||
cellZones_.clearPrimitives();
|
||||
|
||||
cellZoneMesh newZones
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellZones",
|
||||
facesInst,
|
||||
meshSubDir,
|
||||
*this,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
),
|
||||
*this,
|
||||
PtrList<cellZone>()
|
||||
);
|
||||
|
||||
cellZones_.resize(newZones.size());
|
||||
|
||||
forAll(cellZones_, zonei)
|
||||
{
|
||||
// Existing or new empty zone
|
||||
auto& zn =
|
||||
cellZones_.try_emplace
|
||||
(
|
||||
zonei,
|
||||
newZones[zonei], Foam::zero{}, cellZones_
|
||||
);
|
||||
|
||||
// Set addressing
|
||||
zn.resetAddressing(std::move(newZones[zonei]));
|
||||
}
|
||||
}
|
||||
|
||||
// Re-read tet base points
|
||||
tetBasePtIsPtr_ = readTetBasePtIs();
|
||||
|
||||
@ -157,12 +157,55 @@ void Foam::ZoneMesh<ZoneType, MeshType>::calcGroupIDs() const
|
||||
}
|
||||
|
||||
|
||||
template<class ZoneType, class MeshType>
|
||||
void Foam::ZoneMesh<ZoneType, MeshType>::populate
|
||||
(
|
||||
PtrList<entry>&& entries
|
||||
)
|
||||
{
|
||||
clearLocalAddressing();
|
||||
|
||||
PtrList<ZoneType>& zones = *this;
|
||||
|
||||
zones.resize_null(entries.size());
|
||||
|
||||
// Transcribe
|
||||
// Does not handle nullptr at all
|
||||
forAll(zones, zonei)
|
||||
{
|
||||
// Possible handling for nullptr:
|
||||
// zones.emplace_set
|
||||
// (
|
||||
// zonei,
|
||||
// "missing_" + ::Foam::name(zonei), zonei, *this
|
||||
// );
|
||||
|
||||
zones.set
|
||||
(
|
||||
zonei,
|
||||
ZoneType::New
|
||||
(
|
||||
entries[zonei].keyword(),
|
||||
entries[zonei].dict(),
|
||||
zonei,
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
|
||||
template<class ZoneType, class MeshType>
|
||||
bool Foam::ZoneMesh<ZoneType, MeshType>::readContents
|
||||
(
|
||||
const bool allowOptionalRead
|
||||
)
|
||||
{
|
||||
bool updated = false;
|
||||
PtrList<entry> entries;
|
||||
|
||||
if
|
||||
(
|
||||
isReadRequired()
|
||||
@ -172,37 +215,24 @@ bool Foam::ZoneMesh<ZoneType, MeshType>::readContents
|
||||
// Warn for MUST_READ_IF_MODIFIED
|
||||
warnNoRereading<ZoneMesh<ZoneType, MeshType>>();
|
||||
|
||||
PtrList<ZoneType>& zones = *this;
|
||||
|
||||
// Read entries
|
||||
Istream& is = readStream(typeName);
|
||||
|
||||
PtrList<entry> entries(is);
|
||||
zones.resize_null(entries.size());
|
||||
|
||||
// Transcribe
|
||||
forAll(zones, zonei)
|
||||
{
|
||||
zones.set
|
||||
(
|
||||
zonei,
|
||||
ZoneType::New
|
||||
(
|
||||
entries[zonei].keyword(),
|
||||
entries[zonei].dict(),
|
||||
zonei,
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
is >> entries;
|
||||
|
||||
is.check(FUNCTION_NAME);
|
||||
close();
|
||||
return true;
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Nothing read
|
||||
return false;
|
||||
// Future: support master-only and broadcast?
|
||||
|
||||
if (updated)
|
||||
{
|
||||
populate(std::move(entries));
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
@ -283,6 +313,26 @@ Foam::ZoneMesh<ZoneType, MeshType>::ZoneMesh
|
||||
}
|
||||
|
||||
|
||||
template<class ZoneType, class MeshType>
|
||||
Foam::ZoneMesh<ZoneType, MeshType>::ZoneMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const MeshType& mesh,
|
||||
PtrList<entry>&& entries
|
||||
)
|
||||
:
|
||||
PtrList<ZoneType>(),
|
||||
regIOobject(io),
|
||||
mesh_(mesh)
|
||||
{
|
||||
if (!readContents(true)) // allowOptionalRead = true
|
||||
{
|
||||
populate(std::move(entries));
|
||||
}
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class ZoneType, class MeshType>
|
||||
@ -759,11 +809,19 @@ void Foam::ZoneMesh<ZoneType, MeshType>::setGroup
|
||||
}
|
||||
|
||||
|
||||
// Private until it is more generally required (and gets a better name?)
|
||||
template<class ZoneType, class MeshType>
|
||||
void Foam::ZoneMesh<ZoneType, MeshType>::clearAddressing()
|
||||
void Foam::ZoneMesh<ZoneType, MeshType>::clearLocalAddressing()
|
||||
{
|
||||
zoneMapPtr_.reset(nullptr);
|
||||
groupIDsPtr_.reset(nullptr);
|
||||
}
|
||||
|
||||
|
||||
template<class ZoneType, class MeshType>
|
||||
void Foam::ZoneMesh<ZoneType, MeshType>::clearAddressing()
|
||||
{
|
||||
clearLocalAddressing();
|
||||
|
||||
PtrList<ZoneType>& zones = *this;
|
||||
|
||||
|
||||
@ -82,10 +82,6 @@ class ZoneMesh
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Return true if contents were read
|
||||
//- (controlled by IOobject readOption flags).
|
||||
bool readContents(const bool allowOptionalRead);
|
||||
|
||||
//- Total of number of addressed items (all zones)
|
||||
label totalSize() const;
|
||||
|
||||
@ -98,6 +94,31 @@ class ZoneMesh
|
||||
//- Calculate group name to zone ids lookup
|
||||
void calcGroupIDs() const;
|
||||
|
||||
//- Clear addressing at this level
|
||||
void clearLocalAddressing();
|
||||
|
||||
//- Populate/recreate from dictionary entries
|
||||
void populate(PtrList<entry>&& entries);
|
||||
|
||||
//- Return true if contents were read
|
||||
//- (controlled by IOobject readOption flags).
|
||||
bool readContents(const bool allowOptionalRead);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Public Typedefs
|
||||
|
||||
//- The zone type. Same as PtrList<ZoneType>::value_type
|
||||
typedef ZoneType zone_type;
|
||||
|
||||
|
||||
//- Debug switch to disallow the use of generic zones
|
||||
static int disallowGenericZones;
|
||||
|
||||
|
||||
// Generated Methods
|
||||
|
||||
//- No copy construct
|
||||
ZoneMesh(const ZoneMesh&) = delete;
|
||||
|
||||
@ -105,12 +126,6 @@ class ZoneMesh
|
||||
void operator=(const ZoneMesh<ZoneType, MeshType>&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Debug switch to disallow the use of generic zones
|
||||
static int disallowGenericZones;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Read construct from IOobject and mesh reference
|
||||
@ -148,6 +163,15 @@ public:
|
||||
const PtrList<ZoneType>& list
|
||||
);
|
||||
|
||||
//- Read construct (mandatory, optional) based on IOobject properties
|
||||
//- or use the fallback PtrList (with cloning).
|
||||
ZoneMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const MeshType& mesh,
|
||||
PtrList<entry>&& entries
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~ZoneMesh() = default;
|
||||
|
||||
@ -72,6 +72,7 @@ Foam::boundaryPatch::boundaryPatch(const boundaryPatch& p, const label index)
|
||||
|
||||
void Foam::boundaryPatch::write(Ostream& os) const
|
||||
{
|
||||
// if (!type_.empty()) os.writeEntry("type", type_);
|
||||
patchIdentifier::write(os);
|
||||
os.writeEntry("nFaces", size_);
|
||||
os.writeEntry("startFace", start_);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -41,6 +41,7 @@ SourceFiles
|
||||
#define Foam_boundaryPatch_H
|
||||
|
||||
#include "patchIdentifier.H"
|
||||
#include "labelRange.H"
|
||||
#include "autoPtr.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -58,8 +59,10 @@ class boundaryPatch
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The size of the patch
|
||||
label size_;
|
||||
|
||||
//- Start label of the patch
|
||||
label start_;
|
||||
|
||||
public:
|
||||
@ -100,24 +103,22 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
label size() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
//- The start of the patch
|
||||
label start() const noexcept { return start_; }
|
||||
|
||||
label& size()
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
//- The start of the patch (modifiable)
|
||||
label& start() noexcept { return start_; }
|
||||
|
||||
label start() const
|
||||
{
|
||||
return start_;
|
||||
}
|
||||
//- The size of the patch
|
||||
label size() const noexcept { return size_; }
|
||||
|
||||
label& start()
|
||||
//- The size of the patch (modifiable)
|
||||
label& size() noexcept { return size_; }
|
||||
|
||||
//- Return start/size range of this patch
|
||||
labelRange range() const noexcept
|
||||
{
|
||||
return start_;
|
||||
return labelRange(start_, size_);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -101,8 +101,40 @@ void Foam::faBoundaryMesh::calcGroupIDs() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::faBoundaryMesh::populate(PtrList<entry>&& entries)
|
||||
{
|
||||
clearLocalAddressing();
|
||||
|
||||
faPatchList& patches = *this;
|
||||
|
||||
patches.resize_null(entries.size());
|
||||
|
||||
// Transcribe.
|
||||
// Does not handle nullptr at all (what could possibly be done?)
|
||||
forAll(patches, patchi)
|
||||
{
|
||||
patches.set
|
||||
(
|
||||
patchi,
|
||||
faPatch::New
|
||||
(
|
||||
entries[patchi].keyword(),
|
||||
entries[patchi].dict(),
|
||||
patchi,
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMesh::readContents(const bool allowOptionalRead)
|
||||
{
|
||||
bool updated = false;
|
||||
PtrList<entry> entries;
|
||||
|
||||
if
|
||||
(
|
||||
isReadRequired()
|
||||
@ -112,37 +144,23 @@ bool Foam::faBoundaryMesh::readContents(const bool allowOptionalRead)
|
||||
// Warn for MUST_READ_IF_MODIFIED
|
||||
warnNoRereading<faBoundaryMesh>();
|
||||
|
||||
faPatchList& patches = *this;
|
||||
|
||||
// Read entries
|
||||
Istream& is = readStream(typeName);
|
||||
|
||||
PtrList<entry> entries(is);
|
||||
patches.resize_null(entries.size());
|
||||
|
||||
// Transcribe
|
||||
forAll(patches, patchi)
|
||||
{
|
||||
patches.set
|
||||
(
|
||||
patchi,
|
||||
faPatch::New
|
||||
(
|
||||
entries[patchi].keyword(),
|
||||
entries[patchi].dict(),
|
||||
patchi,
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
is >> entries;
|
||||
|
||||
is.check(FUNCTION_NAME);
|
||||
close();
|
||||
return true;
|
||||
updated = true;
|
||||
}
|
||||
// Future: support master-only and broadcast?
|
||||
|
||||
if (updated)
|
||||
{
|
||||
populate(std::move(entries));
|
||||
}
|
||||
|
||||
// Nothing read
|
||||
return false;
|
||||
return updated;
|
||||
}
|
||||
|
||||
|
||||
@ -213,11 +231,36 @@ Foam::faBoundaryMesh::faBoundaryMesh
|
||||
}
|
||||
|
||||
|
||||
Foam::faBoundaryMesh::faBoundaryMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const faMesh& fam,
|
||||
PtrList<entry>&& entries
|
||||
)
|
||||
:
|
||||
faPatchList(),
|
||||
regIOobject(io),
|
||||
mesh_(fam)
|
||||
{
|
||||
if (!readContents(true)) // allowOptionalRead = true
|
||||
{
|
||||
populate(std::move(entries));
|
||||
}
|
||||
entries.clear();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::faBoundaryMesh::clear()
|
||||
{
|
||||
clearLocalAddressing();
|
||||
faPatchList::clear();
|
||||
}
|
||||
|
||||
|
||||
void Foam::faBoundaryMesh::clearLocalAddressing()
|
||||
{
|
||||
groupIDsPtr_.reset(nullptr);
|
||||
}
|
||||
|
||||
@ -987,22 +1030,56 @@ void Foam::faBoundaryMesh::updateMesh()
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMesh::writeData(Ostream& os) const
|
||||
void Foam::faBoundaryMesh::writeEntry(Ostream& os) const
|
||||
{
|
||||
const faPatchList& patches = *this;
|
||||
const faPatchList& entries = *this;
|
||||
|
||||
os << patches.size() << nl << token::BEGIN_LIST << incrIndent << nl;
|
||||
os << entries.size();
|
||||
|
||||
for (const faPatch& p : patches)
|
||||
if (entries.empty())
|
||||
{
|
||||
os.beginBlock(p.name());
|
||||
os << p;
|
||||
os.endBlock();
|
||||
// 0-sized : can write with less vertical space
|
||||
os << token::BEGIN_LIST << token::END_LIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << nl << token::BEGIN_LIST << incrIndent << nl;
|
||||
|
||||
for (const auto& pp : entries)
|
||||
{
|
||||
os.beginBlock(pp.name());
|
||||
os << pp;
|
||||
os.endBlock();
|
||||
}
|
||||
os << decrIndent << token::END_LIST;
|
||||
}
|
||||
os.check(FUNCTION_NAME);
|
||||
}
|
||||
|
||||
|
||||
void Foam::faBoundaryMesh::writeEntry
|
||||
(
|
||||
const keyType& keyword,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
const faPatchList& entries = *this;
|
||||
|
||||
if (!keyword.empty())
|
||||
{
|
||||
os.write(keyword);
|
||||
os << (entries.empty() ? token::SPACE : token::NL);
|
||||
}
|
||||
|
||||
os << decrIndent << token::END_LIST;
|
||||
writeEntry(os);
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
if (!keyword.empty()) os.endEntry();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMesh::writeData(Ostream& os) const
|
||||
{
|
||||
writeEntry(os);
|
||||
return os.good();
|
||||
}
|
||||
|
||||
@ -1013,10 +1090,7 @@ bool Foam::faBoundaryMesh::writeObject
|
||||
const bool writeOnProc
|
||||
) const
|
||||
{
|
||||
// Allow/disallow compression?
|
||||
// 1. keep readable
|
||||
// 2. save some space
|
||||
// ??? streamOpt.compression(IOstreamOption::UNCOMPRESSED);
|
||||
streamOpt.compression(IOstreamOption::UNCOMPRESSED);
|
||||
return regIOobject::writeObject(streamOpt, writeOnProc);
|
||||
}
|
||||
|
||||
|
||||
@ -55,6 +55,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class entry;
|
||||
class faMesh;
|
||||
class faBoundaryMesh;
|
||||
class wordRes;
|
||||
@ -87,11 +88,16 @@ class faBoundaryMesh
|
||||
//- Calculate group name to patch ids lookup
|
||||
void calcGroupIDs() const;
|
||||
|
||||
//- Clear addressing at this level
|
||||
void clearLocalAddressing();
|
||||
|
||||
//- Populate/recreate from dictionary entries
|
||||
void populate(PtrList<entry>&& entries);
|
||||
|
||||
//- Return true if contents were read
|
||||
//- (controlled by IOobject readOption flags).
|
||||
bool readContents(const bool allowOptionalRead);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
@ -143,6 +149,15 @@ public:
|
||||
const faPatchList& list
|
||||
);
|
||||
|
||||
//- Read construct (mandatory, optional) based on IOobject properties
|
||||
//- or fallback to constructing from a list of dictionary entries
|
||||
faBoundaryMesh
|
||||
(
|
||||
const IOobject& io,
|
||||
const faMesh& fam,
|
||||
PtrList<entry>&& entries
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~faBoundaryMesh() = default;
|
||||
@ -278,14 +293,24 @@ public:
|
||||
//- Correct faBoundaryMesh after topology update
|
||||
void updateMesh();
|
||||
|
||||
//- The writeData member function required by regIOobject
|
||||
bool writeData(Ostream& os) const;
|
||||
|
||||
//- Write using stream options
|
||||
// Write
|
||||
|
||||
//- Write as a plain list of entries
|
||||
void writeEntry(Ostream& os) const;
|
||||
|
||||
//- Write as a primitive entry with given name.
|
||||
//- If the keyword is empty, revert to a plain list.
|
||||
void writeEntry(const keyType& keyword, Ostream& os) const;
|
||||
|
||||
//- The writeData member function required by regIOobject
|
||||
virtual bool writeData(Ostream& os) const;
|
||||
|
||||
//- Write using stream options, but always UNCOMPRESSED
|
||||
virtual bool writeObject
|
||||
(
|
||||
IOstreamOption streamOpt,
|
||||
const bool writeOnProc
|
||||
const bool writeOnProc = true
|
||||
) const;
|
||||
|
||||
|
||||
|
||||
@ -36,12 +36,72 @@ namespace Foam
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::faBoundaryMeshEntries::removeProcPatches()
|
||||
Foam::faBoundaryMeshEntries::faBoundaryMeshEntries(const IOobject& io)
|
||||
:
|
||||
regIOobject
|
||||
(
|
||||
IOobject(io, IOobjectOption::NO_REGISTER)
|
||||
)
|
||||
{
|
||||
// readContents()
|
||||
|
||||
if (isReadRequired() || (isReadOptional() && headerOk()))
|
||||
{
|
||||
// Read as entries
|
||||
Istream& is = readStream(typeName);
|
||||
|
||||
is >> *this;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
Foam::PtrList<Foam::entry>
|
||||
Foam::faBoundaryMeshEntries::readContents(const IOobject& io)
|
||||
{
|
||||
faBoundaryMeshEntries reader(io);
|
||||
|
||||
return PtrList<entry>(std::move(static_cast<PtrList<entry>&>(reader)));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Extract optional entry from dictionaries and return as a list
|
||||
template<class T>
|
||||
static inline List<T> extract
|
||||
(
|
||||
const word& key,
|
||||
const UPtrList<entry>& entries,
|
||||
const T& initValue
|
||||
)
|
||||
{
|
||||
List<T> result(entries.size(), initValue);
|
||||
|
||||
forAll(entries, i)
|
||||
{
|
||||
const dictionary& dict = entries[i].dict();
|
||||
dict.readIfPresent(key, result[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End namespace
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::faBoundaryMeshEntries::removeProcPatches(PtrList<entry>& entries)
|
||||
{
|
||||
// Truncate at the first processor patch entry
|
||||
PtrList<entry>& entries = *this;
|
||||
|
||||
label nNonProcessor = entries.size();
|
||||
|
||||
@ -61,4 +121,102 @@ void Foam::faBoundaryMeshEntries::removeProcPatches()
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMeshEntries::writeEntries
|
||||
(
|
||||
Ostream& os,
|
||||
const UPtrList<entry>& entries
|
||||
)
|
||||
{
|
||||
os << entries.size();
|
||||
|
||||
if (entries.empty())
|
||||
{
|
||||
// 0-sized : can write with less vertical space
|
||||
os << token::BEGIN_LIST << token::END_LIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
os << nl << token::BEGIN_LIST << incrIndent << nl;
|
||||
|
||||
forAll(entries, patchi)
|
||||
{
|
||||
const auto& key = entries[patchi].keyword();
|
||||
const auto& dict = entries[patchi].dict();
|
||||
|
||||
dict.writeEntry(key, os);
|
||||
}
|
||||
os << decrIndent << token::END_LIST;
|
||||
}
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
return os.good();
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::faBoundaryMeshEntries::types
|
||||
(
|
||||
const UPtrList<entry>& entries
|
||||
)
|
||||
{
|
||||
return extract<word>("type", entries, "patch");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::faBoundaryMeshEntries::removeProcPatches()
|
||||
{
|
||||
removeProcPatches(*this);
|
||||
}
|
||||
|
||||
|
||||
Foam::wordList Foam::faBoundaryMeshEntries::types() const
|
||||
{
|
||||
return extract<word>("type", *this, "patch");
|
||||
}
|
||||
|
||||
|
||||
void Foam::faBoundaryMeshEntries::writeEntry(Ostream& os) const
|
||||
{
|
||||
writeEntries(os, *this);
|
||||
}
|
||||
|
||||
|
||||
void Foam::faBoundaryMeshEntries::writeEntry
|
||||
(
|
||||
const keyType& keyword,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
const PtrList<entry>& entries = *this;
|
||||
|
||||
if (!keyword.empty())
|
||||
{
|
||||
os.write(keyword);
|
||||
os << (entries.empty() ? token::SPACE : token::NL);
|
||||
}
|
||||
|
||||
writeEntries(os, entries);
|
||||
|
||||
if (!keyword.empty()) os.endEntry();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMeshEntries::writeData(Ostream& os) const
|
||||
{
|
||||
return writeEntries(os, *this);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::faBoundaryMeshEntries::writeObject
|
||||
(
|
||||
IOstreamOption streamOpt,
|
||||
const bool writeOnProc
|
||||
) const
|
||||
{
|
||||
streamOpt.compression(IOstreamOption::UNCOMPRESSED);
|
||||
return regIOobject::writeObject(streamOpt, writeOnProc);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,6 +28,9 @@ Class
|
||||
|
||||
Description
|
||||
Read and store dictionary entries for finite-area boundary patches.
|
||||
The object is *never* registered to avoid registry name clashes with
|
||||
faBoundaryMesh, which may either already have been registered, or
|
||||
which should subsequently be registered.
|
||||
|
||||
SourceFiles
|
||||
faBoundaryMeshEntries.C
|
||||
@ -40,6 +43,7 @@ SourceFiles
|
||||
#include "regIOobject.H"
|
||||
#include "PtrList.H"
|
||||
#include "entry.H"
|
||||
#include "wordList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -63,20 +67,26 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Read construct from IOobject
|
||||
explicit faBoundaryMeshEntries(const IOobject& io)
|
||||
:
|
||||
regIOobject(io)
|
||||
{
|
||||
if (isReadRequired() || (isReadOptional() && headerOk()))
|
||||
{
|
||||
// Read as entries
|
||||
Istream& is = readStream(typeName);
|
||||
//- Read construct from IOobject. Never register!
|
||||
explicit faBoundaryMeshEntries(const IOobject& io);
|
||||
|
||||
is >> *this;
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
// Factory Methods
|
||||
|
||||
//- Read and return contents. The IOobject is never registered
|
||||
static PtrList<entry> readContents(const IOobject& io);
|
||||
|
||||
|
||||
// Static Functions
|
||||
|
||||
//- Truncate entries at the first processor patch entry
|
||||
static void removeProcPatches(PtrList<entry>& entries);
|
||||
|
||||
//- Write list of entries
|
||||
static bool writeEntries(Ostream& os, const UPtrList<entry>& entries);
|
||||
|
||||
//- Return a list of patch types, uses the "patch" entry
|
||||
static wordList types(const UPtrList<entry>& entries);
|
||||
|
||||
|
||||
// Member Functions
|
||||
@ -84,12 +94,31 @@ public:
|
||||
//- Truncate at the first processor patch entry
|
||||
void removeProcPatches();
|
||||
|
||||
//- The class is probably read-only
|
||||
bool writeData(Ostream&) const
|
||||
{
|
||||
NotImplemented;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Characteristics
|
||||
|
||||
//- Return a list of patch types, uses the "patch" entry
|
||||
wordList types() const;
|
||||
|
||||
|
||||
// Write
|
||||
|
||||
//- Write as a plain list of entries
|
||||
void writeEntry(Ostream& os) const;
|
||||
|
||||
//- Write as a primitive entry with given name.
|
||||
//- If the keyword is empty, revert to a plain list.
|
||||
void writeEntry(const keyType& keyword, Ostream& os) const;
|
||||
|
||||
//- The writeData member function required by regIOobject
|
||||
virtual bool writeData(Ostream& os) const;
|
||||
|
||||
//- Write using stream options, forces UNCOMPRESSED
|
||||
virtual bool writeObject
|
||||
(
|
||||
IOstreamOption streamOpt,
|
||||
const bool writeOnProc = true
|
||||
) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user