FreeFOAM The Cross-Platform CFD Toolkit
errorDrivenRefinement.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 | Copyright (C) 1991-2010 OpenCFD Ltd.
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 "errorDrivenRefinement.H"
28 #include <OpenFOAM/polyMesh.H>
29 #include <OpenFOAM/primitiveMesh.H>
32 #include <finiteVolume/volFields.H>
35 #include <finiteVolume/fvc.H>
36 #include <OpenFOAM/mapPolyMesh.H>
38 #include <dynamicMesh/cellCuts.H>
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44  defineTypeNameAndDebug(errorDrivenRefinement, 0);
46  (
47  polyMeshModifier,
48  errorDrivenRefinement,
49  dictionary
50  );
51 }
52 
53 
54 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
55 
56 
57 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
58 
59 // Construct from dictionary
60 Foam::errorDrivenRefinement::errorDrivenRefinement
61 (
62  const word& name,
63  const dictionary& dict,
64  const label index,
65  const polyTopoChanger& mme
66 )
67 :
68  polyMeshModifier(name, index, mme, false),
69  refinementEngine_(topoChanger().mesh(), true),
70  errorField_(dict.lookup("errorField"))
71 {}
72 
73 
74 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
75 
77 {}
78 
79 
80 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
81 
82 
84 {
85  const Time& runTime = topoChanger().mesh().time();
86 
87  if (runTime.foundObject<volVectorField>(errorField_))
88  {
89  if (debug)
90  {
91  Info<< "errorDrivenRefinement::changeTopology() : triggering topo"
92  << " change since found errorField "
93  << errorField_ << endl;
94  }
95 
96  return true;
97  }
98  else
99  {
100  if (debug)
101  {
102  Info<< "errorDrivenRefinement::changeTopology() : no topo"
103  << " change request from me since no errorField "
104  << errorField_ << endl;
105  }
106 
107  return false;
108  }
109 }
110 
111 
113 {
114  // Insert the coarsen/refinement instructions into the topological change
115 
116  if (debug)
117  {
118  Info<< "errorDrivenRefinement::setRefinement(polyTopoChange& ref)"
119  << endl;
120  }
121 
122  const polyMesh& mesh = topoChanger().mesh();
123 
124  const Time& runTime = mesh.time();
125 
126  if (debug)
127  {
128  Info<< "Looking up vector field with name " << errorField_ << endl;
129  }
130  const volVectorField& resError =
131  runTime.lookupObject<volVectorField>(errorField_);
132 
133  const volScalarField magResError = Foam::mag(resError);
134 
135  scalar min = Foam::min(magResError).value();
136  scalar max = Foam::max(magResError).value();
137  scalar avg = Foam::average(magResError).value();
138 
139  if (debug)
140  {
141  Info<< "Writing magResError" << endl;
142  magResError.write();
143 
144  Info<< "min:" << min << " max:" << max << " avg:" << avg << endl;
145  }
146 
147  // Get faces to remove and cells to refine based on error
148  evaluateError refPattern
149  (
150  magResError, // Error on cells
151  resError, // Error vector on cells
152  fvc::interpolate(magResError), // Error on faces
153  refinementEngine_.getSplitFaces() // Current live split faces
154  );
155 
156 
157  // Insert mesh refinement into polyTopoChange:
158  // - remove split faces
159  // - refine cells
160 
161  // Give 'hint' of faces to remove to cell splitter.
162  const labelList& candidates = refPattern.unsplitFaces();
164  //labelList candidates;
165 
166  labelList removedFaces(refinementEngine_.removeSplitFaces(candidates, ref));
167 
168  // Now success will be for every candidates whether face has been removed.
169  // Protect cells using face from refinement.
170 
171  // List of protected cells
172  boolList markedCell(mesh.nCells(), false);
173 
174  forAll(removedFaces, i)
175  {
176  label faceI = removedFaces[i];
177 
178  markedCell[mesh.faceOwner()[faceI]] = true;
179 
180  if (mesh.isInternalFace(faceI))
181  {
182  markedCell[mesh.faceNeighbour()[faceI]] = true;
183  }
184  }
185 
186  // Repack list of cells to refine.
187  List<refineCell> refCells = refPattern.refCells();
188 
189  label newRefCellI = 0;
190 
191  forAll(refCells, refCellI)
192  {
193  label cellI = refCells[refCellI].cellNo();
194 
195  if (!markedCell[cellI] && (newRefCellI != refCellI))
196  {
197  refCells[newRefCellI++] = refCells[refCellI];
198  }
199  }
200 
201  if (debug)
202  {
203  Info<< "errorDrivenRefinement : shrinking refCells from "
204  << refCells.size()
205  << " to " << newRefCellI << endl;
206  }
207 
208  refCells.setSize(newRefCellI);
209 
210  // Determine cut pattern using topological cell walker
211  topoCellLooper cellWalker(mesh);
212 
213  cellCuts cuts(mesh, cellWalker, refCells);
214 
215  // Do actual splitting
216  refinementEngine_.setRefinement(cuts, ref);
217 }
218 
219 
220 // Has the responsability of moving my newly introduced points onto the right
221 // place. This is since the whole mesh might e.g. have been moved by another
222 // meshmodifier. So using preMotionPoints is hack for if I am only meshModifier.
223 // Good solution:
224 // - remember new point label of introduced point and vertices
225 // of edge it is created from (in setRefinement)
226 // - in here reposition point at correct position between current vertex
227 // position of edge endpoints.
229 (
230  pointField& motionPoints
231 ) const
232 {
233  if (debug)
234  {
235  Info<< "errorDrivenRefinement::modifyMotionPoints(*pointField&)" << endl;
236  }
237 }
238 
239 
241 {
242  // Mesh has changed topologically. Update local topological data
243  if (debug)
244  {
245  Info<< "errorDrivenRefinement::updateMesh"
246  << "(const mapPolyMesh& morphMap)" << endl;
247  }
248  refinementEngine_.updateMesh(morphMap);
249 }
250 
251 
253 {
254  os << nl << type() << nl;
255 }
256 
257 
259 {
260  os << nl << name() << nl << token::BEGIN_BLOCK << nl
261  << " type " << type()
263  << token::END_BLOCK << endl;
264 }
265 
266 
267 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
268 
269 
270 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
271 
272 
273 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
274 
275 
276 // ************************ vim: set sw=4 sts=4 et: ************************ //