nonConformalBoundary.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2022-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "nonConformalBoundary.H"
29 #include "syncTools.H"
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 
36 template<class FaceList, class PointField>
37 edge meshEdge
38 (
39  const PrimitivePatch<FaceList, PointField>& p,
40  const label edgei
41 )
42 {
43  return edge
44  (
45  p.meshPoints()[p.edges()[edgei][0]],
46  p.meshPoints()[p.edges()[edgei][1]]
47  );
48 }
49 
50 }
51 
52 
53 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
54 
55 namespace Foam
56 {
58 }
59 
60 
61 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
62 
64 Foam::nonConformalBoundary::boundary(const labelList& patches) const
65 {
66  DynamicList<label> faces;
67  forAll(patches, i)
68  {
69  const polyPatch& pp = mesh().boundaryMesh()[patches[i]];
70 
71  faces.append(identityMap(pp.size()) + pp.start());
72  }
73 
74  return
76  (
77  IndirectList<face>(mesh().faces(), faces),
78  mesh().points()
79  );
80 }
81 
82 
83 const Foam::labelList&
84 Foam::nonConformalBoundary::meshPointOwnerOrigBoundaryPoint() const
85 {
86  if (!meshPointOwnerOrigBoundaryPointPtr_.valid())
87  {
88  meshPointOwnerOrigBoundaryPointPtr_.set
89  (
90  new labelList(mesh().nPoints(), -1)
91  );
92 
93  forAll(ownerOrigBoundary_.meshPoints(), ownerOrigBoundaryPointi)
94  {
95  meshPointOwnerOrigBoundaryPointPtr_()
96  [ownerOrigBoundary_.meshPoints()[ownerOrigBoundaryPointi]] =
97  ownerOrigBoundaryPointi;
98  }
99  }
100 
101  return meshPointOwnerOrigBoundaryPointPtr_();
102 }
103 
104 
105 const Foam::vectorField&
106 Foam::nonConformalBoundary::ownerOrigBoundaryPointNormals() const
107 {
108  if (!ownerOrigBoundaryPointNormalsPtr_.valid())
109  {
110  const faceList& faces = ownerOrigBoundary_.localFaces();
111  const vectorField faceNormals = ownerOrigBoundary_.faceNormals();
112 
113  vectorField pointNormals(ownerOrigBoundary_.nPoints(), Zero);
114 
115  forAll(faces, facei)
116  {
117  forAll(faces[facei], facePointi)
118  {
119  pointNormals[faces[facei][facePointi]] += faceNormals[facei];
120  }
121  }
122 
124  (
125  mesh(),
126  ownerOrigBoundary_.meshPoints(),
127  pointNormals,
128  plusEqOp<vector>(),
130  );
131 
132  ownerOrigBoundaryPointNormalsPtr_.set
133  (
134  (pointNormals/(mag(pointNormals) + vSmall)).ptr()
135  );
136  }
137 
138  return ownerOrigBoundaryPointNormalsPtr_();
139 }
140 
141 
142 const Foam::vectorField&
143 Foam::nonConformalBoundary::ownerOrigBoundaryPointNormals0() const
144 {
145  if (!ownerOrigBoundaryPointNormals0Ptr_.valid())
146  {
147  const faceList& faces = ownerOrigBoundary_.localFaces();
148 
149  vectorField pointNormals(ownerOrigBoundary_.nPoints(), Zero);
150 
151  forAll(faces, facei)
152  {
153  forAll(faces[facei], facePointi)
154  {
155  pointNormals[faces[facei][facePointi]] +=
156  faces[facei].normal(mesh().oldPoints());
157  }
158  }
159 
161  (
162  mesh(),
163  ownerOrigBoundary_.meshPoints(),
164  pointNormals,
165  plusEqOp<vector>(),
167  );
168 
169  ownerOrigBoundaryPointNormals0Ptr_.set
170  (
171  (pointNormals/(mag(pointNormals) + vSmall)).ptr()
172  );
173  }
174 
175  return ownerOrigBoundaryPointNormals0Ptr_();
176 }
177 
178 
179 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
180 
182 :
184  <
185  polyMesh,
188  >(mesh),
189  ownerOrigBoundary_(boundary(ownerOrigPatchIDs())),
190  meshPointOwnerOrigBoundaryPointPtr_(nullptr),
191  ownerOrigBoundaryPointMeshPointPtr_(nullptr),
192  ownerOrigBoundaryEdgeMeshEdgePtr_(nullptr),
193  ownerOrigBoundaryEdgesPtr_(nullptr),
194  ownerOrigBoundaryMeshEdgesPtr_(nullptr),
195  patchPointOwnerOrigBoundaryPointsPtr_(mesh.boundaryMesh().size()),
196  patchEdgeOwnerOrigBoundaryEdgesPtr_(mesh.boundaryMesh().size()),
197  ownerOrigBoundaryPointNormalsPtr_(nullptr)
198 {
199 }
200 
201 
202 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
203 
205 {}
206 
207 
208 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
209 
211 {
212  ownerOrigBoundary_.clearGeom();
213 
214  ownerOrigBoundaryPointNormalsPtr_.clear();
215 
216  return true;
217 }
218 
219 
221 (
222  const label side,
223  label (nonConformalCoupledPolyPatch::*method)() const
224 ) const
225 {
226  const polyBoundaryMesh& pbm = mesh().boundaryMesh();
227 
228  labelHashSet origPatchIDTable;
229  DynamicList<label> nonCoupledPatchIDs(pbm.size());
230 
231  forAll(pbm, nccPatchi)
232  {
233  const polyPatch& pp = pbm[nccPatchi];
234 
235  if (isA<nonConformalCoupledPolyPatch>(pp))
236  {
237  const nonConformalCoupledPolyPatch& nccPp =
238  refCast<const nonConformalCoupledPolyPatch>(pbm[nccPatchi]);
239 
240  if (side == 1 && !nccPp.owner()) continue;
241 
242  if (side == -1 && !nccPp.neighbour()) continue;
243 
244  if (origPatchIDTable.found(nccPp.origPatchID())) continue;
245 
246  origPatchIDTable.insert(nccPp.origPatchID());
247  nonCoupledPatchIDs.append((nccPp.*method)());
248  }
249  }
250 
251  labelList result;
252  result.transfer(nonCoupledPatchIDs);
253  return result;
254 }
255 
256 
258 {
260  return nonConformalNonCoupledPatchIDs(0, method);
261 }
262 
263 
265 {
267  return nonConformalNonCoupledPatchIDs(0, method);
268 }
269 
270 
272 {
274  return nonConformalNonCoupledPatchIDs(1, method);
275 }
276 
277 
279 {
281  return nonConformalNonCoupledPatchIDs(1, method);
282 }
283 
284 
285 const Foam::labelList&
287 {
288  if (!ownerOrigBoundaryPointMeshPointPtr_.valid())
289  {
290  ownerOrigBoundaryPointMeshPointPtr_.set
291  (
292  new labelList(ownerOrigBoundary_.meshPoints())
293  );
294 
295  // ...
296  meshPointOwnerOrigBoundaryPoint();
297  labelList& map = meshPointOwnerOrigBoundaryPointPtr_();
298 
299  // ...
300  label ownerOrigBoundaryPointi = ownerOrigBoundary_.nPoints();
301  DynamicList<label> remotePoints;
302 
303  // ...
304  for
305  (
306  label ownerOrigBoundaryEdgei = ownerOrigBoundary_.nEdges();
307  ownerOrigBoundaryEdgei < ownerOrigBoundaryEdgeMeshEdge().size();
308  ++ ownerOrigBoundaryEdgei
309  )
310  {
311  const label meshEdgei =
312  ownerOrigBoundaryEdgeMeshEdge()[ownerOrigBoundaryEdgei];
313 
314  const edge& e = mesh().edges()[meshEdgei];
315 
316  forAll(e, i)
317  {
318  const label meshPointi = e[i];
319 
320  if (map[meshPointi] == -1)
321  {
322  map[meshPointi] = ownerOrigBoundaryPointi ++;
323  remotePoints.append(meshPointi);
324  }
325  }
326  }
327 
328  // ...
329  ownerOrigBoundaryPointMeshPointPtr_->append(remotePoints);
330  }
331 
332  return ownerOrigBoundaryPointMeshPointPtr_();
333 }
334 
335 
336 const Foam::labelList&
338 {
339  if (!ownerOrigBoundaryEdgeMeshEdgePtr_.valid())
340  {
341  // Create boundary of all owner-orig and proc patches
342  labelList ownerOrigAndProcPatchIDs = this->ownerOrigPatchIDs();
343  forAll(mesh().boundaryMesh(), patchi)
344  {
345  if (isA<processorPolyPatch>(mesh().boundaryMesh()[patchi]))
346  {
347  ownerOrigAndProcPatchIDs.append(patchi);
348  }
349  }
350  const indirectPrimitivePatch ownerOrigAndProcBoundary
351  (
352  boundary(ownerOrigAndProcPatchIDs)
353  );
354 
355  // Create the mesh edge mapping for the owner-orig-and-proc boundary
356  labelList ownerOrigAndProcBoundaryMeshEdges
357  (
358  ownerOrigAndProcBoundary.meshEdges
359  (
360  mesh().edges(),
361  mesh().pointEdges()
362  )
363  );
364 
365  // Map from owner-orig to owner-orig-and-proc edge
366  const labelList map =
368  (
370  (
371  ownerOrigAndProcBoundary.localFaces(),
372  ownerOrigBoundary_.size()
373  ),
374  ownerOrigAndProcBoundary.localPoints()
375  )
376  .meshEdges
377  (
378  ownerOrigAndProcBoundary.edges(),
379  ownerOrigAndProcBoundary.pointEdges()
380  );
381 
382  // Initialise the mapping for the owner-orig boundary. Note, this only
383  // connects edges that are part of the local owner-orig boundary. Edges
384  // that are connected to the owner-orig boundary on a different process
385  // are added below.
386  ownerOrigBoundaryEdgeMeshEdgePtr_.set
387  (
388  new labelList
389  (
390  labelField(ownerOrigAndProcBoundaryMeshEdges, map)
391  )
392  );
393 
394  // Create a reverse map from owner-orig-and-proc to owner-orig edge
395  labelList rMap(ownerOrigAndProcBoundary.nEdges(), -1);
396  forAll(map, i)
397  {
398  rMap[map[i]] = i;
399  }
400 
401  // Synchronise
403  (
404  mesh(),
405  ownerOrigAndProcBoundaryMeshEdges,
406  rMap,
407  maxEqOp<label>(),
408  label(-1)
409  );
410 
411  // Remove all local indexing from the map
412  forAll(map, i)
413  {
414  rMap[map[i]] = -1;
415  }
416 
417  // Any valid rMap entries now refer to edges that are remotely
418  // connected to the owner-orig boundary. Append them to the addressing.
419  DynamicList<label> remoteMeshEdges;
420  forAll(rMap, i)
421  {
422  if (rMap[i] != -1)
423  {
424  remoteMeshEdges.append(ownerOrigAndProcBoundaryMeshEdges[i]);
425  }
426  }
427 
428  ownerOrigBoundaryEdgeMeshEdgePtr_->append(remoteMeshEdges);
429  }
430 
431  return ownerOrigBoundaryEdgeMeshEdgePtr_();
432 }
433 
434 
435 const Foam::edgeList&
437 {
438  if (!ownerOrigBoundaryEdgesPtr_.valid())
439  {
440  ownerOrigBoundaryEdgesPtr_.set
441  (
442  new edgeList(ownerOrigBoundary_.edges())
443  );
444 
445  const labelList& map = meshPointOwnerOrigBoundaryPoint();
446 
447  DynamicList<edge> remoteEdges;
448 
449  for
450  (
451  label ownerOrigBoundaryEdgei = ownerOrigBoundary_.nEdges();
452  ownerOrigBoundaryEdgei < ownerOrigBoundaryEdgeMeshEdge().size();
453  ++ ownerOrigBoundaryEdgei
454  )
455  {
456  const label meshEdgei =
457  ownerOrigBoundaryEdgeMeshEdge()[ownerOrigBoundaryEdgei];
458 
459  const edge& e = mesh().edges()[meshEdgei];
460 
461  remoteEdges.append(edge(map[e.start()], map[e.end()]));
462  }
463 
464  ownerOrigBoundaryEdgesPtr_->append(remoteEdges);
465  }
466 
467  return ownerOrigBoundaryEdgesPtr_();
468 }
469 
470 
471 const Foam::edgeList&
473 {
474  if (!ownerOrigBoundaryMeshEdgesPtr_.valid())
475  {
476  const edgeList& edges = ownerOrigBoundaryEdges();
477 
478  const labelList& pointMeshPoint =
479  ownerOrigBoundaryPointMeshPoint();
480 
481  ownerOrigBoundaryMeshEdgesPtr_.set
482  (
483  new edgeList(edges.size())
484  );
485 
486  forAll(edges, edgei)
487  {
488  ownerOrigBoundaryMeshEdgesPtr_()[edgei] =
489  edge
490  (
491  pointMeshPoint[edges[edgei].start()],
492  pointMeshPoint[edges[edgei].end()]
493  );
494  }
495  }
496 
497  return ownerOrigBoundaryMeshEdgesPtr_();
498 }
499 
500 
501 const Foam::labelList&
503 (
504  const label patchi
505 ) const
506 {
507  if (!patchPointOwnerOrigBoundaryPointsPtr_.set(patchi))
508  {
509  const polyPatch& pp = mesh().boundaryMesh()[patchi];
510 
511  const faceList patchOwnerOrigBoundaryLocalFaces
512  (
513  renumber
514  (
515  meshPointOwnerOrigBoundaryPoint(),
516  static_cast<const faceList&>(pp)
517  )
518  );
519 
520  const primitivePatch ownerOrigBoundaryLocalPatch
521  (
522  SubList<face>(patchOwnerOrigBoundaryLocalFaces, pp.size()),
523  ownerOrigBoundary_.localPoints()
524  );
525 
526  patchPointOwnerOrigBoundaryPointsPtr_.set
527  (
528  patchi,
529  new labelList(ownerOrigBoundaryLocalPatch.meshPoints())
530  );
531 
532  patchEdgeOwnerOrigBoundaryEdgesPtr_.set
533  (
534  patchi,
535  new labelList
536  (
537  ownerOrigBoundaryLocalPatch.meshEdges
538  (
539  ownerOrigBoundary_.edges(),
540  ownerOrigBoundary_.pointEdges()
541  )
542  )
543  );
544 
545  // Check the addressing is valid
546  if (debug)
547  {
548  const labelList& ppPointOwnerOrigBoundaryPoints =
549  patchPointOwnerOrigBoundaryPointsPtr_[patchi];
550 
551  forAll(pp.meshPoints(), ppPointi)
552  {
553  const label ownerOrigBoundaryPointi =
554  ppPointOwnerOrigBoundaryPoints[ppPointi];
555 
556  if
557  (
558  pp.meshPoints()[ppPointi]
559  != ownerOrigBoundary_.meshPoints()[ownerOrigBoundaryPointi]
560  )
561  {
563  << "Patch point does not match all boundary point"
564  << exit(FatalError);
565  }
566  }
567 
568  const labelList& ppEdgeOwnerOrigBoundaryEdges =
569  patchEdgeOwnerOrigBoundaryEdgesPtr_[patchi];
570 
571  forAll(pp.edges(), ppEdgei)
572  {
573  const label ownerOrigBoundaryEdgei =
574  ppEdgeOwnerOrigBoundaryEdges[ppEdgei];
575 
576  if
577  (
578  meshEdge(pp, ppEdgei)
579  != meshEdge(ownerOrigBoundary_, ownerOrigBoundaryEdgei)
580  )
581  {
583  << "Patch edge does not match all boundary edge"
584  << exit(FatalError);
585  }
586  }
587  }
588  }
589 
590  return patchPointOwnerOrigBoundaryPointsPtr_[patchi];
591 }
592 
593 
594 const Foam::labelList&
596 (
597  const label patchi
598 ) const
599 {
600  if (!patchEdgeOwnerOrigBoundaryEdgesPtr_.set(patchi))
601  {
602  patchPointOwnerOrigBoundaryPoints(patchi);
603  }
604 
605  return patchEdgeOwnerOrigBoundaryEdgesPtr_[patchi];
606 }
607 
608 
611 {
612  return
614  (
615  new vectorField
616  (
618  (
619  ownerOrigBoundaryPointNormals(),
620  patchPointOwnerOrigBoundaryPoints(patchi)
621  )
622  )
623  );
624 }
625 
626 
629 {
630  return
632  (
633  new vectorField
634  (
636  (
637  ownerOrigBoundaryPointNormals0(),
638  patchPointOwnerOrigBoundaryPoints(patchi)
639  )
640  )
641  );
642 }
643 
644 
645 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Templated abstract base-class for demand-driven mesh objects used to automate their allocation to the...
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:111
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:113
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label nEdges() const
Return number of edges in patch.
const labelListList & pointEdges() const
Return point-edge addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using.
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
void append(T *)
Append an element at the end of the list.
Definition: PtrListI.H:39
A List obtained as a section of another List.
Definition: SubList.H:56
A List with indirect addressing.
Definition: UIndirectList.H:60
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
static const Form zero
Definition: VectorSpace.H:113
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:61
Mesh object that stores an all boundary patch and mapping to and from it and the mesh and the individ...
virtual bool movePoints()
Update for mesh motion.
labelList ownerOrigPatchIDs() const
Return a list of the owner-orig patch indices.
labelList allErrorPatchIDs() const
Return a list of the error patch indices.
labelList allOrigPatchIDs() const
Return a list of the orig patch indices.
const edgeList & ownerOrigBoundaryMeshEdges() const
Get the owner-orig boundary edges, referring to mesh points.
tmp< vectorField > patchPointNormals(const label patchi) const
Get parallel consistent point normals for the patch.
const labelList & patchEdgeOwnerOrigBoundaryEdges(const label patchi) const
Get a map from patch edge to owner-orig boundary edge.
nonConformalBoundary(const polyMesh &mesh)
Construct from mesh.
const labelList & ownerOrigBoundaryEdgeMeshEdge() const
Get a map from owner-orig boundary edge to mesh edge.
labelList ownerErrorPatchIDs() const
Return a list of the owner error patch indices.
const labelList & patchPointOwnerOrigBoundaryPoints(const label patchi) const
Get a map from patch point to owner-orig boundary point.
tmp< vectorField > patchPointNormals0(const label patchi) const
Get parallel consistent old-time point normals for the patch.
labelList nonConformalNonCoupledPatchIDs(const label side, label(nonConformalCoupledPolyPatch::*method)() const) const
Return a list of non-conformal non-coupled patch indices.
const labelList & ownerOrigBoundaryPointMeshPoint() const
Get a map from owner-orig boundary point to mesh point.
const edgeList & ownerOrigBoundaryEdges() const
Get the owner-orig boundary edges, referring to boundary points.
Non-conformal coupled poly patch. As nonConformalPolyPatch, but this patch is coupled to another non-...
bool owner() const
Does this side own the patch?
bool neighbour() const
Does the coupled side own the patch?
label origPatchID() const
Original patchID.
Foam::polyBoundaryMesh.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:403
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:70
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:270
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronise values on all mesh points.
static void syncEdgeList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronise values on all mesh edges.
A class for managing temporary objects.
Definition: tmp.H:55
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
label patchi
const pointField & points
label nPoints
const fvPatchList & patches
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static const zero Zero
Definition: zero.H:97
const doubleScalar e
Definition: doubleScalar.H:105
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
Addressing for a faceList slice.
edge meshEdge(const PrimitivePatch< FaceList, PointField > &p, const label edgei)
dimensioned< scalar > mag(const dimensioned< Type > &)
defineTypeNameAndDebug(combustionModel, 0)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:49
error FatalError
List< edge > edgeList
Definition: edgeList.H:38
labelList identityMap(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
List< face > faceList
Definition: faceListFwd.H:43
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
faceListList boundary(nPatches)
volScalarField & p