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 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 {
57  defineTypeNameAndDebug(nonConformalBoundary, 0);
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(identity(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  ownerOrigBoundary_(boundary(ownerOrigPatchIDs())),
185  meshPointOwnerOrigBoundaryPointPtr_(nullptr),
186  ownerOrigBoundaryPointMeshPointPtr_(nullptr),
187  ownerOrigBoundaryEdgeMeshEdgePtr_(nullptr),
188  ownerOrigBoundaryEdgesPtr_(nullptr),
189  ownerOrigBoundaryMeshEdgesPtr_(nullptr),
190  patchPointOwnerOrigBoundaryPointsPtr_(mesh.boundaryMesh().size()),
191  patchEdgeOwnerOrigBoundaryEdgesPtr_(mesh.boundaryMesh().size()),
192  ownerOrigBoundaryPointNormalsPtr_(nullptr)
193 {
194 }
195 
196 
197 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
198 
200 {}
201 
202 
203 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
204 
206 {
207  ownerOrigBoundary_.clearGeom();
208 
209  ownerOrigBoundaryPointNormalsPtr_.clear();
210 
211  return true;
212 }
213 
214 
216 (
217  const label side,
218  label (nonConformalCoupledPolyPatch::*method)() const
219 ) const
220 {
221  const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
222 
223  labelHashSet origPatchIDTable;
224  DynamicList<label> nonCoupledPatchIDs(pbm.size());
225 
226  forAll(pbm, nccPatchi)
227  {
228  const polyPatch& pp = pbm[nccPatchi];
229 
230  if (isA<nonConformalCoupledPolyPatch>(pp))
231  {
232  const nonConformalCoupledPolyPatch& nccPp =
233  refCast<const nonConformalCoupledPolyPatch>(pbm[nccPatchi]);
234 
235  if (side == 1 && !nccPp.owner()) continue;
236 
237  if (side == -1 && !nccPp.neighbour()) continue;
238 
239  if (origPatchIDTable.found(nccPp.origPatchID())) continue;
240 
241  origPatchIDTable.insert(nccPp.origPatchID());
242  nonCoupledPatchIDs.append((nccPp.*method)());
243  }
244  }
245 
246  labelList result;
247  result.transfer(nonCoupledPatchIDs);
248  return result;
249 }
250 
251 
253 {
255  return nonConformalNonCoupledPatchIDs(0, method);
256 }
257 
258 
260 {
262  return nonConformalNonCoupledPatchIDs(0, method);
263 }
264 
265 
267 {
269  return nonConformalNonCoupledPatchIDs(1, method);
270 }
271 
272 
274 {
276  return nonConformalNonCoupledPatchIDs(1, method);
277 }
278 
279 
280 const Foam::labelList&
282 {
283  if (!ownerOrigBoundaryPointMeshPointPtr_.valid())
284  {
285  ownerOrigBoundaryPointMeshPointPtr_.set
286  (
287  new labelList(ownerOrigBoundary_.meshPoints())
288  );
289 
290  // ...
291  meshPointOwnerOrigBoundaryPoint();
292  labelList& map = meshPointOwnerOrigBoundaryPointPtr_();
293 
294  // ...
295  label ownerOrigBoundaryPointi = ownerOrigBoundary_.nPoints();
296  DynamicList<label> remotePoints;
297 
298  // ...
299  for
300  (
301  label ownerOrigBoundaryEdgei = ownerOrigBoundary_.nEdges();
302  ownerOrigBoundaryEdgei < ownerOrigBoundaryEdgeMeshEdge().size();
303  ++ ownerOrigBoundaryEdgei
304  )
305  {
306  const label meshEdgei =
307  ownerOrigBoundaryEdgeMeshEdge()[ownerOrigBoundaryEdgei];
308 
309  const edge& e = mesh_.edges()[meshEdgei];
310 
311  forAll(e, i)
312  {
313  const label meshPointi = e[i];
314 
315  if (map[meshPointi] == -1)
316  {
317  map[meshPointi] = ownerOrigBoundaryPointi ++;
318  remotePoints.append(meshPointi);
319  }
320  }
321  }
322 
323  // ...
324  ownerOrigBoundaryPointMeshPointPtr_->append(remotePoints);
325  }
326 
327  return ownerOrigBoundaryPointMeshPointPtr_();
328 }
329 
330 
331 const Foam::labelList&
333 {
334  if (!ownerOrigBoundaryEdgeMeshEdgePtr_.valid())
335  {
336  // Create boundary of all owner-orig and proc patches
337  labelList ownerOrigAndProcPatchIDs = this->ownerOrigPatchIDs();
339  {
340  if (isA<processorPolyPatch>(mesh_.boundaryMesh()[patchi]))
341  {
342  ownerOrigAndProcPatchIDs.append(patchi);
343  }
344  }
345  const indirectPrimitivePatch ownerOrigAndProcBoundary
346  (
347  boundary(ownerOrigAndProcPatchIDs)
348  );
349 
350  // Create the mesh edge mapping for the owner-orig-and-proc boundary
351  labelList ownerOrigAndProcBoundaryMeshEdges
352  (
353  ownerOrigAndProcBoundary.meshEdges
354  (
355  mesh_.edges(),
356  mesh_.pointEdges()
357  )
358  );
359 
360  // Map from owner-orig to owner-orig-and-proc edge
361  const labelList map =
363  (
365  (
366  ownerOrigAndProcBoundary.localFaces(),
367  ownerOrigBoundary_.size()
368  ),
369  ownerOrigAndProcBoundary.localPoints()
370  )
371  .meshEdges
372  (
373  ownerOrigAndProcBoundary.edges(),
374  ownerOrigAndProcBoundary.pointEdges()
375  );
376 
377  // Initialise the mapping for the owner-orig boundary. Note, this only
378  // connects edges that are part of the local owner-orig boundary. Edges
379  // that are connected to the owner-orig boundary on a different process
380  // are added below.
381  ownerOrigBoundaryEdgeMeshEdgePtr_.set
382  (
383  new labelList
384  (
385  labelField(ownerOrigAndProcBoundaryMeshEdges, map)
386  )
387  );
388 
389  // Create a reverse map from owner-orig-and-proc to owner-orig edge
390  labelList rMap(ownerOrigAndProcBoundary.nEdges(), -1);
391  forAll(map, i)
392  {
393  rMap[map[i]] = i;
394  }
395 
396  // Synchronise
398  (
399  mesh_,
400  ownerOrigAndProcBoundaryMeshEdges,
401  rMap,
402  maxEqOp<label>(),
403  label(-1)
404  );
405 
406  // Remove all local indexing from the map
407  forAll(map, i)
408  {
409  rMap[map[i]] = -1;
410  }
411 
412  // Any valid rMap entries now refer to edges that are remotely
413  // connected to the owner-orig boundary. Append them to the addressing.
414  DynamicList<label> remoteMeshEdges;
415  forAll(rMap, i)
416  {
417  if (rMap[i] != -1)
418  {
419  remoteMeshEdges.append(ownerOrigAndProcBoundaryMeshEdges[i]);
420  }
421  }
422 
423  ownerOrigBoundaryEdgeMeshEdgePtr_->append(remoteMeshEdges);
424  }
425 
426  return ownerOrigBoundaryEdgeMeshEdgePtr_();
427 }
428 
429 
430 const Foam::edgeList&
432 {
433  if (!ownerOrigBoundaryEdgesPtr_.valid())
434  {
435  ownerOrigBoundaryEdgesPtr_.set
436  (
437  new edgeList(ownerOrigBoundary_.edges())
438  );
439 
440  const labelList& map = meshPointOwnerOrigBoundaryPoint();
441 
442  DynamicList<edge> remoteEdges;
443 
444  for
445  (
446  label ownerOrigBoundaryEdgei = ownerOrigBoundary_.nEdges();
447  ownerOrigBoundaryEdgei < ownerOrigBoundaryEdgeMeshEdge().size();
448  ++ ownerOrigBoundaryEdgei
449  )
450  {
451  const label meshEdgei =
452  ownerOrigBoundaryEdgeMeshEdge()[ownerOrigBoundaryEdgei];
453 
454  const edge& e = mesh_.edges()[meshEdgei];
455 
456  remoteEdges.append(edge(map[e.start()], map[e.end()]));
457  }
458 
459  ownerOrigBoundaryEdgesPtr_->append(remoteEdges);
460  }
461 
462  return ownerOrigBoundaryEdgesPtr_();
463 }
464 
465 
466 const Foam::edgeList&
468 {
469  if (!ownerOrigBoundaryMeshEdgesPtr_.valid())
470  {
471  const edgeList& edges = ownerOrigBoundaryEdges();
472 
473  const labelList& pointMeshPoint =
475 
476  ownerOrigBoundaryMeshEdgesPtr_.set
477  (
478  new edgeList(edges.size())
479  );
480 
481  forAll(edges, edgei)
482  {
483  ownerOrigBoundaryMeshEdgesPtr_()[edgei] =
484  edge
485  (
486  pointMeshPoint[edges[edgei].start()],
487  pointMeshPoint[edges[edgei].end()]
488  );
489  }
490  }
491 
492  return ownerOrigBoundaryMeshEdgesPtr_();
493 }
494 
495 
496 const Foam::labelList&
498 (
499  const label patchi
500 ) const
501 {
502  if (!patchPointOwnerOrigBoundaryPointsPtr_.set(patchi))
503  {
504  const polyPatch& pp = mesh_.boundaryMesh()[patchi];
505 
506  const faceList patchOwnerOrigBoundaryLocalFaces
507  (
508  renumber
509  (
510  meshPointOwnerOrigBoundaryPoint(),
511  static_cast<const faceList&>(pp)
512  )
513  );
514 
515  const primitivePatch ownerOrigBoundaryLocalPatch
516  (
517  SubList<face>(patchOwnerOrigBoundaryLocalFaces, pp.size()),
518  ownerOrigBoundary_.localPoints()
519  );
520 
521  patchPointOwnerOrigBoundaryPointsPtr_.set
522  (
523  patchi,
524  new labelList(ownerOrigBoundaryLocalPatch.meshPoints())
525  );
526 
527  patchEdgeOwnerOrigBoundaryEdgesPtr_.set
528  (
529  patchi,
530  new labelList
531  (
532  ownerOrigBoundaryLocalPatch.meshEdges
533  (
534  ownerOrigBoundary_.edges(),
535  ownerOrigBoundary_.pointEdges()
536  )
537  )
538  );
539 
540  // Check the addressing is valid
541  if (debug)
542  {
543  const labelList& ppPointOwnerOrigBoundaryPoints =
544  patchPointOwnerOrigBoundaryPointsPtr_[patchi];
545 
546  forAll(pp.meshPoints(), ppPointi)
547  {
548  const label ownerOrigBoundaryPointi =
549  ppPointOwnerOrigBoundaryPoints[ppPointi];
550 
551  if
552  (
553  pp.meshPoints()[ppPointi]
554  != ownerOrigBoundary_.meshPoints()[ownerOrigBoundaryPointi]
555  )
556  {
558  << "Patch point does not match all boundary point"
559  << exit(FatalError);
560  }
561  }
562 
563  const labelList& ppEdgeOwnerOrigBoundaryEdges =
564  patchEdgeOwnerOrigBoundaryEdgesPtr_[patchi];
565 
566  forAll(pp.edges(), ppEdgei)
567  {
568  const label ownerOrigBoundaryEdgei =
569  ppEdgeOwnerOrigBoundaryEdges[ppEdgei];
570 
571  if
572  (
573  meshEdge(pp, ppEdgei)
574  != meshEdge(ownerOrigBoundary_, ownerOrigBoundaryEdgei)
575  )
576  {
578  << "Patch edge does not match all boundary edge"
579  << exit(FatalError);
580  }
581  }
582  }
583  }
584 
585  return patchPointOwnerOrigBoundaryPointsPtr_[patchi];
586 }
587 
588 
589 const Foam::labelList&
591 (
592  const label patchi
593 ) const
594 {
595  if (!patchEdgeOwnerOrigBoundaryEdgesPtr_.set(patchi))
596  {
598  }
599 
600  return patchEdgeOwnerOrigBoundaryEdgesPtr_[patchi];
601 }
602 
603 
606 {
607  return
609  (
610  new vectorField
611  (
613  (
614  ownerOrigBoundaryPointNormals(),
616  )
617  )
618  );
619 }
620 
621 
624 {
625  return
627  (
628  new vectorField
629  (
631  (
632  ownerOrigBoundaryPointNormals0(),
634  )
635  )
636  );
637 }
638 
639 
640 // ************************************************************************* //
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:453
ListType renumber(const labelUList &oldToNew, const ListType &)
Renumber the values (not the indices) of a list.
const labelListList & pointEdges() const
Return point-edge addressing.
label nPoints() const
Return number of points supporting patch faces.
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:49
virtual bool movePoints()
Update for mesh motion.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Non-conformal coupled poly patch. As nonConformalPolyPatch, but this patch is coupled to another non-...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Mesh object that stores an all boundary patch and mapping to and from it and the mesh and the individ...
tmp< vectorField > patchPointNormals0(const label patchi) const
Get parallel consistent old-time point normals for the patch.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
labelList allErrorPatchIDs() const
Return a list of the error patch indices.
const labelList & ownerOrigBoundaryEdgeMeshEdge() const
Get a map from owner-orig boundary edge to mesh edge.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
const labelListList & pointEdges() const
labelList ownerErrorPatchIDs() const
Return a list of the owner error patch indices.
const labelList & patchEdgeOwnerOrigBoundaryEdges(const label patchi) const
Get a map from patch edge to owner-orig boundary edge.
const edgeList & ownerOrigBoundaryEdges() const
Get the owner-orig boundary edges, referring to boundary points.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
List< face > faceList
Definition: faceListFwd.H:43
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
bool neighbour() const
Does the coupled side own the patch?
const Field< PointType > & localPoints() const
Return pointField of points in patch.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
Foam::indirectPrimitivePatch.
fvMesh & mesh
bool insert(const Key &key)
Insert a new entry.
Definition: HashSet.H:111
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
Templated abstract base-class for optional mesh objects used to automate their allocation to the mesh...
Definition: MeshObject.H:87
A list of faces which address into the list of points.
A List obtained as a section of another List.
Definition: SubList.H:53
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
List< edge > edgeList
Definition: edgeList.H:38
bool owner() const
Does this side own the patch?
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:113
static void syncEdgeList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronise values on all mesh edges.
labelList allOrigPatchIDs() const
Return a list of the orig patch indices.
void append(const T &)
Append an element at the end of the list.
Definition: ListI.H:178
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
List< label > labelList
A List of labels.
Definition: labelList.H:56
static const zero Zero
Definition: zero.H:97
faceListList boundary(nPatches)
Foam::polyBoundaryMesh.
label nEdges() const
Return number of edges in patch.
const labelList & patchPointOwnerOrigBoundaryPoints(const label patchi) const
Get a map from patch point to owner-orig boundary point.
defineTypeNameAndDebug(combustionModel, 0)
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
Addressing for a faceList slice.
nonConformalBoundary(const polyMesh &mesh)
Construct from a mesh.
const labelList & ownerOrigBoundaryPointMeshPoint() const
Get a map from owner-orig boundary point to mesh point.
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
const edgeList & ownerOrigBoundaryMeshEdges() const
Get the owner-orig boundary edges, referring to mesh points.
edge meshEdge(const PrimitivePatch< FaceList, PointField > &p, const label edgei)
label patchi
label origPatchID() const
Original patchID.
label end() const
Return end vertex label.
Definition: edgeI.H:92
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using.
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
A List with indirect addressing.
Definition: fvMatrix.H:106
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronise values on all mesh points.
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
const doubleScalar e
Elementary charge.
Definition: doubleScalar.H:105
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:76
labelList nonConformalNonCoupledPatchIDs(const label side, label(nonConformalCoupledPolyPatch::*method)() const) const
Return a list of non-conformal non-coupled patch indices.
labelList ownerOrigPatchIDs() const
Return a list of the owner-orig patch indices.
tmp< vectorField > patchPointNormals(const label patchi) const
Get parallel consistent point normals for the patch.
A class for managing temporary objects.
Definition: PtrList.H:53
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
label start() const
Return start vertex label.
Definition: edgeI.H:81
Namespace for OpenFOAM.