FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

errorDrivenRefinement.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "errorDrivenRefinement.H"
00027 #include <dynamicMesh/polyTopoChanger.H>
00028 #include <OpenFOAM/polyMesh.H>
00029 #include <OpenFOAM/primitiveMesh.H>
00030 #include <dynamicMesh/polyTopoChange.H>
00031 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00032 #include <finiteVolume/volFields.H>
00033 #include <finiteVolume/surfaceFields.H>
00034 #include <errorEstimation/evaluateError.H>
00035 #include <finiteVolume/fvc.H>
00036 #include <OpenFOAM/mapPolyMesh.H>
00037 #include <dynamicMesh/topoCellLooper.H>
00038 #include <dynamicMesh/cellCuts.H>
00039 
00040 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00041 
00042 namespace Foam
00043 {
00044     defineTypeNameAndDebug(errorDrivenRefinement, 0);
00045     addToRunTimeSelectionTable
00046     (
00047         polyMeshModifier,
00048         errorDrivenRefinement,
00049         dictionary
00050     );
00051 }
00052 
00053 
00054 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00055 
00056 
00057 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00058 
00059 // Construct from dictionary
00060 Foam::errorDrivenRefinement::errorDrivenRefinement
00061 (
00062     const word& name,
00063     const dictionary& dict,
00064     const label index,
00065     const polyTopoChanger& mme
00066 )
00067 :
00068     polyMeshModifier(name, index, mme, false),
00069     refinementEngine_(topoChanger().mesh(), true),
00070     errorField_(dict.lookup("errorField"))
00071 {}
00072 
00073 
00074 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00075 
00076 Foam::errorDrivenRefinement::~errorDrivenRefinement()
00077 {}
00078 
00079 
00080 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00081 
00082 
00083 bool Foam::errorDrivenRefinement::changeTopology() const
00084 {
00085     const Time& runTime = topoChanger().mesh().time();
00086 
00087     if (runTime.foundObject<volVectorField>(errorField_))
00088     {
00089         if (debug)
00090         {
00091             Info<< "errorDrivenRefinement::changeTopology() : triggering topo"
00092                 << " change since found errorField "
00093                 << errorField_ << endl;
00094         }
00095 
00096         return true;
00097     }
00098     else
00099     {
00100         if (debug)
00101         {
00102             Info<< "errorDrivenRefinement::changeTopology() : no topo"
00103                 << " change request from me since no errorField "
00104                 << errorField_ << endl;
00105         }
00106 
00107         return false;
00108     }
00109 }
00110 
00111 
00112 void Foam::errorDrivenRefinement::setRefinement(polyTopoChange& ref) const
00113 {
00114     // Insert the coarsen/refinement instructions into the topological change
00115 
00116     if (debug)
00117     {
00118         Info<< "errorDrivenRefinement::setRefinement(polyTopoChange& ref)"
00119             << endl;
00120     }
00121 
00122     const polyMesh& mesh = topoChanger().mesh();
00123 
00124     const Time& runTime = mesh.time();
00125 
00126     if (debug)
00127     {
00128         Info<< "Looking up vector field with name " << errorField_ << endl;
00129     }
00130     const volVectorField& resError =
00131         runTime.lookupObject<volVectorField>(errorField_);
00132 
00133     const volScalarField magResError = Foam::mag(resError);
00134 
00135     scalar min = Foam::min(magResError).value();
00136     scalar max = Foam::max(magResError).value();
00137     scalar avg = Foam::average(magResError).value();
00138 
00139     if (debug) 
00140     {
00141         Info<< "Writing magResError" << endl;
00142         magResError.write();
00143 
00144         Info<< "min:" << min << " max:" << max << " avg:" << avg << endl;
00145     }
00146 
00147     // Get faces to remove and cells to refine based on error
00148     evaluateError refPattern
00149     (
00150         magResError,                        // Error on cells
00151         resError,                           // Error vector on cells
00152         fvc::interpolate(magResError),      // Error on faces
00153         refinementEngine_.getSplitFaces()   // Current live split faces
00154     );
00155 
00156 
00157     // Insert mesh refinement into polyTopoChange:
00158     // - remove split faces
00159     // - refine cells
00160 
00161     // Give 'hint' of faces to remove to cell splitter.
00162     const labelList& candidates = refPattern.unsplitFaces();
00164     //labelList candidates;
00165 
00166     labelList removedFaces(refinementEngine_.removeSplitFaces(candidates, ref));
00167 
00168     // Now success will be for every candidates whether face has been removed.
00169     // Protect cells using face from refinement.
00170 
00171     // List of protected cells
00172     boolList markedCell(mesh.nCells(), false);
00173 
00174     forAll(removedFaces, i)
00175     {
00176         label faceI = removedFaces[i];
00177 
00178         markedCell[mesh.faceOwner()[faceI]] = true;
00179 
00180         if (mesh.isInternalFace(faceI))
00181         {
00182             markedCell[mesh.faceNeighbour()[faceI]] = true;
00183         }
00184     }
00185     
00186     // Repack list of cells to refine.
00187     List<refineCell> refCells = refPattern.refCells();
00188 
00189     label newRefCellI = 0;
00190 
00191     forAll(refCells, refCellI)
00192     {
00193         label cellI = refCells[refCellI].cellNo();
00194 
00195         if (!markedCell[cellI] && (newRefCellI != refCellI))
00196         {
00197             refCells[newRefCellI++] = refCells[refCellI];
00198         }
00199     }
00200 
00201     if (debug)
00202     {
00203         Info<< "errorDrivenRefinement : shrinking refCells from "
00204             << refCells.size()
00205             << " to " << newRefCellI << endl;
00206     }
00207 
00208     refCells.setSize(newRefCellI);
00209 
00210     // Determine cut pattern using topological cell walker
00211     topoCellLooper cellWalker(mesh);
00212 
00213     cellCuts cuts(mesh, cellWalker, refCells);
00214 
00215     // Do actual splitting
00216     refinementEngine_.setRefinement(cuts, ref);
00217 }
00218 
00219 
00220 // Has the responsability of moving my newly introduced points onto the right
00221 // place. This is since the whole mesh might e.g. have been moved by another
00222 // meshmodifier. So using preMotionPoints is hack for if I am only meshModifier.
00223 // Good solution:
00224 // - remember new point label of introduced point and vertices
00225 // of edge it is created from (in setRefinement)
00226 // - in here reposition point at correct position between current vertex
00227 // position of edge endpoints.
00228 void Foam::errorDrivenRefinement::modifyMotionPoints
00229 (
00230     pointField& motionPoints
00231 ) const
00232 {
00233     if (debug)
00234     {
00235         Info<< "errorDrivenRefinement::modifyMotionPoints(*pointField&)" << endl;
00236     }
00237 }
00238 
00239 
00240 void Foam::errorDrivenRefinement::updateMesh(const mapPolyMesh& morphMap)
00241 {
00242     // Mesh has changed topologically. Update local topological data
00243     if (debug)
00244     {
00245         Info<< "errorDrivenRefinement::updateMesh"
00246             << "(const mapPolyMesh& morphMap)" << endl;
00247     }
00248     refinementEngine_.updateMesh(morphMap);
00249 }
00250 
00251 
00252 void Foam::errorDrivenRefinement::write(Ostream& os) const
00253 {
00254     os  << nl << type() << nl;
00255 }
00256 
00257 
00258 void Foam::errorDrivenRefinement::writeDict(Ostream& os) const
00259 {
00260     os  << nl << name() << nl << token::BEGIN_BLOCK << nl
00261         << "    type " << type()
00262         << token::END_STATEMENT << nl
00263         << token::END_BLOCK << endl;
00264 }
00265 
00266 
00267 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00268 
00269 
00270 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
00271 
00272 
00273 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
00274 
00275 
00276 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines