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 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 {
44  defineTypeNameAndDebug(refinementIterator, 0);
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  label nCuts = cuts.nLoops();
112  reduce(nCuts, sumOp<label>());
113 
114  if (nCuts == 0)
115  {
116  if (debug)
117  {
118  Pout<< "refinementIterator : exiting iteration since no valid"
119  << " loops found for " << currentRefCells.size()
120  << " cells" << endl;
121 
122 
123  fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj");
124 
125  Pout<< "Writing cuts for time " << runTime.timeName()
126  << " to " << cutsFile << endl;
127 
128  OFstream cutsStream(cutsFile);
129 
130 
131  labelList refCellsDebug(currentRefCells.size());
132  forAll(currentRefCells, i)
133  {
134  refCellsDebug[i] = currentRefCells[i].cellNo();
135  }
137  (
138  cutsStream,
139  mesh().cells(),
140  mesh().faces(),
141  mesh().points(),
142  refCellsDebug
143  );
144  }
145 
146  break;
147  }
148 
149  if (debug)
150  {
151  fileName cutsFile("cuts_" + runTime.timeName() + ".obj");
152 
153  Pout<< "Writing cuts for time " << runTime.timeName()
154  << " to " << cutsFile << endl;
155 
156  OFstream cutsStream(cutsFile);
157  cuts.writeOBJ(cutsStream);
158  }
159 
160 
161  // Insert mesh refinement into polyTopoChange.
162  meshRefiner_.setRefinement(cuts, meshMod);
163 
164 
165  //
166  // Do all changes
167  //
168 
169  autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh
170  (
171  mesh_,
172  false
173  );
174 
175  // Move mesh (since morphing does not do this)
176  if (morphMap().hasMotionPoints())
177  {
178  mesh_.movePoints(morphMap().preMotionPoints());
179  }
180 
181  // Update stored refinement pattern
182  meshRefiner_.updateMesh(morphMap());
183 
184  // Write resulting mesh
185  if (writeMesh_)
186  {
187  if (debug)
188  {
189  Pout<< "Writing refined polyMesh to time "
190  << runTime.timeName() << endl;
191  }
192 
193  mesh_.write();
194  }
195 
196  // Update currentRefCells for new cell numbers. Use helper function
197  // in meshCutter class.
198  updateLabels
199  (
200  morphMap->reverseCellMap(),
201  currentRefCells
202  );
203 
204  // Update addedCells for new cell numbers
205  updateLabels
206  (
207  morphMap->reverseCellMap(),
208  addedCells
209  );
210 
211  // Get all added cells from cellCutter (already in new numbering
212  // from meshRefiner.updateMesh call) and add to global list of added
213  const Map<label>& addedNow = meshRefiner_.addedCells();
214 
215  forAllConstIters(addedNow, iter)
216  {
217  if (!addedCells.insert(iter.key(), iter.val()))
218  {
220  << "Master cell " << iter.key()
221  << " already has been refined" << endl
222  << "Added cell:" << iter.val() << abort(FatalError);
223  }
224  }
225 
226 
227  // Get failed refinement in new cell numbering and reconstruct input
228  // to the meshRefiner. Is done by removing all refined cells from
229  // current list of cells to refine.
230 
231  // Update refCells for new cell numbers.
232  updateLabels
233  (
234  morphMap->reverseCellMap(),
235  currentRefCells
236  );
237 
238  // Pack refCells acc. to refined status
239  nRefCells = 0;
240 
241  forAll(currentRefCells, refI)
242  {
243  const refineCell& refCell = currentRefCells[refI];
244 
245  if (!addedNow.found(refCell.cellNo()))
246  {
247  if (nRefCells != refI)
248  {
249  currentRefCells[nRefCells++] =
250  refineCell
251  (
252  refCell.cellNo(),
253  refCell.direction()
254  );
255  }
256  }
257  }
258 
259  oldRefCells = currentRefCells.size();
260 
261  currentRefCells.setSize(nRefCells);
262 
263  if (debug)
264  {
265  Pout<< endl;
266  }
267 
268  // Stop only if all finished or all can't refine any further.
269  stop = (nRefCells == 0) || (nRefCells == oldRefCells);
270  reduce(stop, andOp<bool>());
271  }
272  while (!stop);
273 
274 
275  if (returnReduce((nRefCells == oldRefCells), andOp<bool>()))
276  {
278  << "stopped refining."
279  << "Did not manage to refine a single cell" << endl
280  << "Wanted :" << oldRefCells << endl;
281  }
282 
283  return addedCells;
284 }
285 
286 
287 
288 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
runTime
engineTime & runTime
Definition: createEngineTime.H:13
meshTools.H
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::cellCuts::nLoops
label nLoops() const
Number of valid cell loops.
Definition: cellCuts.H:596
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
Foam::refinementIterator::setRefinement
Map< label > setRefinement(const List< refineCell > &)
Try to refine cells in given direction. Constructs intermediate.
Definition: refinementIterator.C:75
mapPolyMesh.H
polyTopoChange.H
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:99
Foam::edgeVertex
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
Definition: edgeVertex.H:55
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: lumpedPointController.H:69
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
undoableMeshCutter.H
polyMesh.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
OFstream.H
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::List::setSize
void setSize(const label n)
Alias for resize()
Definition: List.H:222
Foam::cellLooper
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Definition: cellLooper.H:72
Foam::andOp
Definition: ops.H:233
refineCell.H
Foam::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, const labelUList &patchMap, const bool inflate, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Definition: polyTopoChange.C:2980
cellCuts.H
Foam::refineCell::direction
const vector & direction() const
Definition: refineCell.H:88
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::refinementIterator::~refinementIterator
~refinementIterator()
Destructor.
Definition: refinementIterator.C:68
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:53
Time.H
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::mapPolyMesh::reverseCellMap
const labelList & reverseCellMap() const
Reverse cell map.
Definition: mapPolyMesh.H:532
Foam::refineCell
Container with cells to refine. Refinement given as single direction.
Definition: refineCell.H:56
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
forAllConstIters
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
Foam::List< refineCell >
points
const pointField & points
Definition: gmvOutputHeader.H:1
refinementIterator.H
Foam::refineCell::cellNo
label cellNo() const
Definition: refineCell.H:83
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::refinementIterator::refinementIterator
refinementIterator(polyMesh &mesh, undoableMeshCutter &meshRefiner, const cellLooper &cellWalker, const bool writeMesh=false)
Construct from mesh, refinementEngine and cell walking routine.
Definition: refinementIterator.C:51
Foam::undoableMeshCutter
The main refinement handler. Gets cellCuts which is structure that describes which cells are to be cu...
Definition: undoableMeshCutter.H:93
Foam::cellCuts
Description of cuts across cells.
Definition: cellCuts.H:110