refinementIterator.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2019-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "refinementIterator.H"
30 #include "polyMesh.H"
31 #include "Time.H"
32 #include "refineCell.H"
33 #include "undoableMeshCutter.H"
34 #include "polyTopoChange.H"
35 #include "mapPolyMesh.H"
36 #include "cellCuts.H"
37 #include "OFstream.H"
38 #include "meshTools.H"
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
45 }
46 
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
51 (
52  polyMesh& mesh,
53  undoableMeshCutter& meshRefiner,
54  const cellLooper& cellWalker,
55  const bool writeMesh
56 )
57 :
59  mesh_(mesh),
60  meshRefiner_(meshRefiner),
61  cellWalker_(cellWalker),
62  writeMesh_(writeMesh)
63 {}
64 
65 
66 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
67 
69 {} // Define here since polyMesh was forward declared
70 
71 
72 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
73 
75 (
76  const List<refineCell>& refCells
77 )
78 {
79  Map<label> addedCells(2*refCells.size());
80 
81  Time& runTime = const_cast<Time&>(mesh_.time());
82 
83  label nRefCells = refCells.size();
84 
85  label oldRefCells = -1;
86 
87  // Operate on copy.
88  List<refineCell> currentRefCells(refCells);
89 
90  bool stop = false;
91 
92  do
93  {
94  if (writeMesh_)
95  {
96  // Need different times to write meshes.
97  ++runTime;
98  }
99 
100  polyTopoChange meshMod(mesh_);
101 
102  if (debug)
103  {
104  Pout<< "refinementIterator : refining "
105  << currentRefCells.size() << " cells." << endl;
106  }
107 
108  // Determine cut pattern.
109  cellCuts cuts(mesh_, cellWalker_, currentRefCells);
110 
111  if (!returnReduceOr(cuts.nLoops()))
112  {
113  if (debug)
114  {
115  Pout<< "refinementIterator : exiting iteration since no valid"
116  << " loops found for " << currentRefCells.size()
117  << " cells" << endl;
118 
119 
120  fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj");
121 
122  Pout<< "Writing cuts for time " << runTime.timeName()
123  << " to " << cutsFile << endl;
124 
125  OFstream cutsStream(cutsFile);
126 
127 
128  labelList refCellsDebug(currentRefCells.size());
129  forAll(currentRefCells, i)
130  {
131  refCellsDebug[i] = currentRefCells[i].cellNo();
132  }
134  (
135  cutsStream,
136  mesh().cells(),
137  mesh().faces(),
138  mesh().points(),
139  refCellsDebug
140  );
141  }
142 
143  break;
144  }
145 
146  if (debug)
147  {
148  fileName cutsFile("cuts_" + runTime.timeName() + ".obj");
149 
150  Pout<< "Writing cuts for time " << runTime.timeName()
151  << " to " << cutsFile << endl;
152 
153  OFstream cutsStream(cutsFile);
154  cuts.writeOBJ(cutsStream);
155  }
156 
157 
158  // Insert mesh refinement into polyTopoChange.
159  meshRefiner_.setRefinement(cuts, meshMod);
160 
161 
162  //
163  // Do all changes
164  //
165 
166  autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh
167  (
168  mesh_,
169  false
170  );
171 
172  // Move mesh (since morphing does not do this)
173  if (morphMap().hasMotionPoints())
174  {
175  mesh_.movePoints(morphMap().preMotionPoints());
176  }
177 
178  // Update stored refinement pattern
179  meshRefiner_.updateMesh(morphMap());
180 
181  // Write resulting mesh
182  if (writeMesh_)
183  {
184  if (debug)
185  {
186  Pout<< "Writing refined polyMesh to time "
187  << runTime.timeName() << endl;
188  }
189 
190  mesh_.write();
191  }
192 
193  // Update currentRefCells for new cell numbers. Use helper function
194  // in meshCutter class.
195  updateLabels
196  (
197  morphMap->reverseCellMap(),
198  currentRefCells
199  );
200 
201  // Update addedCells for new cell numbers
202  updateLabels
203  (
204  morphMap->reverseCellMap(),
205  addedCells
206  );
207 
208  // Get all added cells from cellCutter (already in new numbering
209  // from meshRefiner.updateMesh call) and add to global list of added
210  const Map<label>& addedNow = meshRefiner_.addedCells();
211 
212  forAllConstIters(addedNow, iter)
213  {
214  if (!addedCells.insert(iter.key(), iter.val()))
215  {
217  << "Master cell " << iter.key()
218  << " already has been refined" << endl
219  << "Added cell:" << iter.val() << abort(FatalError);
220  }
221  }
222 
223 
224  // Get failed refinement in new cell numbering and reconstruct input
225  // to the meshRefiner. Is done by removing all refined cells from
226  // current list of cells to refine.
227 
228  // Update refCells for new cell numbers.
229  updateLabels
230  (
231  morphMap->reverseCellMap(),
232  currentRefCells
233  );
234 
235  // Pack refCells acc. to refined status
236  nRefCells = 0;
237 
238  forAll(currentRefCells, refI)
239  {
240  const refineCell& refCell = currentRefCells[refI];
241 
242  if (!addedNow.found(refCell.cellNo()))
243  {
244  if (nRefCells != refI)
245  {
246  currentRefCells[nRefCells++] =
247  refineCell
248  (
249  refCell.cellNo(),
250  refCell.direction()
251  );
252  }
253  }
254  }
255 
256  oldRefCells = currentRefCells.size();
257 
258  currentRefCells.setSize(nRefCells);
259 
260  if (debug)
261  {
262  Pout<< endl;
263  }
264 
265  // Stop only if all finished or all can't refine any further.
266  stop = returnReduceAnd(nRefCells == 0 || nRefCells == oldRefCells);
267  }
268  while (!stop);
269 
270 
271  if (returnReduceAnd(nRefCells == oldRefCells))
272  {
274  << "stopped refining."
275  << "Did not manage to refine a single cell" << endl
276  << "Wanted :" << oldRefCells << endl;
277  }
278 
279  return addedCells;
280 }
281 
282 
283 
284 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
Map< label > setRefinement(const List< refineCell > &)
Try to refine cells in given direction. Constructs intermediate.
engineTime & runTime
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Definition: cellLooper.H:68
The main refinement handler. Gets cellCuts which is structure that describes which cells are to be cu...
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:196
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
dynamicFvMesh & mesh
const cellShapeList & cells
const pointField & points
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
Definition: edgeVertex.H:51
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
static word timeName(const scalar t, const int precision=precision_)
Return a time name for the given scalar time value formatted with the given precision.
Definition: Time.C:714
Utility class to do iterating meshCutter until all requests satisfied.
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
#define WarningInFunction
Report a warning using Foam::Warning.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
List< label > labelList
A List of labels.
Definition: List.H:62
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
refinementIterator(polyMesh &mesh, undoableMeshCutter &meshRefiner, const cellLooper &cellWalker, const bool writeMesh=false)
Construct from mesh, refinementEngine and cell walking routine.
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
A HashTable to objects of type <T> with a label key.