Moving cfMesh into place. Updated contibutors list
[foam-extend-3.2.git] / src / mesh / cfMesh / meshLibrary / utilities / boundaryLayers / boundaryLayersFacesAndCells.C
blobe298a37e7557cb59729553887b51abbe0632d035
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | cfMesh: A library for mesh generation
4    \\    /   O peration     |
5     \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6      \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "boundaryLayers.H"
29 #include "meshSurfaceEngine.H"
30 #include "helperFunctions.H"
31 #include "demandDrivenData.H"
32 #include "VRWGraphList.H"
34 #include <map>
36 //#define DEBUGLayer
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
40 namespace Foam
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() )
60     {
61         createNewFacesParallel(treatPatches);
63         otherProcPatchPtr = &mse.otherEdgeFacePatch();
64     }
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();
76     forAll(bFaces, bfI)
77         if( treatPatches[boundaryFacePatches[bfI]] )
78         {
79             const face& f = bFaces[bfI];
81             faceList cellFaces(f.size() + 2);
83             label fI(0);
85             //- store boundary face
86             cellFaces[fI++] = f.reverseFace();
88             //- create parallel face
89             face newF(f.size());
90             forAll(f, pI)
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]);
98             //- create quad faces
99             newF.setSize(4);
100             forAll(f, pI)
101             {
102                 newF[0] = f[pI];
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 )
113                 {
114                     label neiFace = edgeFaces(edgeI, 0);
115                     if( neiFace == bfI )
116                         neiFace = edgeFaces(edgeI, 1);
118                     if( !treatPatches[boundaryFacePatches[neiFace]] )
119                     {
120                         newBoundaryFaces.appendList(newF);
121                         newBoundaryOwners.append(cellsToAdd.size() + nOldCells);
122                         newBoundaryPatches.append(boundaryFacePatches[neiFace]);
123                     }
124                 }
125                 else if( edgeFaces.sizeOfRow(edgeI) == 1 )
126                 {
127                     const Map<label>& otherProcPatch = *otherProcPatchPtr;
128                     if( !treatPatches[otherProcPatch[edgeI]] )
129                     {
130                         newBoundaryFaces.appendList(newF);
131                         newBoundaryOwners.append(cellsToAdd.size() + nOldCells);
132                         newBoundaryPatches.append(otherProcPatch[edgeI]);
133                     }
134                 }
135             }
137             cellsToAdd.appendGraph(cellFaces);
138         }
139         else
140         {
141             # ifdef DEBUGLayer
142             Info << "Storing original boundary face "
143                 << bfI << " into patch " << boundaryFacePatches[bfI] << endl;
144             # endif
146             newBoundaryFaces.appendList(bFaces[bfI]);
147             newBoundaryOwners.append(faceOwners[bfI]);
148             newBoundaryPatches.append(boundaryFacePatches[bfI]);
149         }
151     //- create mesh modifier
152     polyMeshGenModifier meshModifier(mesh_);
154     meshModifier.addCells(cellsToAdd);
155     cellsToAdd.clear();
156     meshModifier.reorderBoundaryFaces();
157     meshModifier.replaceBoundary
158     (
159         patchNames_,
160         newBoundaryFaces,
161         newBoundaryOwners,
162         newBoundaryPatches
163     );
165     //- delete meshSurfaceEngine
166     this->clearOut();
168     # ifdef DEBUGLayer
169     mesh_.addressingData().checkMesh(true);
170     # endif
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)
199     {
200         const processorBoundaryPatch& wp = mesh_.procBoundaries()[patchI];
201         otherProcToProcPatch.insert(wp.neiProcNo(), patchI);
202     }
204     label nTreatedEdges(0);
205     boolList treatEdge(edgeFaces.size(), false);
206     for
207     (
208         Map<label>::const_iterator iter=globalToLocal.begin();
209         iter!=globalToLocal.end();
210         ++iter
211     )
212     {
213         const label beI = iter();
215         if( edgeFaces.sizeOfRow(beI) != 1 )
216             continue;
218         if(
219             treatPatches[boundaryFacePatches[edgeFaces(beI, 0)]] &&
220             treatPatches[otherProcPatch[beI]]
221         )
222         {
223             ++nTreatedEdges;
224             treatEdge[beI] = true;
225         }
226     }
228     //- create a list of treated edges and sort the list
229     labelList treatedEdgeLabels(nTreatedEdges);
230     nTreatedEdges = 0;
231     forAll(treatEdge, beI)
232         if( treatEdge[beI] )
233         {
234             treatedEdgeLabels[nTreatedEdges++] = globalEdgeLabel[beI];
235         }
236     treatedEdgeLabels.setSize(nTreatedEdges);
238     sort(treatedEdgeLabels);
240     //- create additional processor patches if needed
241     forAll(treatedEdgeLabels, eI)
242     {
243         const label beI = globalToLocal[treatedEdgeLabels[eI]];
245         if( !otherProcToProcPatch.found(otherFaceProc[beI]) )
246         {
247             otherProcToProcPatch.insert
248             (
249                 otherFaceProc[beI],
250                 polyMeshGenModifier(mesh_).addProcessorPatch
251                 (
252                     otherFaceProc[beI]
253                 )
254             );
255         }
256     }
258     //- create new processor faces
259     VRWGraph newProcFaces;
260     labelLongList faceProcPatch;
261     FixedList<label, 4> newF;
262     forAll(treatedEdgeLabels, geI)
263     {
264         const label beI = globalToLocal[treatedEdgeLabels[geI]];
266         if( edgeFaces.sizeOfRow(beI) == 0 )
267             continue;
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() )
274         {
275             newF[0] = e.start();
276             newF[1] = e.end();
277             if( patchKey_.size() != 0 )
278             {
279                 newF[2] =
280                     findNewNodeLabel(e.end(), patchKey_[otherProcPatch[beI]]);
281                 newF[3] =
282                     findNewNodeLabel(e.start(), patchKey_[otherProcPatch[beI]]);
283             }
284             else
285             {
286                 newF[2] = newLabelForVertex_[e.end()];
287                 newF[3] = newLabelForVertex_[e.start()];
288             }
289         }
290         else
291         {
292             newF[0] = e.end();
293             if( patchKey_.size() != 0 )
294             {
295                 newF[1] =
296                     findNewNodeLabel
297                     (
298                         e.end(),
299                         patchKey_[boundaryFacePatches[bfI]]
300                     );
301                 newF[2] =
302                     findNewNodeLabel
303                     (
304                         e.start(),
305                         patchKey_[boundaryFacePatches[bfI]]
306                     );
307             }
308             else
309             {
310                 newF[1] = newLabelForVertex_[e.end()];
311                 newF[2] = newLabelForVertex_[e.start()];
312             }
313             newF[3] = e.start();
314         }
316         newProcFaces.appendList(newF);
317         faceProcPatch.append(otherProcToProcPatch[otherFaceProc[beI]]);
318     }
320     //- add faces into the mesh
321     polyMeshGenModifier(mesh_).addProcessorFaces(newProcFaces, faceProcPatch);
324 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
326 } // End namespace Foam
328 // ************************************************************************* //