43 template<
class PatchType>
52 edgeList dumpEdges(
p.edges(), selectEdges);
77 const bool validBoundary
83 <<
"boundary already exists" 87 globalMeshDataPtr_.reset(
nullptr);
91 setPrimitiveMeshData();
102 const List<faPatch*>&
p,
103 const bool validBoundary
109 addFaPatches(plist, validBoundary);
115 const word& patchName,
116 const word& patchType
120 if (!patchName.empty())
122 onePatchDict.
add(
"name", patchName);
124 if (!patchType.empty())
126 onePatchDict.add(
"type", patchType);
129 return createPatchList
140 const dictionary& bndDict,
141 const word& emptyPatchName,
142 const dictionary* defaultPatchDefinition
148 DynamicList<faPatchData> faPatchDefs(bndDict.size() + 8);
149 for (
const entry& dEntry : bndDict)
151 if (!dEntry.isDict())
154 <<
"Not a dictionary entry: " << dEntry.name() <<
nl;
160 auto& patchDef = faPatchDefs.emplace_back();
161 patchDef.name_ = dEntry.keyword();
162 patchDef.type_ = patchDict.get<word>(
"type");
167 if (patchDict.readIfPresent(
"ownerPolyPatch", patchName))
170 if (patchDef.ownerPolyPatchId_ < 0)
173 <<
"ownerPolyPatch " << patchName <<
" not found" 179 patchDict.readEntry(
"neighbourPolyPatch", patchName);
182 if (patchDef.neighPolyPatchId_ < 0)
185 <<
"neighbourPolyPatch " << patchName <<
" not found" 192 if (!emptyPatchName.empty())
194 auto& patchDef = faPatchDefs.emplace_back();
195 patchDef.name_ = emptyPatchName;
196 patchDef.type_ = emptyFaPatch::typeName_();
199 label nWarnUndefinedPatch(5);
202 const label undefPatchIndex = faPatchDefs.size();
204 auto& patchDef = faPatchDefs.emplace_back();
205 patchDef.name_ =
"undefined";
206 patchDef.type_ =
"patch";
208 if (defaultPatchDefinition)
212 (*defaultPatchDefinition).readIfPresent(
"name", patchDef.name_)
217 nWarnUndefinedPatch = 0;
219 (*defaultPatchDefinition).readIfPresent(
"type", patchDef.type_);
224 const label ignorePatchIndex = faPatchDefs.size();
226 auto& patchDef = faPatchDefs.emplace_back();
227 patchDef.name_ =
"_ignore_edges_";
228 patchDef.type_ = ignoreFaPatch::typeName_();
234 List<Pair<patchTuple>> bndEdgeConnections
236 this->getBoundaryEdgeConnections()
240 this->setBoundaryConnections(bndEdgeConnections);
244 labelList patchDefLookup(bndEdgeConnections.size(), -1);
246 Map<labelHashSet> procConnections;
251 forAll(bndEdgeConnections, connecti)
253 const Pair<patchTuple>& connection = bndEdgeConnections[connecti];
254 const auto& a = connection.first();
255 const auto&
b = connection.second();
259 if (!a.valid() || !
b.valid())
262 patchDefLookup[connecti] = ignorePatchIndex;
263 patchDefsUsed.insert(ignorePatchIndex);
266 else if (a.is_finiteArea())
268 if (
b.is_finiteArea())
272 if (a.procNo() ==
b.procNo())
276 <<
"Processor-processor addressing error:" <<
nl 277 <<
"Both connections have the same processor: " 279 <<
"Connecting patches " 280 << a.realPatchi() <<
" and " <<
b.realPatchi() <<
nl 283 else if (a.is_localProc())
285 procConnections(
b.procNo()).
insert(connecti);
289 procConnections(a.procNo()).
insert(connecti);
294 else if (a.is_localProc())
296 patchPair.first() = a.realPatchi();
297 patchPair.second() =
b.realPatchi();
300 else if (
b.is_finiteArea() &&
b.is_localProc())
302 patchPair.first() =
b.realPatchi();
303 patchPair.second() = a.realPatchi();
310 label bestPatchDefi = -1;
312 const label nPatchDefs = (patchPair.valid() ? faPatchDefs.size() : 0);
314 for (label patchDefi = 0; patchDefi < nPatchDefs; ++patchDefi)
316 const int match = faPatchDefs[patchDefi].matchPatchPair(patchPair);
320 bestPatchDefi = patchDefi;
323 else if (
match == 2 && bestPatchDefi < 0)
326 bestPatchDefi = patchDefi;
330 if (bestPatchDefi < 0)
332 bestPatchDefi = undefPatchIndex;
335 patchDefLookup[connecti] = bestPatchDefi;
336 patchDefsUsed.insert(bestPatchDefi);
340 bool reportBadEdges =
false;
345 faPatchDefs[undefPatchIndex].clear();
349 patchDefsUsed.insert(undefPatchIndex);
350 reportBadEdges =
true;
356 faPatchDefs[ignorePatchIndex].clear();
360 patchDefsUsed.insert(ignorePatchIndex);
361 reportBadEdges =
true;
368 forAll(patchDefLookup, connecti)
370 if (patchDefLookup[connecti] == undefPatchIndex)
372 const auto& connection = bndEdgeConnections[connecti];
374 const auto& a = connection.first();
375 const auto&
b = connection.second();
377 if (a.is_localProc() && a.is_finiteArea())
381 else if (
b.is_localProc() &&
b.is_finiteArea())
388 Pout<<
"Undefined connection: " 389 <<
"(patch:" << a.realPatchi()
390 <<
" face:" << a.meshFacei()
391 <<
" proc:" << a.procNo()
392 <<
") and (patch:" <<
b.realPatchi()
393 <<
" face:" <<
b.meshFacei()
394 <<
" proc:" <<
b.procNo()
423 <<
" undefined edge connections, added to defaultPatch: " 424 << faPatchDefs[undefPatchIndex].name_ <<
nl <<
nl 425 <<
"==> Could indicate a non-manifold patch geometry" <<
nl 428 if (nWarnUndefinedPatch)
431 word
outputName(
"faMesh-construct.undefEdges");
437 thisDb().time().globalPath(),
451 forAll(patchDefLookup, connecti)
453 if (patchDefLookup[connecti] == ignorePatchIndex)
455 const auto& connection = bndEdgeConnections[connecti];
457 const auto& a = connection.first();
458 const auto&
b = connection.second();
460 if (a.is_localProc() && a.is_finiteArea())
464 else if (
b.is_localProc() &&
b.is_finiteArea())
471 Pout<<
"Illegal connection: " 472 <<
"(patch:" << a.realPatchi()
473 <<
" face:" << a.meshFacei()
474 <<
" proc:" << a.procNo()
475 <<
") and (patch:" <<
b.realPatchi()
476 <<
" face:" <<
b.meshFacei()
477 <<
" proc:" <<
b.procNo()
506 <<
" illegal edge connections, added to " 507 << faPatchDefs[ignorePatchIndex].name_ <<
nl <<
nl 508 <<
"==> Could indicate a non-manifold patch geometry" <<
nl 511 if (nWarnUndefinedPatch)
514 word
outputName(
"faMesh-construct.ignoreEdges");
520 thisDb().time().globalPath(),
531 Map<label> procToDefLookup;
533 procToDefLookup.reserve(procConnections.size());
534 faPatchDefs.reserve(faPatchDefs.size() + procConnections.size());
536 for (
const label otherProci : procConnections.sortedToc())
538 const label patchDefi = faPatchDefs.size();
539 procToDefLookup.insert(otherProci, patchDefi);
542 auto& patchDef = faPatchDefs.emplace_back();
552 DynamicList<label> selectEdges(bndEdgeConnections.size());
553 label nOffProcessorEdges = 0;
555 for (
const label patchDefi : patchDefsUsed.sortedToc())
557 auto& patchDef = faPatchDefs[patchDefi];
563 forAll(patchDefLookup, connecti)
565 if (patchDefLookup[connecti] == patchDefi)
567 const auto& a = bndEdgeConnections[connecti].first();
568 const auto&
b = bndEdgeConnections[connecti].second();
570 if (a.is_localProc() && a.is_finiteArea())
572 selectEdges.push_back(a.patchEdgei());
574 else if (
b.is_localProc() &&
b.is_finiteArea())
576 selectEdges.push_back(
b.patchEdgei());
578 else if (a.valid() &&
b.valid())
581 <<
"Error in programming logic" <<
nl 585 if (a.is_localProc() !=
b.is_localProc())
587 ++nOffProcessorEdges;
590 patchDefLookup[connecti] = -2;
598 patchDef.edgeLabels_ = selectEdges;
603 Pout<<
"Had " << nOffProcessorEdges
604 <<
" patch edges connected off-processor" <<
endl;
609 <<
" patch edges connected off-processor" <<
endl;
614 for (
const label otherProci : procToDefLookup.sortedToc())
616 const label patchDefi = procToDefLookup[otherProci];
618 auto& patchDef = faPatchDefs[patchDefi];
624 for (
const label connecti : procConnections(otherProci).
sortedToc())
626 const auto& connection = bndEdgeConnections[connecti];
627 const auto& a = connection.first();
628 const auto&
b = connection.second();
630 if (a.is_localProc())
632 selectEdges.push_back(a.patchEdgei());
634 else if (
b.is_localProc())
636 selectEdges.push_back(
b.patchEdgei());
641 <<
"Error in programming logic" <<
nl 645 patchDefLookup[connecti] = -2;
651 patchDef.edgeLabels_ = selectEdges;
660 for (faPatchData& patchDef : faPatchDefs)
662 if (!patchDef.good())
673 patchDef.dict(
false),
680 newPatches[
nPatches].resetEdges(std::move(patchDef.edgeLabels_));
688 Pout<<
"Created new finiteArea patches:" <<
nl;
689 for (
const faPatch&
p : newPatches)
692 <<
" name:" <<
p.
name()
693 <<
" type:" <<
p.type() <<
nl;
697 Pout<<
"addressed: " << nTotal
698 <<
'/' <<
patch().nBoundaryEdges() <<
" edges" <<
endl;
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
PtrList< faPatch > faPatchList
Store lists of faPatch as a PtrList.
const polyBoundaryMesh & pbm
static autoPtr< faPatch > New(const word &name, const dictionary &dict, const label index, const faBoundaryMesh &bm)
Return pointer to a new patch created on freestore from dictionary.
void size(const label n)
Older name for setAddressableSize.
bool checkDefinition(const bool report=false) const
Check boundary definition.
void addFaPatches(faPatchList &plist, const bool validBoundary=true)
Add boundary patches. Constructor helper.
A class for handling file names.
errorManipArg< error, int > exit(error &err, const int errNo=1)
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/"finiteArea-edgesCentres"))
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const word & name() const noexcept
Return the object name.
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
bool writeProcIDs()
Write processor ids for each line as CellData or for each point as PointData, depending on isPointDat...
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
bool match(const UList< wordRe > &selectors, const std::string &text)
True if text matches one of the selector expressions.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
labelHashSet badEdges(pp.nEdges()/20)
#define forAll(list, i)
Loop across all elements in list.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
label size() const noexcept
The number of elements in table.
word outputName("finiteArea-edges.obj")
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
void sort(UList< T > &list)
Sort the list.
void clear()
Remove all entries from table.
static const dictionary null
An empty dictionary, which is also the parent for all dictionaries.
static const word null
An empty word.
errorManip< error > abort(error &err)
Write edge/points (optionally with fields) as a vtp file or a legacy vtk file.
static void vtkWritePatchEdges(const PatchType &p, const labelList &selectEdges, const fileName &outputPath, const word &outputName)
virtual bool beginCellData(label nFields=0)
Begin CellData output section for specified number of fields.
bool empty() const noexcept
True if the hash table is empty.
int debug
Static debugging option.
const faBoundaryMesh & boundary() const noexcept
Return constant reference to boundary mesh.
#define WarningInFunction
Report a warning using Foam::Warning.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
void close()
End the file contents and close the file after writing.
const std::string patch
OpenFOAM patch number as a std::string.
List< label > sortedToc(const UList< bool > &bools)
Return the (sorted) values corresponding to 'true' entries.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool writeGeometry()
Write patch topology.
void transfer(PtrList< T > &list)
Transfer into this list and annul the argument list.
List< label > labelList
A List of labels.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
#define InfoInFunction
Report an information message using Foam::Info.