1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | cfMesh: A library for mesh generation
5 \\ / A nd | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6 \\/ M anipulation | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of cfMesh.
11 cfMesh 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 3 of the License, or (at your
14 option) any later version.
16 cfMesh 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 cfMesh. If not, see <http://www.gnu.org/licenses/>.
26 \*---------------------------------------------------------------------------*/
28 #include "demandDrivenData.H"
29 #include "polyMeshGenModifier.H"
30 #include "partTetMesh.H"
31 #include "tetMatcher.H"
32 #include "polyMeshGenAddressing.H"
33 #include "helperFunctionsPar.H"
37 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
44 void partTetMesh::createPointsAndTets
46 const List<direction>& useCell,
47 const boolList& lockedPoints
50 const pointFieldPMG& points = origMesh_.points();
51 const faceListPMG& faces = origMesh_.faces();
52 const cellListPMG& cells = origMesh_.cells();
53 const labelList& owner = origMesh_.owner();
54 const labelList& neighbour = origMesh_.neighbour();
55 const PtrList<boundaryPatch>& boundaries = origMesh_.boundaries();
56 const PtrList<processorBoundaryPatch>& procBoundaries =
57 origMesh_.procBoundaries();
58 const label nInternalFaces = origMesh_.nInternalFaces();
60 //- check how many neighbours of a face are marked for smoothing
61 labelList usedFace(faces.size(), 0);
66 if( useCell[owner[faceI]] )
69 if( neighbour[faceI] < 0 )
72 if( useCell[neighbour[faceI]] )
76 //- send data at processor boundaries
77 forAll(procBoundaries, patchI)
79 const label start = procBoundaries[patchI].patchStart();
80 const label size = procBoundaries[patchI].patchSize();
82 labelLongList dataToSend;
83 for(label faceI=0;faceI<size;++faceI)
85 if( usedFace[start+faceI] )
86 dataToSend.append(faceI);
92 procBoundaries[patchI].neiProcNo(),
96 toOtherProc << dataToSend;
99 //- receive data at proc boundaries
100 forAll(procBoundaries, patchI)
102 labelLongList receivedData;
104 IPstream fromOtherProc
107 procBoundaries[patchI].neiProcNo()
110 fromOtherProc >> receivedData;
112 const label start = procBoundaries[patchI].patchStart();
113 forAll(receivedData, faceI)
114 ++usedFace[start+receivedData[faceI]];
117 const vectorField& faceCentres = origMesh_.addressingData().faceCentres();
118 const vectorField& cellCentres = origMesh_.addressingData().cellCentres();
120 labelLongList nodeLabelForPoint(points.size(), -1);
121 labelLongList nodeLabelForFace(faces.size(), -1);
122 labelLongList nodeLabelForCell(cells.size(), -1);
125 smoothVertex_.clear();
127 //- create BOUNDARY points
128 forAll(boundaries, patchI)
130 const boundaryPatch& patch = boundaries[patchI];
131 const label start = patch.patchStart();
132 const label end = start + patch.patchSize();
134 for(label faceI=start;faceI<end;++faceI)
136 if( !usedFace[faceI] )
139 const face& f = faces[faceI];
143 //- create face centre
144 nodeLabelForFace[faceI] = points_.size();
145 points_.append(faceCentres[faceI]);
146 smoothVertex_.append(FACECENTRE);
152 const label pointI = f[pI];
153 if( nodeLabelForPoint[pointI] == -1 )
155 nodeLabelForPoint[pointI] = points_.size();
156 points_.append(points[pointI]);
158 smoothVertex_.append(BOUNDARY);
164 //- create points at processor boundaries
165 forAll(procBoundaries, patchI)
167 const processorBoundaryPatch& patch = procBoundaries[patchI];
168 const label start = patch.patchStart();
169 const label end = start + patch.patchSize();
171 for(label faceI=start;faceI<end;++faceI)
173 if( !usedFace[faceI] )
176 const face& f = faces[faceI];
180 //- create face centre
181 nodeLabelForFace[faceI] = points_.size();
182 points_.append(faceCentres[faceI]);
183 smoothVertex_.append(FACECENTRE);
187 const direction vType = usedFace[faceI]==2?SMOOTH:NONE;
190 const label pointI = f[pI];
191 if( nodeLabelForPoint[pointI] == -1 )
193 nodeLabelForPoint[pointI] = points_.size();
194 points_.append(points[pointI]);
196 smoothVertex_.append(vType);
198 else if( vType == NONE )
200 smoothVertex_[nodeLabelForPoint[pointI]] = NONE;
206 //- create points for internal faces
207 for(label faceI=0;faceI<nInternalFaces;++faceI)
209 if( usedFace[faceI] )
211 const face& f = faces[faceI];
215 //- create face centre
216 nodeLabelForFace[faceI] = points_.size();
217 points_.append(faceCentres[faceI]);
218 smoothVertex_.append(FACECENTRE);
222 const direction vType = usedFace[faceI]==2?SMOOTH:NONE;
225 const label pointI = f[pI];
226 if( nodeLabelForPoint[pointI] == -1 )
228 nodeLabelForPoint[pointI] = points_.size();
229 points_.append(points[pointI]);
231 smoothVertex_.append(vType);
233 else if( vType == NONE )
235 smoothVertex_[nodeLabelForPoint[pointI]] = NONE;
246 const cell& c = cells[cI];
248 if( tet.matchShape(false, faces, owner, cI, cells[cI]) )
250 const labelList& tVrt = tet.vertLabels();
257 nodeLabelForPoint[tVrt[0]],
258 nodeLabelForPoint[tVrt[1]],
259 nodeLabelForPoint[tVrt[2]],
260 nodeLabelForPoint[tVrt[3]]
267 nodeLabelForCell[cI] = points_.size();
268 const label centreLabel = points_.size();
269 points_.append(cellCentres[cI]);
270 smoothVertex_.append(CELLCENTRE);
274 const face& f = faces[c[fI]];
276 if( owner[c[fI]] == cI )
282 nodeLabelForPoint[f[0]],
283 nodeLabelForPoint[f[2]],
284 nodeLabelForPoint[f[1]],
289 Info << "1.1 Tet " << tets_.size() << " is "
301 nodeLabelForPoint[f[pI]],
302 nodeLabelForPoint[f.prevLabel(pI)],
303 nodeLabelForFace[c[fI]],
308 Info << "1.2 Tet " << tets_.size() << " is "
322 nodeLabelForPoint[f[0]],
323 nodeLabelForPoint[f[1]],
324 nodeLabelForPoint[f[2]],
329 Info << "2.1 Tet " << tets_.size() << " is "
341 nodeLabelForPoint[f[pI]],
342 nodeLabelForPoint[f.nextLabel(pI)],
343 nodeLabelForFace[c[fI]],
348 Info << "2.2 Tet " << tets_.size() << " is "
359 //- create node labels in origMesh_
360 nodeLabelInOrigMesh_.setSize(points_.size());
361 nodeLabelInOrigMesh_ = -1;
362 forAll(nodeLabelForPoint, pI)
363 if( nodeLabelForPoint[pI] != -1 )
365 //- lock mesh vertices
366 if( lockedPoints[pI] )
367 smoothVertex_[nodeLabelForPoint[pI]] |= LOCKED;
369 nodeLabelInOrigMesh_[nodeLabelForPoint[pI]] = pI;
373 //- create pointTets_
374 pointTets_.reverseAddressing(points_.size(), tets_);
376 //- create addressing for parallel runs
377 if( Pstream::parRun() )
379 createParallelAddressing
386 createBufferLayers();
390 forAll(nodeLabelInOrigMesh_, pI)
392 (nodeLabelInOrigMesh_[pI] != -1) &&
393 (mag(points_[pI] - points[nodeLabelInOrigMesh_[pI]]) > SMALL)
397 "void partTetMesh::createPointsAndTets"
398 "(const boolList& useCell)"
399 ) << "Node " << pI << " is dislocated" << abort(FatalError);
403 void partTetMesh::createSMOOTHPointsOrdering() const
405 internalPointsOrderPtr_ = new VRWGraph();
406 VRWGraph& internalPointsOrder = *internalPointsOrderPtr_;
408 internalPointsOrder.setSize(0);
409 labelLongList order(points_.size(), -1);
410 boolList helper(points_.size());
417 labelLongList selectedPoints;
419 forAll(points_, nodeI)
421 if( smoothVertex_[nodeI] & SMOOTH )
425 if( order[nodeI] != -1 )
428 //- find neighbouring FACECENTRE and CELLCENTRE points
429 DynList<label, 64> neiCentrePoints, neiSmoothPoints;
430 forAllRow(pointTets_, nodeI, ptI)
432 const partTet& tet = tets_[pointTets_(nodeI, ptI)];
434 for(label i=0;i<4;++i)
435 if( smoothVertex_[tet[i]] & (FACECENTRE+CELLCENTRE) )
437 neiCentrePoints.appendIfNotIn(tet[i]);
439 else if( smoothVertex_[tet[i]] & SMOOTH )
441 neiSmoothPoints.appendIfNotIn(tet[i]);
445 //- find neighbouring SMOOTH points
446 forAll(neiCentrePoints, ncI)
448 const label centreI = neiCentrePoints[ncI];
450 forAllRow(pointTets_, centreI, ptI)
452 const partTet& tet = tets_[pointTets_(centreI, ptI)];
454 for(label i=0;i<4;++i)
455 if( smoothVertex_[tet[i]] & SMOOTH )
456 neiSmoothPoints.appendIfNotIn(tet[i]);
460 //- select the point and mark neighbouring SMOOTH points
461 selectedPoints.append(nodeI);
462 order[nodeI] = internalPointsOrder.size();
464 forAll(neiSmoothPoints, i)
465 helper[neiSmoothPoints[i]] = true;
469 if( selectedPoints.size() != 0 )
471 internalPointsOrder.appendList(selectedPoints);
478 void partTetMesh::createBOUNDARYPointsOrdering() const
480 boundaryPointsOrderPtr_ = new VRWGraph();
481 VRWGraph& boundaryPointsOrder = *boundaryPointsOrderPtr_;
483 boundaryPointsOrder.setSize(0);
484 labelLongList order(points_.size(), -1);
485 boolList helper(points_.size());
493 labelLongList selectedPoints;
494 forAll(points_, nodeI)
496 if( smoothVertex_[nodeI] & BOUNDARY )
500 if( order[nodeI] != -1 )
503 //- find neighbouring FACECENTRE and CELLCENTRE points
504 DynList<label, 64> neiCentrePoints, neiSmoothPoints;
505 forAllRow(pointTets_, nodeI, ptI)
507 const partTet& tet = tets_[pointTets_(nodeI, ptI)];
509 for(label i=0;i<4;++i)
510 if( smoothVertex_[tet[i]] & (FACECENTRE+CELLCENTRE) )
512 neiCentrePoints.appendIfNotIn(tet[i]);
514 else if( smoothVertex_[tet[i]] & BOUNDARY )
516 neiSmoothPoints.appendIfNotIn(tet[i]);
520 //- find neighbouring BOUNDARY points
521 forAll(neiCentrePoints, ncI)
523 const label centreI = neiCentrePoints[ncI];
525 forAllRow(pointTets_, centreI, ptI)
527 const partTet& tet = tets_[pointTets_(centreI, ptI)];
529 for(label i=0;i<4;++i)
530 if( smoothVertex_[tet[i]] & BOUNDARY )
531 neiSmoothPoints.appendIfNotIn(tet[i]);
535 //- select the point and mark neighbouring BOUNDARY points
536 selectedPoints.append(nodeI);
537 order[nodeI] = boundaryPointsOrder.size();
539 forAll(neiSmoothPoints, i)
540 helper[neiSmoothPoints[i]] = true;
544 if( selectedPoints.size() != 0 )
546 boundaryPointsOrder.appendList(selectedPoints);
553 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
555 } // End namespace Foam
557 // ************************************************************************* //