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

refinementIterator.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 "refinementIterator.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <OpenFOAM/Time.H>
00029 #include <dynamicMesh/refineCell.H>
00030 #include <dynamicMesh/undoableMeshCutter.H>
00031 #include <dynamicMesh/polyTopoChange.H>
00032 #include <OpenFOAM/mapPolyMesh.H>
00033 #include <dynamicMesh/cellCuts.H>
00034 #include <OpenFOAM/OFstream.H>
00035 #include <meshTools/meshTools.H>
00036 
00037 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00038 
00039 namespace Foam
00040 {
00041 
00042 defineTypeNameAndDebug(refinementIterator, 0);
00043 
00044 }
00045 
00046 
00047 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00048 
00049 // Construct from components
00050 Foam::refinementIterator::refinementIterator
00051 (
00052     polyMesh& mesh,
00053     undoableMeshCutter& meshRefiner,
00054     const cellLooper& cellWalker,
00055     const bool writeMesh
00056 )
00057 :
00058     edgeVertex(mesh),
00059     mesh_(mesh),
00060     meshRefiner_(meshRefiner),
00061     cellWalker_(cellWalker),
00062     writeMesh_(writeMesh)
00063 {}
00064 
00065 
00066 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00067 
00068 Foam::refinementIterator::~refinementIterator()
00069 {}
00070 
00071 
00072 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00073 
00074 Foam::Map<Foam::label> Foam::refinementIterator::setRefinement
00075 (
00076     const List<refineCell>& refCells
00077 )
00078 {
00079     Map<label> addedCells(2*refCells.size());
00080 
00081     Time& runTime = const_cast<Time&>(mesh_.time());
00082 
00083     label nRefCells = refCells.size();
00084 
00085     label oldRefCells = -1;
00086 
00087     // Operate on copy.
00088     List<refineCell> currentRefCells(refCells);
00089 
00090     bool stop = false;
00091 
00092     do
00093     {
00094         if (writeMesh_)
00095         {
00096             // Need different times to write meshes.
00097             runTime++;
00098         }
00099 
00100         polyTopoChange meshMod(mesh_);
00101 
00102         if (debug)
00103         {
00104             Pout<< "refinementIterator : refining "
00105                 << currentRefCells.size() << " cells." << endl;
00106         }
00107 
00108         // Determine cut pattern.
00109         cellCuts cuts(mesh_, cellWalker_, currentRefCells);
00110 
00111         label nCuts = cuts.nLoops();
00112         reduce(nCuts, sumOp<label>());
00113 
00114         if (nCuts == 0)
00115         {
00116             if (debug)
00117             {
00118                 Pout<< "refinementIterator : exiting iteration since no valid"
00119                     << " loops found for " << currentRefCells.size() 
00120                     << " cells" << endl;
00121 
00122 
00123                 fileName cutsFile("failedCuts_" + runTime.timeName() + ".obj");
00124 
00125                 Pout<< "Writing cuts for time " <<  runTime.timeName()
00126                     << " to " << cutsFile << endl;
00127 
00128                 OFstream cutsStream(cutsFile);
00129 
00130 
00131                 labelList refCells(currentRefCells.size());
00132                 forAll(currentRefCells, i)
00133                 {
00134                     refCells[i] = currentRefCells[i].cellNo();
00135                 }
00136                 meshTools::writeOBJ
00137                 (
00138                     cutsStream,
00139                     mesh().cells(),
00140                     mesh().faces(),
00141                     mesh().points(),
00142                     refCells
00143                 );
00144             }
00145 
00146             break;
00147         }
00148             
00149         if (debug)
00150         {
00151             fileName cutsFile("cuts_" + runTime.timeName() + ".obj");
00152 
00153             Pout<< "Writing cuts for time " <<  runTime.timeName()
00154                 << " to " << cutsFile << endl;
00155 
00156             OFstream cutsStream(cutsFile);
00157             cuts.writeOBJ(cutsStream);
00158         }
00159 
00160 
00161         // Insert mesh refinement into polyTopoChange.
00162         meshRefiner_.setRefinement(cuts, meshMod);
00163 
00164 
00165         //
00166         // Do all changes
00167         //
00168 
00169         autoPtr<mapPolyMesh> morphMap = meshMod.changeMesh
00170         (
00171             mesh_,
00172             false
00173         );
00174 
00175         // Move mesh (since morphing does not do this)
00176         if (morphMap().hasMotionPoints())
00177         {
00178             mesh_.movePoints(morphMap().preMotionPoints());
00179         }
00180 
00181         // Update stored refinement pattern
00182         meshRefiner_.updateMesh(morphMap());
00183 
00184         // Write resulting mesh
00185         if (writeMesh_)
00186         {
00187             if (debug)
00188             {
00189                 Pout<< "Writing refined polyMesh to time "
00190                     << runTime.timeName() << endl;
00191             }
00192 
00193             mesh_.write();
00194         }
00195 
00196         // Update currentRefCells for new cell numbers. Use helper function
00197         // in meshCutter class.
00198         updateLabels
00199         (
00200             morphMap->reverseCellMap(),
00201             currentRefCells
00202         );
00203 
00204         // Update addedCells for new cell numbers
00205         updateLabels
00206         (
00207             morphMap->reverseCellMap(),
00208             addedCells
00209         );
00210 
00211         // Get all added cells from cellCutter (already in new numbering
00212         // from meshRefiner.updateMesh call) and add to global list of added
00213         const Map<label>& addedNow = meshRefiner_.addedCells();
00214 
00215         for
00216         (
00217             Map<label>::const_iterator iter = addedNow.begin();
00218             iter != addedNow.end();
00219             ++iter
00220         )
00221         {
00222             if (!addedCells.insert(iter.key(), iter()))
00223             {
00224                 FatalErrorIn("refinementIterator")
00225                     << "Master cell " << iter.key()
00226                     << " already has been refined" << endl
00227                     << "Added cell:" << iter() << abort(FatalError);
00228             }
00229         }
00230 
00231 
00232         // Get failed refinement in new cell numbering and reconstruct input
00233         // to the meshRefiner. Is done by removing all refined cells from
00234         // current list of cells to refine.
00235 
00236         // Update refCells for new cell numbers.
00237         updateLabels
00238         (
00239             morphMap->reverseCellMap(),
00240             currentRefCells
00241         );
00242 
00243         // Pack refCells acc. to refined status
00244         nRefCells = 0;
00245 
00246         forAll(currentRefCells, refI)
00247         {
00248             const refineCell& refCell = currentRefCells[refI];
00249 
00250             if (!addedNow.found(refCell.cellNo()))
00251             {
00252                 if (nRefCells != refI)
00253                 {
00254                     currentRefCells[nRefCells++] =
00255                         refineCell
00256                         (
00257                             refCell.cellNo(),
00258                             refCell.direction()
00259                         );
00260                 }
00261             }
00262         }
00263 
00264         oldRefCells = currentRefCells.size();
00265 
00266         currentRefCells.setSize(nRefCells);
00267 
00268         if (debug)
00269         {
00270             Pout<< endl;
00271         }
00272 
00273         // Stop only if all finished or all can't refine any further.
00274         stop = (nRefCells == 0) || (nRefCells == oldRefCells);
00275         reduce(stop, andOp<bool>());
00276     }
00277     while (!stop);
00278 
00279 
00280     if (nRefCells == oldRefCells)
00281     {
00282         WarningIn("refinementIterator")
00283             << "stopped refining."
00284             << "Did not manage to refine a single cell" << endl
00285             << "Wanted :" << oldRefCells << endl;
00286     }
00287 
00288     return addedCells;
00289 }
00290 
00291 
00292 
00293 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines