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 
50 // Construct from components
52 (
53  polyMesh& mesh,
54  undoableMeshCutter& meshRefiner,
55  const cellLooper& cellWalker,
56  const bool writeMesh
57 )
58 :
60  mesh_(mesh),
61  meshRefiner_(meshRefiner),
62  cellWalker_(cellWalker),
63  writeMesh_(writeMesh)
64 {}
65 
66 
67 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
68 
70 {}
71 
72 
73 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
74 
76 (
77  const List<refineCell>& refCells
78 )
79 {
80  Map<label> addedCells(2*refCells.size());
81 
82  Time& runTime = const_cast<Time&>(mesh_.time());
83 
84  label nRefCells = refCells.size();
85 
86  label oldRefCells = -1;
87 
88  // Operate on copy.
89  List<refineCell> currentRefCells(refCells);
90 
91  bool stop = false;
92 
93  do
94  {
95  if (writeMesh_)
96  {
97  // Need different times to write meshes.
98  ++runTime;
99  }
100 
101  polyTopoChange meshMod(mesh_);
102 
103  if (debug)
104  {
105  Pout<< "refinementIterator : refining "
106  << currentRefCells.size() << " cells." << endl;
107  }
108 
109  // Determine cut pattern.
110  cellCuts cuts(mesh_, cellWalker_, currentRefCells);
111 
112  label nCuts = cuts.nLoops();
113  reduce(nCuts, sumOp<label>());
114 
115  if (nCuts == 0)
116  {
117  if (debug)
118  {
119  Pout<< "refinementIterator : exiting iteration since no valid"
120  << " loops found for " << currentRefCells.size()
121  << " cells" << endl;
122 
123 
124  fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj");
125 
126  Pout<< "Writing cuts for time " << runTime.timeName()
127  << " to " << cutsFile << endl;
128 
129  OFstream cutsStream(cutsFile);
130 
131 
132  labelList refCellsDebug(currentRefCells.size());
133  forAll(currentRefCells, i)
134  {
135  refCellsDebug[i] = currentRefCells[i].cellNo();
136  }
138  (
139  cutsStream,
140  mesh().cells(),
141  mesh().faces(),
142  mesh().points(),
143  refCellsDebug
144  );
145  }
146 
147  break;
148  }
149 
150  if (debug)
151  {
152  fileName cutsFile("cuts_" + runTime.timeName() + ".obj");
153 
154  Pout<< "Writing cuts for time " << runTime.timeName()
155  << " to " << cutsFile << endl;
156 
157  OFstream cutsStream(cutsFile);
158  cuts.writeOBJ(cutsStream);
159  }
160 
161 
162  // Insert mesh refinement into polyTopoChange.
163  meshRefiner_.setRefinement(cuts, meshMod);
164 
165 
166  //
167  // Do all changes
168  //
169 
170  autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh
171  (
172  mesh_,
173  false
174  );
175 
176  // Move mesh (since morphing does not do this)
177  if (morphMap().hasMotionPoints())
178  {
179  mesh_.movePoints(morphMap().preMotionPoints());
180  }
181 
182  // Update stored refinement pattern
183  meshRefiner_.updateMesh(morphMap());
184 
185  // Write resulting mesh
186  if (writeMesh_)
187  {
188  if (debug)
189  {
190  Pout<< "Writing refined polyMesh to time "
191  << runTime.timeName() << endl;
192  }
193 
194  mesh_.write();
195  }
196 
197  // Update currentRefCells for new cell numbers. Use helper function
198  // in meshCutter class.
199  updateLabels
200  (
201  morphMap->reverseCellMap(),
202  currentRefCells
203  );
204 
205  // Update addedCells for new cell numbers
206  updateLabels
207  (
208  morphMap->reverseCellMap(),
209  addedCells
210  );
211 
212  // Get all added cells from cellCutter (already in new numbering
213  // from meshRefiner.updateMesh call) and add to global list of added
214  const Map<label>& addedNow = meshRefiner_.addedCells();
215 
216  forAllConstIters(addedNow, iter)
217  {
218  if (!addedCells.insert(iter.key(), iter.val()))
219  {
221  << "Master cell " << iter.key()
222  << " already has been refined" << endl
223  << "Added cell:" << iter.val() << abort(FatalError);
224  }
225  }
226 
227 
228  // Get failed refinement in new cell numbering and reconstruct input
229  // to the meshRefiner. Is done by removing all refined cells from
230  // current list of cells to refine.
231 
232  // Update refCells for new cell numbers.
233  updateLabels
234  (
235  morphMap->reverseCellMap(),
236  currentRefCells
237  );
238 
239  // Pack refCells acc. to refined status
240  nRefCells = 0;
241 
242  forAll(currentRefCells, refI)
243  {
244  const refineCell& refCell = currentRefCells[refI];
245 
246  if (!addedNow.found(refCell.cellNo()))
247  {
248  if (nRefCells != refI)
249  {
250  currentRefCells[nRefCells++] =
251  refineCell
252  (
253  refCell.cellNo(),
254  refCell.direction()
255  );
256  }
257  }
258  }
259 
260  oldRefCells = currentRefCells.size();
261 
262  currentRefCells.setSize(nRefCells);
263 
264  if (debug)
265  {
266  Pout<< endl;
267  }
268 
269  // Stop only if all finished or all can't refine any further.
270  stop = (nRefCells == 0) || (nRefCells == oldRefCells);
271  reduce(stop, andOp<bool>());
272  }
273  while (!stop);
274 
275 
276  if (returnReduce((nRefCells == oldRefCells), andOp<bool>()))
277  {
279  << "stopped refining."
280  << "Did not manage to refine a single cell" << endl
281  << "Wanted :" << oldRefCells << endl;
282  }
283 
284  return addedCells;
285 }
286 
287 
288 
289 // ************************************************************************* //
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:595
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
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::polyTopoChange::changeMesh
autoPtr< mapPolyMesh > changeMesh(polyMesh &mesh, 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:2957
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:76
mapPolyMesh.H
polyTopoChange.H
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:764
Foam::polyTopoChange
Direct mesh changes based on v1.3 polyTopoChange syntax.
Definition: polyTopoChange.H:100
Foam::edgeVertex
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
Definition: edgeVertex.H:54
Foam::Map
A HashTable to objects of type <T> with a label key.
Definition: HashTableFwd.H:46
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::Pout
prefixOSstream Pout
An Ostream wrapper for parallel output to std::cout.
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:290
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::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::cellLooper
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Definition: cellLooper.H:71
Foam::andOp
Definition: ops.H:233
refineCell.H
cellCuts.H
Foam::refineCell::direction
const vector & direction() const
Definition: refineCell.H:89
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::refinementIterator::~refinementIterator
~refinementIterator()
Destructor.
Definition: refinementIterator.C:69
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:137
Foam::OFstream
Output to file stream, using an OSstream.
Definition: OFstream.H:99
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:531
Foam::refineCell
Container with cells to refine. Refinement given as single direction.
Definition: refineCell.H:58
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
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:84
cells
const cellShapeList & cells
Definition: gmvOutputHeader.H:3
Foam::List::setSize
void setSize(const label newSize)
Alias for resize(const label)
Definition: ListI.H:146
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294
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:52
Foam::undoableMeshCutter
The main refinement handler. Gets cellCuts which is structure that describes which cells are to be cu...
Definition: undoableMeshCutter.H:95
Foam::cellCuts
Description of cuts across cells.
Definition: cellCuts.H:110