faPatch.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2017 Wikki Ltd
9  Copyright (C) 2019-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "faPatch.H"
31 #include "faBoundaryMesh.H"
32 #include "faMesh.H"
33 #include "areaFields.H"
34 #include "edgeFields.H"
35 #include "edgeHashes.H"
36 #include "polyMesh.H"
37 #include "polyPatch.H"
38 //#include "pointPatchField.H"
39 #include "demandDrivenData.H"
40 
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45  defineTypeNameAndDebug(faPatch, 0);
48 }
49 
50 
51 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
52 
53 bool Foam::faPatch::constraintType(const word& patchType)
54 {
55  // Reasonable to expect any faPatch constraint has an identically
56  // named polyPatch/pointPatch equivalent
57 
58  return polyPatch::constraintType(patchType);
59 }
60 
61 
63 {
64  const auto& cnstrTable = *dictionaryConstructorTablePtr_;
65 
66  wordList cTypes(cnstrTable.size());
67 
68  label i = 0;
69 
70  forAllConstIters(cnstrTable, iter)
71  {
72  if (constraintType(iter.key()))
73  {
74  cTypes[i++] = iter.key();
75  }
76  }
77 
78  cTypes.resize(i);
79 
80  return cTypes;
81 }
82 
83 
84 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
85 
86 void Foam::faPatch::clearOut()
87 {
88  deleteDemandDrivenData(edgeFacesPtr_);
89  deleteDemandDrivenData(pointLabelsPtr_);
90  deleteDemandDrivenData(pointEdgesPtr_);
91 }
92 
93 
94 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
95 
96 Foam::faPatch::faPatch
97 (
98  const word& name,
99  const labelUList& edgeLabels,
100  const label index,
101  const faBoundaryMesh& bm,
102  const label nbrPolyPatchi,
103  const word& patchType
104 )
105 :
106  patchIdentifier(name, index),
107  labelList(edgeLabels),
108  nbrPolyPatchId_(nbrPolyPatchi),
109  boundaryMesh_(bm),
110  edgeFacesPtr_(nullptr),
111  pointLabelsPtr_(nullptr),
112  pointEdgesPtr_(nullptr)
113 {
114  if (constraintType(patchType))
115  {
116  inGroups().appendUniq(patchType);
117  }
118 }
119 
120 
121 Foam::faPatch::faPatch
122 (
123  const word& name,
124  const dictionary& dict,
125  const label index,
126  const faBoundaryMesh& bm,
127  const word& patchType
128 )
129 :
130  patchIdentifier(name, dict, index),
131  labelList(dict.get<labelList>("edgeLabels")),
132  nbrPolyPatchId_(dict.get<label>("ngbPolyPatchIndex")),
133  boundaryMesh_(bm),
134  edgeFacesPtr_(nullptr),
135  pointLabelsPtr_(nullptr),
136  pointEdgesPtr_(nullptr)
137 {
138  if (constraintType(patchType))
139  {
140  inGroups().appendUniq(patchType);
141  }
142 }
143 
144 
145 Foam::faPatch::faPatch
146 (
147  const faPatch& p,
148  const faBoundaryMesh& bm,
149  const label index,
150  const labelUList& edgeLabels,
151  const label nbrPolyPatchi
152 )
153 :
154  patchIdentifier(p, index),
155  labelList(edgeLabels),
156  nbrPolyPatchId_(p.nbrPolyPatchId_),
157  boundaryMesh_(bm),
158  edgeFacesPtr_(nullptr),
159  pointLabelsPtr_(nullptr),
160  pointEdgesPtr_(nullptr)
161 {}
162 
163 
164 Foam::faPatch::faPatch
165 (
166  const faPatch& p,
167  const faBoundaryMesh& bm
168 )
169 :
170  faPatch
171  (
172  p,
173  bm,
174  p.index(),
175  p.edgeLabels(),
176  p.nbrPolyPatchId_
177  )
178 {}
179 
180 
181 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
182 
184 {
185  clearOut();
186 }
187 
188 
189 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
192 {
193  return boundaryMesh_;
194 }
195 
197 Foam::label Foam::faPatch::start() const
198 {
199  return boundaryMesh().mesh().patchStarts()[index()];
200 }
201 
202 
204 {
205  const auto& connections = boundaryMesh().mesh().boundaryConnections();
206  const label nInternalEdges = boundaryMesh().mesh().nInternalEdges();
207 
208  List<labelPair> output(this->nEdges());
209 
210  // Like an IndirectList but removing the nInternalEdges offset
211  label count = 0;
212  for (const label patchEdgei : this->edgeLabels())
213  {
214  const label bndEdgei = (patchEdgei - nInternalEdges);
215  output[count] = connections[bndEdgei];
216  ++count;
217  }
218 
219  return output;
220 }
221 
222 
224 {
225  const auto& connections = boundaryMesh().mesh().boundaryConnections();
226  const label nInternalEdges = boundaryMesh().mesh().nInternalEdges();
227 
228  labelHashSet procsUsed(2*Pstream::nProcs());
229 
230  for (const label patchEdgei : this->edgeLabels())
231  {
232  const label bndEdgei = (patchEdgei - nInternalEdges);
233  const label proci = connections[bndEdgei].first();
234  procsUsed.insert(proci);
235  }
236  procsUsed.erase(-1); // placeholder value
237  procsUsed.erase(Pstream::myProcNo());
238 
239  return procsUsed.sortedToc();
240 }
241 
242 
244 {
245  const auto& connections = boundaryMesh().mesh().boundaryConnections();
246  const label nInternalEdges = boundaryMesh().mesh().nInternalEdges();
247 
248  Map<label> procCount(2*Pstream::nProcs());
249 
250  for (const label patchEdgei : this->edgeLabels())
251  {
252  const label bndEdgei = (patchEdgei - nInternalEdges);
253  const label proci = connections[bndEdgei].first();
254  ++procCount(proci);
255  }
256  procCount.erase(-1); // placeholder value
257  procCount.erase(Pstream::myProcNo());
258 
259  // Flatten as list
260  List<labelPair> output(procCount.size());
261  label count = 0;
262  for (const label proci : procCount.sortedToc())
263  {
264  output[count].first() = proci;
265  output[count].second() = procCount[proci]; // size
266  ++count;
267  }
268 
269  return output;
270 }
271 
272 
274 {
275  if (!pointLabelsPtr_)
276  {
277  calcPointLabels();
278  }
279 
280  return *pointLabelsPtr_;
281 }
282 
283 
285 {
286  if (!pointEdgesPtr_)
287  {
288  calcPointEdges();
289  }
290 
291  return *pointEdgesPtr_;
292 }
293 
294 
296 {
297  const edgeList::subList edges = patchSlice(boundaryMesh().mesh().edges());
298 
299  // Walk boundary edges.
300  // The edge orientation corresponds to the face orientation
301  // (outwards normal).
302 
303  // Note: could combine this with calcPointEdges for more efficiency
304 
305  // Map<label> markedPoints(4*edges.size());
306  labelHashSet markedPoints(4*edges.size());
307  DynamicList<label> dynEdgePoints(2*edges.size());
308 
309  for (const edge& e : edges)
310  {
311  // if (markedPoints.insert(e.first(), markedPoints.size()))
312  if (markedPoints.insert(e.first()))
313  {
314  dynEdgePoints.append(e.first());
315  }
316  // if (markedPoints.insert(e.second(), markedPoints.size()))
317  if (markedPoints.insert(e.second()))
318  {
319  dynEdgePoints.append(e.second());
320  }
321  }
322 
323  // Transfer to plain list (reuse storage)
324  pointLabelsPtr_ = new labelList(std::move(dynEdgePoints));
349 }
350 
351 
353 {
354  const edgeList::subList edges = patchSlice(boundaryMesh().mesh().edges());
355 
356  const labelList& edgePoints = pointLabels();
357 
358  // Cannot use invertManyToMany - we have non-local edge numbering
359 
360  // Intermediate storage for pointEdges.
361  // Points on the boundary will normally connect 1 or 2 edges only.
362  List<DynamicList<label,2>> dynPointEdges(edgePoints.size());
363 
364  forAll(edges, edgei)
365  {
366  const edge& e = edges[edgei];
367 
368  dynPointEdges[edgePoints.find(e.first())].append(edgei);
369  dynPointEdges[edgePoints.find(e.second())].append(edgei);
370  }
371 
372  // Flatten to regular list
373  pointEdgesPtr_ = new labelListList(edgePoints.size());
374  auto& pEdges = *pointEdgesPtr_;
375 
376  forAll(pEdges, pointi)
377  {
378  pEdges[pointi] = std::move(dynPointEdges[pointi]);
379  }
380 }
381 
382 
384 {
385  if (nbrPolyPatchId_ < 0)
386  {
388  }
389 
390  return boundaryMesh().mesh().haloFaceNormals(this->index());
391 }
392 
393 
395 {
396  if (nbrPolyPatchId_ < 0)
397  {
398  return tmp<vectorField>::New();
399  }
400 
401  // Unit normals for the neighbour patch faces
402  const vectorField faceNormals
403  (
404  boundaryMesh().mesh().haloFaceNormals(this->index())
405  );
406 
407  const labelListList& pntEdges = pointEdges();
408 
409  auto tpointNorm = tmp<vectorField>::New(pntEdges.size());
410  auto& pointNorm = tpointNorm.ref();
411 
412  forAll(pointNorm, pointi)
413  {
414  vector& n = pointNorm[pointi];
415  n = Zero;
416 
417  for (const label bndEdgei : pntEdges[pointi])
418  {
419  n += faceNormals[bndEdgei];
420  }
421 
422  n.normalise();
423  }
424 
425  return tpointNorm;
426 }
427 
428 
430 {
431  if (!edgeFacesPtr_)
432  {
433  edgeFacesPtr_ = new labelList::subList
434  (
435  patchSlice(boundaryMesh().mesh().edgeOwner())
436  );
437  }
438 
439  return *edgeFacesPtr_;
440 }
441 
444 {
445  return boundaryMesh().mesh().edgeCentres().boundaryField()[index()];
446 }
447 
450 {
451  return boundaryMesh().mesh().Le().boundaryField()[index()];
452 }
453 
456 {
457  return boundaryMesh().mesh().magLe().boundaryField()[index()];
458 }
459 
460 
462 {
463  auto tedgeNorm = tmp<vectorField>::New(edgeLengths());
465  tedgeNorm.ref().normalise();
466 
467  return tedgeNorm;
468 }
469 
472 {
473  return patchInternalField(boundaryMesh().mesh().areaCentres());
474 }
475 
476 
478 {
479  // Use patch-normal delta for all non-coupled BCs
480  const vectorField nHat(edgeNormals());
481 
482  vectorField edgePN(edgeCentres() - edgeFaceCentres());
483 
484  // Do not allow any mag(val) < SMALL
485  for (vector& edgei : edgePN)
486  {
487  if (mag(edgei) < SMALL)
488  {
489  edgei = vector::uniform(SMALL);
490  }
491  }
492 
493  return nHat*(nHat & edgePN);
494 }
495 
498 {
499  dc = scalar(1)/(edgeNormals() & delta());
500 }
501 
502 
504 {
505  vectorField unitDelta(delta()/mag(delta()));
506  vectorField edgeNormMag(edgeNormals()/mag(edgeNormals()));
507  scalarField dn(edgeNormals() & delta());
508 
509  k = edgeNormMag - (scalar(1)/(unitDelta & edgeNormMag))*unitDelta;
510 }
511 
514 {
515  return boundaryMesh().mesh().deltaCoeffs().boundaryField()[index()];
516 }
517 
520 {
521  w = scalar(1);
522 }
523 
526 {
527  return boundaryMesh().mesh().weights().boundaryField()[index()];
528 }
529 
530 
532 {}
533 
534 
536 {
537  clearOut();
538  static_cast<labelList&>(*this) = newEdges;
539 }
540 
541 
543 {
544  clearOut();
545  static_cast<labelList&>(*this) = std::move(newEdges);
546 }
547 
548 
549 void Foam::faPatch::write(Ostream& os) const
550 {
551  os.writeEntry("type", type());
552 
554 
555  os.writeEntry("ngbPolyPatchIndex", nbrPolyPatchId_);
556  static_cast<const labelList&>(*this).writeEntry("edgeLabels", os);
557 }
558 
559 
560 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
561 
562 Foam::Ostream& Foam::operator<<(Ostream& os, const faPatch& p)
563 {
564  p.write(os);
566  return os;
567 }
568 
569 
570 // ************************************************************************* //
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
scalar delta
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:51
dictionary dict
const scalarField & weights() const
Return patch weighting factors.
Definition: faPatch.C:518
virtual tmp< vectorField > delta() const
Return cell-centre to face-centre vector.
Definition: faPatch.C:470
void write(Ostream &os) const
Write (physicalType, inGroups) dictionary entries (without surrounding braces)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
labelList pointLabels(nPoints, -1)
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:45
const scalarField & deltaCoeffs() const
Return patch edge - neighbour face distances.
Definition: faPatch.C:506
Identifies a patch by name and index, with optional physical type and group information.
static bool constraintType(const word &patchType)
Return true if the given type is a constraint type.
Definition: faPatch.C:46
const wordList & inGroups() const noexcept
The (optional) groups that the patch belongs to.
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Definition: boundaryMesh.H:58
label appendUniq(const T &val)
Append an element if not already in the list.
Definition: List.H:526
const labelList & pointLabels() const
Return patch point labels.
Definition: faPatch.C:266
label nInternalEdges() const
Number of internal edges.
virtual void makeDeltaCoeffs(scalarField &) const
Make patch edge - neighbour face distances.
Definition: faPatch.C:490
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:312
label size() const noexcept
The number of elements in table.
Definition: HashTableI.H:45
const scalarField & magEdgeLengths() const
Return edge length magnitudes.
Definition: faPatch.C:448
SubList< edge > subList
Declare type of subList.
Definition: List.H:122
label k
Boltzmann constant.
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:688
Macros for easy insertion into run-time selection tables.
UList< label > labelUList
A UList of labels.
Definition: UList.H:80
List< labelPair > boundaryProcSizes() const
List of proc/size for the boundary edge neighbour processors (does not include own proc) ...
Definition: faPatch.C:236
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
static wordList constraintTypes()
Return a list of all the constraint patch types.
Definition: faPatch.C:55
void makeCorrectionVectors(vectorField &) const
Definition: faPatch.C:496
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition: HashSet.H:85
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:752
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator) is 1 for serial run.
Definition: UPstream.H:656
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
const vectorField & edgeCentres() const
Return edge centres.
Definition: faPatch.C:436
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
tmp< vectorField > edgeFaceCentres() const
Return neighbour face centres.
Definition: faPatch.C:464
void calcPointLabels() const
Calculate patch point labels.
Definition: faPatch.C:288
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual void write(Ostream &) const
Write.
Definition: faPatch.C:542
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:203
Vector< scalar > vector
Definition: vector.H:57
const labelUList & edgeFaces() const
Return edge-face addressing.
Definition: faPatch.C:422
tmp< vectorField > edgeNormals() const
Return edge normals.
Definition: faPatch.C:454
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
const direction noexcept
Definition: Scalar.H:258
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
labelList boundaryProcs() const
Boundary edge neighbour processors (does not include own proc)
Definition: faPatch.C:216
defineTypeNameAndDebug(combustionModel, 0)
List< labelPair > boundaryConnections() const
List of proc/face for the boundary edge neighbours in locally reordered edge numbering.
Definition: faPatch.C:196
Finite area patch class. Used for 2-D non-Euclidian finite area method.
Definition: faPatch.H:72
label start() const
Patch start in edge list.
Definition: faPatch.C:190
Buffers for inter-processor communications streams (UOPstream, UIPstream).
virtual ~faPatch()
Destructor.
Definition: faPatch.C:176
addToRunTimeSelectionTable(decompositionMethod, kahipDecomp, dictionary)
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
Definition: HashTable.C:433
tmp< vectorField > ngbPolyPatchPointNormals() const
Return normals of neighbour polyPatch joined points.
Definition: faPatch.C:387
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:76
Template functions to aid in the implementation of demand driven data.
rAUs append(new volScalarField(IOobject::groupName("rAU", phase1.name()), 1.0/(U1Eqn.A()+byDt(max(phase1.residualAlpha() - alpha1, scalar(0)) *rho1))))
virtual void makeWeights(scalarField &) const
Make patch weighting factors.
Definition: faPatch.C:512
static bool constraintType(const word &patchType)
Return true if the given type is a constraint type.
Definition: polyPatch.C:270
const vectorField & edgeLengths() const
Return edge length vectors.
Definition: faPatch.C:442
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:130
Finite area boundary mesh.
const labelListList & pointEdges() const
Return patch point-edge addressing.
Definition: faPatch.C:277
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:59
label n
void writeEntry(Ostream &os) const
Write the UList with its compound type.
Definition: UListIO.C:31
Field< vector > vectorField
Specialisation of Field<T> for vector.
const bMesh & mesh() const
Definition: boundaryMesh.H:259
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
virtual bool write(const bool valid=true) const
Write using setting from DB.
void deleteDemandDrivenData(DataPtr &dataPtr)
tmp< vectorField > ngbPolyPatchFaceNormals() const
Return normals of neighbour polyPatch faces.
Definition: faPatch.C:376
virtual void movePoints(PstreamBuffers &, const pointField &)
Correct patch after moving points.
Definition: faPatch.C:524
void calcPointEdges() const
Calculate patch point-edge addressing.
Definition: faPatch.C:345
void resetEdges(const labelUList &newEdges)
Reset the list of edges (use with caution)
Definition: faPatch.C:528
const faBoundaryMesh & boundaryMesh() const noexcept
Return boundaryMesh reference.
Definition: faPatch.C:184
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:157