1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Calculate cut edge processor addressing, needed for vector-matrix
27 multiply on processor boundaries.
29 \*---------------------------------------------------------------------------*/
31 #include "processorTetPolyPatchCellDecomp.H"
32 #include "tetPolyBoundaryMeshCellDecomp.H"
33 #include "tetPolyMeshCellDecomp.H"
35 #include "globalTetPolyPatchCellDecomp.H"
36 #include "primitiveFacePatch.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45 void processorTetPolyPatchCellDecomp::calcCutEdgeIndices() const
49 Info<< "void processorTetPolyPatchCellDecomp::"
50 << "calcCutEdgeIndices() const : "
51 << "calculating cut edge indices"
55 if (cutEdgeIndicesPtr_)
59 "void processorTetPolyPatchCellDecomp::calcCutEdgesIndices() const"
60 ) << "addressing already allocated"
64 // Make a list over all edges in the mesh. Mark the ones that are local
65 // to the patch and then collect the rest
67 boolList isLocal(boundaryMesh().mesh().nEdges(), false);
69 // Get reference to local edge indices
70 const labelList& localEdges = localEdgeIndices();
72 forAll (localEdges, edgeI)
74 isLocal[localEdges[edgeI]] = true;
77 // Get reference to parallel shared edges
78 const labelList& sharedEdges =
79 boundaryMesh().globalPatch().localEdgeIndices();
81 forAll (sharedEdges, sharedI)
83 isLocal[sharedEdges[sharedI]] = true;
86 const labelList& sharedCutEdges =
87 boundaryMesh().globalPatch().cutEdgeIndices();
89 forAll (sharedCutEdges, sharedCutI)
91 isLocal[sharedCutEdges[sharedCutI]] = true;
94 // Count the maximum number of edges coming from the patch
95 label maxEdgesOnPatch = 0;
97 const tetPolyMeshCellDecomp& mesh = boundaryMesh().mesh();
99 const labelList& mp = meshPoints();
103 maxEdgesOnPatch += mesh.nEdgesForPoint(mp[pointI]);
106 // Allocate the array
107 cutEdgeIndicesPtr_ = new labelList(maxEdgesOnPatch, -1);
108 labelList& cutEdgeInd = *cutEdgeIndicesPtr_;
110 label nCutEdgeInd = 0;
112 // Go through all the local points and get all the edges coming
113 // from that point. Check if the edge has been marked as local;
114 // if not, add it to the list of cut edges.
117 labelList curEdges = mesh.edgesForPoint(mp[pointI]);
119 forAll (curEdges, edgeI)
121 if (!isLocal[curEdges[edgeI]])
123 cutEdgeInd[nCutEdgeInd] = curEdges[edgeI];
129 // Reset the size of the edge list
130 cutEdgeInd.setSize(nCutEdgeInd);
134 Info<< "void processorTetPolyPatchCellDecomp::"
135 << "calcCutEdgeIndices() const : "
136 << "finished calculating cut edge indices"
142 void processorTetPolyPatchCellDecomp::calcCutEdgeAddressing() const
146 cutEdgeOwnerIndicesPtr_
147 || cutEdgeOwnerStartPtr_
148 || cutEdgeNeighbourIndicesPtr_
149 || cutEdgeNeighbourStartPtr_
150 || doubleCutEdgeIndicesPtr_
151 || doubleCutOwnerPtr_
152 || doubleCutNeighbourPtr_
157 "void processorTetPolyPatchCellDecomp::calcCutEdgeAddressing() "
159 ) << "addressing already allocated"
160 << abort(FatalError);
163 // Make a list over all edges in the mesh. Mark the ones that are local
164 // to the patch and then collect the rest.
165 // For doubly cut edges, mark up the local points
167 const tetPolyMeshCellDecomp& mesh = boundaryMesh().mesh();
169 // Get reference to local edge indices
170 const labelList& localEdges = localEdgeIndices();
172 // Get reference to mesh point addressing for the patch
173 const labelList& mp = meshPoints();
175 // Mark up the local edges
177 boolList isLocal(mesh.nEdges(), false);
179 forAll (localEdges, edgeI)
181 isLocal[localEdges[edgeI]] = true;
184 // Get reference to parallel shared edges
185 const labelList& sharedEdges =
186 boundaryMesh().globalPatch().localEdgeIndices();
188 forAll (sharedEdges, sharedI)
190 isLocal[sharedEdges[sharedI]] = true;
193 const labelList& sharedCutEdges =
194 boundaryMesh().globalPatch().cutEdgeIndices();
196 forAll (sharedCutEdges, sharedCutI)
198 isLocal[sharedCutEdges[sharedCutI]] = true;
201 labelList localPointLabel(mesh.nPoints(), -1);
205 localPointLabel[mp[pointI]] = pointI;
208 // Count the maximum number of edges coming from the patch
209 label maxEdgesOnPatch = 0;
213 maxEdgesOnPatch += mesh.nEdgesForPoint(mp[pointI]);
216 // Get reference to addressing
217 const lduAddressing& ldu = mesh.lduAddr();
219 // Allocate doubly cut arrays
220 doubleCutEdgeIndicesPtr_ = new labelList(maxEdgesOnPatch, -1);
221 labelList& doubleCutEdges = *doubleCutEdgeIndicesPtr_;
223 doubleCutOwnerPtr_ = new labelList(maxEdgesOnPatch, -1);
224 labelList& doubleCutOwn = *doubleCutOwnerPtr_;
226 doubleCutNeighbourPtr_ = new labelList(maxEdgesOnPatch, -1);
227 labelList& doubleCutNei = *doubleCutNeighbourPtr_;
229 label nDoubleCut = 0;
231 const labelList& globalOwner = ldu.lowerAddr();
232 const labelList& globalNeighbour = ldu.upperAddr();
237 // Allocate the array
238 cutEdgeOwnerIndicesPtr_ = new labelList(maxEdgesOnPatch, -1);
239 labelList& own = *cutEdgeOwnerIndicesPtr_;
242 cutEdgeOwnerStartPtr_ = new labelList(meshPoints().size() + 1, -1);
243 labelList& ownStart = *cutEdgeOwnerStartPtr_;
245 // Go through all the local points and get all the edges coming
246 // from that point. Check if the edge has been marked as local;
247 // if not, add it to the list of cut edges.
250 ownStart[pointI] = nOwn;
252 const label curPointID = mp[pointI];
254 // get owner edges indices
255 const label startFaceOwn = ldu.ownerStartAddr()[curPointID];
256 const label endFaceOwn = ldu.ownerStartAddr()[curPointID + 1];
260 label edgeLabel = startFaceOwn;
261 edgeLabel < endFaceOwn;
265 if (!isLocal[edgeLabel])
267 isLocal[edgeLabel] = true;
269 if (localPointLabel[globalNeighbour[edgeLabel]] == -1)
272 own[nOwn] = edgeLabel;
278 doubleCutEdges[nDoubleCut] = edgeLabel;
279 doubleCutOwn[nDoubleCut] = pointI;
280 doubleCutNei[nDoubleCut] =
281 localPointLabel[globalNeighbour[edgeLabel]];
289 // reset the size of owner edges
292 // set the last start label by hand
293 ownStart[meshPoints().size()] = nOwn;
298 // Allocate the array
299 cutEdgeNeighbourIndicesPtr_ = new labelList(maxEdgesOnPatch, -1);
300 labelList& nei = *cutEdgeNeighbourIndicesPtr_;
303 cutEdgeNeighbourStartPtr_ = new labelList(meshPoints().size() + 1, -1);
304 labelList& neiStart = *cutEdgeNeighbourStartPtr_;
306 const unallocLabelList& losort = ldu.losortAddr();
308 // Go through all the local points and get all the edges coming
309 // from that point. Check if the edge has been marked as local;
310 // if not, add it to the list of cut edges.
313 neiStart[pointI] = nNei;
315 const label curPointID = mp[pointI];
317 // get neighbour edges indices
318 const label startFaceNei = ldu.losortStartAddr()[curPointID];
319 const label endFaceNei = ldu.losortStartAddr()[curPointID + 1];
323 label edgeLabel = startFaceNei;
324 edgeLabel < endFaceNei;
328 if (!isLocal[losort[edgeLabel]])
330 isLocal[losort[edgeLabel]] = true;
332 if (localPointLabel[globalOwner[losort[edgeLabel]]] == -1)
335 nei[nNei] = losort[edgeLabel];
341 doubleCutEdges[nDoubleCut] = losort[edgeLabel];
342 doubleCutOwn[nDoubleCut] =
343 localPointLabel[globalOwner[losort[edgeLabel]]];
344 doubleCutNei[nDoubleCut] = pointI;
352 // reset the size of neighbour edges
355 // set the last start label by hand
356 neiStart[meshPoints().size()] = nNei;
358 // Reset the size of double cut edge data
359 doubleCutEdges.setSize(nDoubleCut);
360 doubleCutOwn.setSize(nDoubleCut);
361 doubleCutNei.setSize(nDoubleCut);
365 void processorTetPolyPatchCellDecomp::calcOwnNeiDoubleMask() const
367 if (ownNeiDoubleMaskPtr_)
371 "void processorTetPolyPatchCellDecomp::calcOwnNeiDoubleMask() "
373 ) << "ownNeiDoubleMaskPtr_ already allocated"
374 << abort(FatalError);
378 // Make a point lookup field which marks all points belonging to
379 // Other processor patches.
380 // Go through all the cut edges and cheeck the points of the edge.
381 // If the point belongs to another parallel patch, set the mask to zero
383 const tetPolyMeshCellDecomp& mesh = boundaryMesh().mesh();
385 boolList otherProcPoint(mesh.nPoints(), false);
387 forAll (boundaryMesh(), patchI)
391 isA<processorTetPolyPatchCellDecomp>(boundaryMesh()[patchI])
394 // Get the local points and mark up the list
395 const labelList& mp = boundaryMesh()[patchI].meshPoints();
399 otherProcPoint[mp[i]] = true;
404 // Go through all cut edges and set the mask
406 // Get matrix addressing
407 const labelList& mp = meshPoints();
409 const unallocLabelList& L = mesh.lduAddr().lowerAddr();
410 const unallocLabelList& U = mesh.lduAddr().upperAddr();
412 const labelList& cutOwn = cutEdgeOwnerIndices();
413 const labelList& cutNei = cutEdgeNeighbourIndices();
414 const labelList& doubleCut = doubleCutEdgeIndices();
416 ownNeiDoubleMaskPtr_ =
419 cutOwn.size() + cutNei.size() + doubleCut.size(),
422 scalarField& mask = *ownNeiDoubleMaskPtr_;
429 const labelList& cutOwnStart = cutEdgeOwnerStart();
433 label ownIndex = cutOwnStart[pointI];
434 label endOwn = cutOwnStart[pointI + 1];
436 for (; ownIndex < endOwn; ownIndex++)
438 if(otherProcPoint[U[cutOwn[ownIndex]]])
450 const labelList& cutNeiStart = cutEdgeNeighbourStart();
454 label neiIndex = cutNeiStart[pointI];
455 label endNei = cutNeiStart[pointI + 1];
457 for (; neiIndex < endNei; neiIndex++)
459 if (otherProcPoint[L[cutNei[neiIndex]]])
469 // Doubly cut coefficients
470 // ~~~~~~~~~~~~~~~~~~~~~~~
471 // Not needed. HJ, 18/Apr/2002
475 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
477 const labelList& processorTetPolyPatchCellDecomp::localEdgeIndices() const
479 if (!localEdgeIndicesPtr_)
483 localEdgeIndicesPtr_ =
484 new labelList(calcProcLocalEdgesIndices(procPolyPatch_));
488 // Slave side. Create the reversed patch and pick up its points
489 // so that the order is correct
490 const polyPatch& pp = patch();
492 faceList masterFaces(pp.size());
496 masterFaces[faceI] = pp[faceI].reverseFace();
499 // To adhere to the interface, the primitive patch is created
500 // from master faces locally and lost after use
501 localEdgeIndicesPtr_ =
504 calcProcLocalEdgesIndices
516 return *localEdgeIndicesPtr_;
520 const labelList& processorTetPolyPatchCellDecomp::cutEdgeIndices() const
522 if (!cutEdgeIndicesPtr_)
524 calcCutEdgeIndices();
527 return *cutEdgeIndicesPtr_;
531 const labelList& processorTetPolyPatchCellDecomp::cutEdgeOwnerIndices() const
533 if (!cutEdgeOwnerIndicesPtr_)
535 calcCutEdgeAddressing();
538 return *cutEdgeOwnerIndicesPtr_;
542 const labelList& processorTetPolyPatchCellDecomp::cutEdgeOwnerStart() const
544 if (!cutEdgeOwnerStartPtr_)
546 calcCutEdgeAddressing();
549 return *cutEdgeOwnerStartPtr_;
554 processorTetPolyPatchCellDecomp::cutEdgeNeighbourIndices() const
556 if (!cutEdgeNeighbourIndicesPtr_)
558 calcCutEdgeAddressing();
561 return *cutEdgeNeighbourIndicesPtr_;
565 const labelList& processorTetPolyPatchCellDecomp::cutEdgeNeighbourStart() const
567 if (!cutEdgeNeighbourStartPtr_)
569 calcCutEdgeAddressing();
572 return *cutEdgeNeighbourStartPtr_;
576 const labelList& processorTetPolyPatchCellDecomp::doubleCutEdgeIndices() const
578 if (!doubleCutEdgeIndicesPtr_)
580 calcCutEdgeAddressing();
583 return *doubleCutEdgeIndicesPtr_;
587 const labelList& processorTetPolyPatchCellDecomp::doubleCutOwner() const
589 if (!doubleCutOwnerPtr_)
591 calcCutEdgeAddressing();
594 return *doubleCutOwnerPtr_;
598 const labelList& processorTetPolyPatchCellDecomp::doubleCutNeighbour() const
600 if (!doubleCutNeighbourPtr_)
602 calcCutEdgeAddressing();
605 return *doubleCutNeighbourPtr_;
609 const scalarField& processorTetPolyPatchCellDecomp::ownNeiDoubleMask() const
611 if (!ownNeiDoubleMaskPtr_)
613 calcOwnNeiDoubleMask();
616 return *ownNeiDoubleMaskPtr_;
620 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
622 } // End namespace Foam
624 // ************************************************************************* //