1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "errorDrivenRefinement.H"
28 #include <dynamicMesh/polyTopoChanger.H>
29 #include <OpenFOAM/polyMesh.H>
30 #include <OpenFOAM/primitiveMesh.H>
31 #include <dynamicMesh/polyTopoChange.H>
32 #include <OpenFOAM/addToRunTimeSelectionTable.H>
33 #include <finiteVolume/volFields.H>
34 #include <finiteVolume/surfaceFields.H>
35 #include <errorEstimation/evaluateError.H>
36 #include <finiteVolume/fvc.H>
37 #include <OpenFOAM/mapPolyMesh.H>
38 #include <dynamicMesh/topoCellLooper.H>
39 #include <dynamicMesh/cellCuts.H>
41 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
45 defineTypeNameAndDebug(errorDrivenRefinement, 0);
46 addToRunTimeSelectionTable
49 errorDrivenRefinement,
55 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
58 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
60 // Construct from dictionary
61 Foam::errorDrivenRefinement::errorDrivenRefinement
64 const dictionary& dict,
66 const polyTopoChanger& mme
69 polyMeshModifier(name, index, mme, false),
70 refinementEngine_(topoChanger().mesh(), true),
71 errorField_(dict.lookup("errorField"))
75 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
77 Foam::errorDrivenRefinement::~errorDrivenRefinement()
81 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
84 bool Foam::errorDrivenRefinement::changeTopology() const
86 const Time& runTime = topoChanger().mesh().time();
88 if (runTime.foundObject<volVectorField>(errorField_))
92 Info<< "errorDrivenRefinement::changeTopology() : triggering topo"
93 << " change since found errorField "
94 << errorField_ << endl;
103 Info<< "errorDrivenRefinement::changeTopology() : no topo"
104 << " change request from me since no errorField "
105 << errorField_ << endl;
113 void Foam::errorDrivenRefinement::setRefinement(polyTopoChange& ref) const
115 // Insert the coarsen/refinement instructions into the topological change
119 Info<< "errorDrivenRefinement::setRefinement(polyTopoChange& ref)"
123 const polyMesh& mesh = topoChanger().mesh();
125 const Time& runTime = mesh.time();
129 Info<< "Looking up vector field with name " << errorField_ << endl;
131 const volVectorField& resError =
132 runTime.lookupObject<volVectorField>(errorField_);
134 const volScalarField magResError = Foam::mag(resError);
136 scalar min = Foam::min(magResError).value();
137 scalar max = Foam::max(magResError).value();
138 scalar avg = Foam::average(magResError).value();
142 Info<< "Writing magResError" << endl;
145 Info<< "min:" << min << " max:" << max << " avg:" << avg << endl;
148 // Get faces to remove and cells to refine based on error
149 evaluateError refPattern
151 magResError, // Error on cells
152 resError, // Error vector on cells
153 fvc::interpolate(magResError), // Error on faces
154 refinementEngine_.getSplitFaces() // Current live split faces
158 // Insert mesh refinement into polyTopoChange:
159 // - remove split faces
162 // Give 'hint' of faces to remove to cell splitter.
163 const labelList& candidates = refPattern.unsplitFaces();
164 ////Hack:no unsplitting
165 //labelList candidates;
167 labelList removedFaces(refinementEngine_.removeSplitFaces(candidates, ref));
169 // Now success will be for every candidates whether face has been removed.
170 // Protect cells using face from refinement.
172 // List of protected cells
173 boolList markedCell(mesh.nCells(), false);
175 forAll(removedFaces, i)
177 label faceI = removedFaces[i];
179 markedCell[mesh.faceOwner()[faceI]] = true;
181 if (mesh.isInternalFace(faceI))
183 markedCell[mesh.faceNeighbour()[faceI]] = true;
187 // Repack list of cells to refine.
188 List<refineCell> refCells = refPattern.refCells();
190 label newRefCellI = 0;
192 forAll(refCells, refCellI)
194 label cellI = refCells[refCellI].cellNo();
196 if (!markedCell[cellI] && (newRefCellI != refCellI))
198 refCells[newRefCellI++] = refCells[refCellI];
204 Info<< "errorDrivenRefinement : shrinking refCells from "
206 << " to " << newRefCellI << endl;
209 refCells.setSize(newRefCellI);
211 // Determine cut pattern using topological cell walker
212 topoCellLooper cellWalker(mesh);
214 cellCuts cuts(mesh, cellWalker, refCells);
216 // Do actual splitting
217 refinementEngine_.setRefinement(cuts, ref);
221 // Has the responsability of moving my newly introduced points onto the right
222 // place. This is since the whole mesh might e.g. have been moved by another
223 // meshmodifier. So using preMotionPoints is hack for if I am only meshModifier.
225 // - remember new point label of introduced point and vertices
226 // of edge it is created from (in setRefinement)
227 // - in here reposition point at correct position between current vertex
228 // position of edge endpoints.
229 void Foam::errorDrivenRefinement::modifyMotionPoints
231 pointField& motionPoints
236 Info<< "errorDrivenRefinement::modifyMotionPoints(*pointField&)" << endl;
241 void Foam::errorDrivenRefinement::updateMesh(const mapPolyMesh& morphMap)
243 // Mesh has changed topologically. Update local topological data
246 Info<< "errorDrivenRefinement::updateMesh"
247 << "(const mapPolyMesh& morphMap)" << endl;
249 refinementEngine_.updateMesh(morphMap);
253 void Foam::errorDrivenRefinement::write(Ostream& os) const
255 os << nl << type() << nl;
259 void Foam::errorDrivenRefinement::writeDict(Ostream& os) const
261 os << nl << name() << nl << token::BEGIN_BLOCK << nl
262 << " type " << type()
263 << token::END_STATEMENT << nl
264 << token::END_BLOCK << endl;
268 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
271 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
274 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
277 // ************************ vim: set sw=4 sts=4 et: ************************ //