refinementIterator.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2024 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
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 "polyTopoChangeMap.H"
33 #include "cellCuts.H"
34 #include "OFstream.H"
35 #include "meshTools.H"
36 
37 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38 
39 namespace Foam
40 {
42 }
43 
44 
45 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
46 
47 // Construct from components
49 (
50  polyMesh& mesh,
51  undoableMeshCutter& meshRefiner,
52  const cellLooper& cellWalker,
53  const bool writeMesh
54 )
55 :
56  edgeVertex(mesh),
57  mesh_(mesh),
58  meshRefiner_(meshRefiner),
59  cellWalker_(cellWalker),
60  writeMesh_(writeMesh)
61 {}
62 
63 
64 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
65 
67 {}
68 
69 
70 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
71 
73 (
74  const List<refineCell>& refCells
75 )
76 {
77  Map<label> addedCells(2*refCells.size());
78 
79  Time& runTime = const_cast<Time&>(mesh_.time());
80 
81  label nRefCells = refCells.size();
82 
83  label oldRefCells = -1;
84 
85  // Operate on copy.
86  List<refineCell> currentRefCells(refCells);
87 
88  bool stop = false;
89 
90  do
91  {
92  if (writeMesh_)
93  {
94  // Need different times to write meshes.
95  runTime++;
96  }
97 
98  polyTopoChange meshMod(mesh_);
99 
100  if (debug)
101  {
102  Pout<< "refinementIterator : refining "
103  << currentRefCells.size() << " cells." << endl;
104  }
105 
106  // Determine cut pattern.
107  cellCuts cuts(mesh_, cellWalker_, currentRefCells);
108 
109  label nCuts = cuts.nLoops();
110  reduce(nCuts, sumOp<label>());
111 
112  if (nCuts == 0)
113  {
114  if (debug)
115  {
116  Pout<< "refinementIterator : exiting iteration since no valid"
117  << " loops found for " << currentRefCells.size()
118  << " cells" << endl;
119 
120 
121  fileName cutsFile("failedCuts_" + runTime.name() + ".obj");
122 
123  Pout<< "Writing cuts for time " << runTime.name()
124  << " to " << cutsFile << endl;
125 
126  OFstream cutsStream(cutsFile);
127 
128 
129  labelList refCellsDebug(currentRefCells.size());
130  forAll(currentRefCells, i)
131  {
132  refCellsDebug[i] = currentRefCells[i].cellNo();
133  }
135  (
136  cutsStream,
137  mesh().cells(),
138  mesh().faces(),
139  mesh().points(),
140  refCellsDebug
141  );
142  }
143 
144  break;
145  }
146 
147  if (debug)
148  {
149  fileName cutsFile("cuts_" + runTime.name() + ".obj");
150 
151  Pout<< "Writing cuts for time " << runTime.name()
152  << " to " << cutsFile << endl;
153 
154  OFstream cutsStream(cutsFile);
155  cuts.writeOBJ(cutsStream);
156  }
157 
158 
159  // Insert mesh refinement into polyTopoChange.
160  meshRefiner_.setRefinement(cuts, meshMod);
161 
162 
163  //
164  // Do all changes
165  //
166 
167  autoPtr<polyTopoChangeMap> map = meshMod.changeMesh(mesh_);
168 
169  // Update stored refinement pattern
170  meshRefiner_.topoChange(map());
171 
172  // Write resulting mesh
173  if (writeMesh_)
174  {
175  if (debug)
176  {
177  Pout<< "Writing refined polyMesh to time "
178  << runTime.name() << endl;
179  }
180 
181  mesh_.write();
182  }
183 
184  // Update currentRefCells for new cell numbers. Use helper function
185  // in meshCutter class.
186  updateLabels
187  (
188  map->reverseCellMap(),
189  currentRefCells
190  );
191 
192  // Update addedCells for new cell numbers
193  updateLabels
194  (
195  map->reverseCellMap(),
196  addedCells
197  );
198 
199  // Get all added cells from cellCutter (already in new numbering
200  // from meshRefiner.topoChange call) and add to global list of added
201  const Map<label>& addedNow = meshRefiner_.addedCells();
202 
203  forAllConstIter(Map<label>, addedNow, iter)
204  {
205  if (!addedCells.insert(iter.key(), iter()))
206  {
208  << "Master cell " << iter.key()
209  << " already has been refined" << endl
210  << "Added cell:" << iter() << abort(FatalError);
211  }
212  }
213 
214 
215  // Get failed refinement in new cell numbering and reconstruct input
216  // to the meshRefiner. Is done by removing all refined cells from
217  // current list of cells to refine.
218 
219  // Update refCells for new cell numbers.
220  updateLabels
221  (
222  map->reverseCellMap(),
223  currentRefCells
224  );
225 
226  // Pack refCells acc. to refined status
227  nRefCells = 0;
228 
229  forAll(currentRefCells, refI)
230  {
231  const refineCell& refCell = currentRefCells[refI];
232 
233  if (!addedNow.found(refCell.cellNo()))
234  {
235  if (nRefCells != refI)
236  {
237  currentRefCells[nRefCells++] =
238  refineCell
239  (
240  refCell.cellNo(),
241  refCell.direction()
242  );
243  }
244  }
245  }
246 
247  oldRefCells = currentRefCells.size();
248 
249  currentRefCells.setSize(nRefCells);
250 
251  if (debug)
252  {
253  Pout<< endl;
254  }
255 
256  // Stop only if all finished or all can't refine any further.
257  stop = (nRefCells == 0) || (nRefCells == oldRefCells);
258  reduce(stop, andOp<bool>());
259  }
260  while (!stop);
261 
262 
263  if (returnReduce((nRefCells == oldRefCells), andOp<bool>()))
264  {
266  << "stopped refining."
267  << "Did not manage to refine a single cell" << endl
268  << "Wanted :" << oldRefCells << endl;
269  }
270 
271  return addedCells;
272 }
273 
274 
275 
276 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:138
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
A HashTable to objects of type <T> with a label key.
Definition: Map.H:52
Output to file stream.
Definition: OFstream.H:86
virtual Ostream & write(const char)=0
Write character.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: autoPtr.H:51
Description of cuts across cells.
Definition: cellCuts.H:111
label nLoops() const
Number of valid cell loops.
Definition: cellCuts.H:569
Abstract base class. Concrete implementations know how to cut a cell (i.e. determine a loop around th...
Definition: cellLooper.H:72
const word & name() const
Return const reference to name.
Combines edge or vertex in single label. Used to specify cuts across cell circumference.
Definition: edgeVertex.H:53
A class for handling file names.
Definition: fileName.H:82
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
Direct mesh changes based on v1.3 polyTopoChange syntax.
autoPtr< polyTopoChangeMap > changeMesh(polyMesh &mesh, const bool syncParallel=true, const bool orderCells=false, const bool orderPoints=false)
Inplace changes mesh without change of patches.
Container with cells to refine. Refinement given as single direction.
Definition: refineCell.H:57
label cellNo() const
Definition: refineCell.H:82
const vector & direction() const
Definition: refineCell.H:87
Utility class to do iterating meshCutter until all requests satisfied.
refinementIterator(polyMesh &mesh, undoableMeshCutter &meshRefiner, const cellLooper &cellWalker, const bool writeMesh=false)
Construct from mesh, refinementEngine and cell walking routine.
Map< label > setRefinement(const List< refineCell > &)
Try to refine cells in given direction. Constructs intermediate.
The main refinement handler. Gets cellCuts which is structure that describes which cells are to be cu...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
const pointField & points
const cellShapeList & cells
#define WarningInFunction
Report a warning using Foam::Warning.
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
Namespace for OpenFOAM.
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:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:257
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
error FatalError