Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / dynamicMesh / meshCut / meshModifiers / refinementIterator / refinementIterator.C
blob255d2b0bf42517e7c8feb483f9baed4127ed8517
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2004-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "refinementIterator.H"
27 #include "polyMesh.H"
28 #include "Time.H"
29 #include "refineCell.H"
30 #include "undoableMeshCutter.H"
31 #include "polyTopoChange.H"
32 #include "mapPolyMesh.H"
33 #include "cellCuts.H"
34 #include "OFstream.H"
35 #include "meshTools.H"
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 defineTypeNameAndDebug(Foam::refinementIterator, 0);
42 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
44 // Construct from components
45 Foam::refinementIterator::refinementIterator
47     polyMesh& mesh,
48     undoableMeshCutter& meshRefiner,
49     const cellLooper& cellWalker,
50     const bool writeMesh
53     edgeVertex(mesh),
54     mesh_(mesh),
55     meshRefiner_(meshRefiner),
56     cellWalker_(cellWalker),
57     writeMesh_(writeMesh)
61 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
63 Foam::refinementIterator::~refinementIterator()
67 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
69 Foam::Map<Foam::label> Foam::refinementIterator::setRefinement
71     const List<refineCell>& refCells
74     Map<label> addedCells(2*refCells.size());
76     Time& runTime = const_cast<Time&>(mesh_.time());
78     label nRefCells = refCells.size();
80     label oldRefCells = -1;
82     // Operate on copy.
83     List<refineCell> currentRefCells(refCells);
85     bool stop = false;
87     do
88     {
89         if (writeMesh_)
90         {
91             // Need different times to write meshes.
92             runTime++;
93         }
95         polyTopoChange meshMod(mesh_);
97         if (debug)
98         {
99             Pout<< "refinementIterator : refining "
100                 << currentRefCells.size() << " cells." << endl;
101         }
103         // Determine cut pattern.
104         cellCuts cuts(mesh_, cellWalker_, currentRefCells);
106         label nCuts = cuts.nLoops();
107         reduce(nCuts, sumOp<label>());
109         if (nCuts == 0)
110         {
111             if (debug)
112             {
113                 Pout<< "refinementIterator : exiting iteration since no valid"
114                     << " loops found for " << currentRefCells.size()
115                     << " cells" << endl;
118                 fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj");
120                 Pout<< "Writing cuts for time " <<  runTime.timeName()
121                     << " to " << cutsFile << endl;
123                 OFstream cutsStream(cutsFile);
126                 labelList refCells(currentRefCells.size());
127                 forAll(currentRefCells, i)
128                 {
129                     refCells[i] = currentRefCells[i].cellNo();
130                 }
131                 meshTools::writeOBJ
132                 (
133                     cutsStream,
134                     mesh().cells(),
135                     mesh().faces(),
136                     mesh().points(),
137                     refCells
138                 );
139             }
141             break;
142         }
144         if (debug)
145         {
146             fileName cutsFile("cuts_" + runTime.timeName() + ".obj");
148             Pout<< "Writing cuts for time " <<  runTime.timeName()
149                 << " to " << cutsFile << endl;
151             OFstream cutsStream(cutsFile);
152             cuts.writeOBJ(cutsStream);
153         }
156         // Insert mesh refinement into polyTopoChange.
157         meshRefiner_.setRefinement(cuts, meshMod);
160         //
161         // Do all changes
162         //
164         autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh
165         (
166             mesh_,
167             false
168         );
170         // Move mesh (since morphing does not do this)
171         if (morphMap().hasMotionPoints())
172         {
173             mesh_.movePoints(morphMap().preMotionPoints());
174         }
176         // Update stored refinement pattern
177         meshRefiner_.updateMesh(morphMap());
179         // Write resulting mesh
180         if (writeMesh_)
181         {
182             if (debug)
183             {
184                 Pout<< "Writing refined polyMesh to time "
185                     << runTime.timeName() << endl;
186             }
188             mesh_.write();
189         }
191         // Update currentRefCells for new cell numbers. Use helper function
192         // in meshCutter class.
193         updateLabels
194         (
195             morphMap->reverseCellMap(),
196             currentRefCells
197         );
199         // Update addedCells for new cell numbers
200         updateLabels
201         (
202             morphMap->reverseCellMap(),
203             addedCells
204         );
206         // Get all added cells from cellCutter (already in new numbering
207         // from meshRefiner.updateMesh call) and add to global list of added
208         const Map<label>& addedNow = meshRefiner_.addedCells();
210         forAllConstIter(Map<label>, addedNow, iter)
211         {
212             if (!addedCells.insert(iter.key(), iter()))
213             {
214                 FatalErrorIn("refinementIterator")
215                     << "Master cell " << iter.key()
216                     << " already has been refined" << endl
217                     << "Added cell:" << iter() << abort(FatalError);
218             }
219         }
222         // Get failed refinement in new cell numbering and reconstruct input
223         // to the meshRefiner. Is done by removing all refined cells from
224         // current list of cells to refine.
226         // Update refCells for new cell numbers.
227         updateLabels
228         (
229             morphMap->reverseCellMap(),
230             currentRefCells
231         );
233         // Pack refCells acc. to refined status
234         nRefCells = 0;
236         forAll(currentRefCells, refI)
237         {
238             const refineCell& refCell = currentRefCells[refI];
240             if (!addedNow.found(refCell.cellNo()))
241             {
242                 if (nRefCells != refI)
243                 {
244                     currentRefCells[nRefCells++] =
245                         refineCell
246                         (
247                             refCell.cellNo(),
248                             refCell.direction()
249                         );
250                 }
251             }
252         }
254         oldRefCells = currentRefCells.size();
256         currentRefCells.setSize(nRefCells);
258         if (debug)
259         {
260             Pout<< endl;
261         }
263         // Stop only if all finished or all can't refine any further.
264         stop = (nRefCells == 0) || (nRefCells == oldRefCells);
265         reduce(stop, andOp<bool>());
266     }
267     while (!stop);
270     if (nRefCells == oldRefCells)
271     {
272         WarningIn("refinementIterator")
273             << "stopped refining."
274             << "Did not manage to refine a single cell" << endl
275             << "Wanted :" << oldRefCells << endl;
276     }
278     return addedCells;
283 // ************************************************************************* //