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 "boundaryLayers.H"
29 #include "meshSurfaceEngine.H"
30 #include "helperFunctions.H"
31 #include "demandDrivenData.H"
32 #include "VRWGraphList.H"
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 void boundaryLayers::createNewFacesAndCells(const boolList& treatPatches)
47 Info << "Starting creating layer cells" << endl;
49 const meshSurfaceEngine& mse = surfaceEngine();
50 const faceList::subList& bFaces = mse.boundaryFaces();
51 const VRWGraph& faceEdges = mse.faceEdges();
52 const VRWGraph& edgeFaces = mse.edgeFaces();
53 const labelList& boundaryFacePatches = mse.boundaryFacePatches();
54 const labelList& faceOwners = mse.faceOwners();
56 //- this is used for parallel runs
57 const Map<label>* otherProcPatchPtr(NULL);
59 if( Pstream::parRun() )
61 createNewFacesParallel(treatPatches);
63 otherProcPatchPtr = &mse.otherEdgeFacePatch();
66 //- create lists for new boundary faces
67 VRWGraph newBoundaryFaces;
68 labelLongList newBoundaryOwners;
69 labelLongList newBoundaryPatches;
71 //- create storage for new cells
72 VRWGraphList cellsToAdd;
74 //- create layer cells and store boundary faces
75 const label nOldCells = mesh_.cells().size();
77 if( treatPatches[boundaryFacePatches[bfI]] )
79 const face& f = bFaces[bfI];
81 faceList cellFaces(f.size() + 2);
85 //- store boundary face
86 cellFaces[fI++] = f.reverseFace();
88 //- create parallel face
91 newF[pI] = newLabelForVertex_[f[pI]];
92 cellFaces[fI++] = newF;
94 newBoundaryFaces.appendList(newF);
95 newBoundaryOwners.append(cellsToAdd.size() + nOldCells);
96 newBoundaryPatches.append(boundaryFacePatches[bfI]);
103 newF[1] = f.nextLabel(pI);
104 newF[2] = newLabelForVertex_[f.nextLabel(pI)];
105 newF[3] = newLabelForVertex_[f[pI]];
107 cellFaces[fI++] = newF;
109 //- check if the face is at the boundary
110 //- of the treated partitions
111 const label edgeI = faceEdges(bfI, pI);
112 if( edgeFaces.sizeOfRow(edgeI) == 2 )
114 label neiFace = edgeFaces(edgeI, 0);
116 neiFace = edgeFaces(edgeI, 1);
118 if( !treatPatches[boundaryFacePatches[neiFace]] )
120 newBoundaryFaces.appendList(newF);
121 newBoundaryOwners.append(cellsToAdd.size() + nOldCells);
122 newBoundaryPatches.append(boundaryFacePatches[neiFace]);
125 else if( edgeFaces.sizeOfRow(edgeI) == 1 )
127 const Map<label>& otherProcPatch = *otherProcPatchPtr;
128 if( !treatPatches[otherProcPatch[edgeI]] )
130 newBoundaryFaces.appendList(newF);
131 newBoundaryOwners.append(cellsToAdd.size() + nOldCells);
132 newBoundaryPatches.append(otherProcPatch[edgeI]);
137 cellsToAdd.appendGraph(cellFaces);
142 Info << "Storing original boundary face "
143 << bfI << " into patch " << boundaryFacePatches[bfI] << endl;
146 newBoundaryFaces.appendList(bFaces[bfI]);
147 newBoundaryOwners.append(faceOwners[bfI]);
148 newBoundaryPatches.append(boundaryFacePatches[bfI]);
151 //- create mesh modifier
152 polyMeshGenModifier meshModifier(mesh_);
154 meshModifier.addCells(cellsToAdd);
156 meshModifier.reorderBoundaryFaces();
157 meshModifier.replaceBoundary
165 //- delete meshSurfaceEngine
169 mesh_.addressingData().checkMesh(true);
172 Info << "Finished creating layer cells" << endl;
175 void boundaryLayers::createNewFacesParallel
177 const boolList& treatPatches
180 const meshSurfaceEngine& mse = surfaceEngine();
181 const faceList::subList& bFaces = mse.boundaryFaces();
182 const VRWGraph& faceEdges = mse.faceEdges();
183 const VRWGraph& edgeFaces = mse.edgeFaces();
184 const labelList& boundaryFacePatches = mse.boundaryFacePatches();
185 const labelList& globalEdgeLabel = mse.globalBoundaryEdgeLabel();
186 const Map<label>& globalToLocal = mse.globalToLocalBndEdgeAddressing();
188 const Map<label>& otherProcPatch = mse.otherEdgeFacePatch();
189 const Map<label>& otherFaceProc = mse.otherEdgeFaceAtProc();
191 //- the next stage is the generation of processor faces
192 //- this step can be done without any communication, but only if the faces
193 //- are added in the same order on both processors
194 //- this will be achieved by sorting edges according to their global labes
195 //- another difficulty here is that new processor patches may occur
196 //- during this procedure
197 Map<label> otherProcToProcPatch;
198 forAll(mesh_.procBoundaries(), patchI)
200 const processorBoundaryPatch& wp = mesh_.procBoundaries()[patchI];
201 otherProcToProcPatch.insert(wp.neiProcNo(), patchI);
204 label nTreatedEdges(0);
205 boolList treatEdge(edgeFaces.size(), false);
208 Map<label>::const_iterator iter=globalToLocal.begin();
209 iter!=globalToLocal.end();
213 const label beI = iter();
215 if( edgeFaces.sizeOfRow(beI) != 1 )
219 treatPatches[boundaryFacePatches[edgeFaces(beI, 0)]] &&
220 treatPatches[otherProcPatch[beI]]
224 treatEdge[beI] = true;
228 //- create a list of treated edges and sort the list
229 labelList treatedEdgeLabels(nTreatedEdges);
231 forAll(treatEdge, beI)
234 treatedEdgeLabels[nTreatedEdges++] = globalEdgeLabel[beI];
236 treatedEdgeLabels.setSize(nTreatedEdges);
238 sort(treatedEdgeLabels);
240 //- create additional processor patches if needed
241 forAll(treatedEdgeLabels, eI)
243 const label beI = globalToLocal[treatedEdgeLabels[eI]];
245 if( !otherProcToProcPatch.found(otherFaceProc[beI]) )
247 otherProcToProcPatch.insert
250 polyMeshGenModifier(mesh_).addProcessorPatch
258 //- create new processor faces
259 VRWGraph newProcFaces;
260 labelLongList faceProcPatch;
261 FixedList<label, 4> newF;
262 forAll(treatedEdgeLabels, geI)
264 const label beI = globalToLocal[treatedEdgeLabels[geI]];
266 if( edgeFaces.sizeOfRow(beI) == 0 )
269 const label bfI = edgeFaces(beI, 0);
270 const label pos = faceEdges.containsAtPosition(bfI, beI);
271 const edge e = bFaces[bfI].faceEdge(pos);
273 if( otherFaceProc[beI] > Pstream::myProcNo() )
277 if( patchKey_.size() != 0 )
280 findNewNodeLabel(e.end(), patchKey_[otherProcPatch[beI]]);
282 findNewNodeLabel(e.start(), patchKey_[otherProcPatch[beI]]);
286 newF[2] = newLabelForVertex_[e.end()];
287 newF[3] = newLabelForVertex_[e.start()];
293 if( patchKey_.size() != 0 )
299 patchKey_[boundaryFacePatches[bfI]]
305 patchKey_[boundaryFacePatches[bfI]]
310 newF[1] = newLabelForVertex_[e.end()];
311 newF[2] = newLabelForVertex_[e.start()];
316 newProcFaces.appendList(newF);
317 faceProcPatch.append(otherProcToProcPatch[otherFaceProc[beI]]);
320 //- add faces into the mesh
321 polyMeshGenModifier(mesh_).addProcessorFaces(newProcFaces, faceProcPatch);
324 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
326 } // End namespace Foam
328 // ************************************************************************* //