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

polyTopoChanger.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 "polyTopoChanger.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <dynamicMesh/polyTopoChange.H>
00029 #include <OpenFOAM/Time.H>
00030 
00031 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00032 
00033 namespace Foam
00034 {
00035     defineTypeNameAndDebug(polyTopoChanger, 0);
00036 }
00037 
00038 
00039 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00040 
00041 void Foam::polyTopoChanger::readModifiers()
00042 {
00043     if
00044     (
00045         readOpt() == IOobject::MUST_READ
00046      || (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
00047     )
00048     {
00049         PtrList<polyMeshModifier>& modifiers = *this;
00050 
00051         // Read modifiers
00052         Istream& is = readStream(typeName);
00053 
00054         PtrList<entry> patchEntries(is);
00055         modifiers.setSize(patchEntries.size());
00056 
00057         forAll(modifiers, modifierI)
00058         {
00059             modifiers.set
00060             (
00061                 modifierI,
00062                 polyMeshModifier::New
00063                 (
00064                     patchEntries[modifierI].keyword(),
00065                     patchEntries[modifierI].dict(),
00066                     modifierI,
00067                     *this
00068                 )
00069             );
00070         }
00071 
00072         // Check state of IOstream
00073         is.check
00074         (
00075             "polyTopoChanger::polyTopoChanger"
00076             "(const IOobject&, const polyMesh&)"
00077         );
00078 
00079         close();
00080     }
00081 }
00082 
00083 
00084 // Read constructor given IOobject and a polyMesh reference
00085 Foam::polyTopoChanger::polyTopoChanger
00086 (
00087     const IOobject& io,
00088     polyMesh& mesh
00089 )
00090 :
00091     PtrList<polyMeshModifier>(),
00092     regIOobject(io),
00093     mesh_(mesh)
00094 {
00095     readModifiers();
00096 }
00097 
00098 
00099 // Read constructor given IOobject and a polyMesh reference
00100 Foam::polyTopoChanger::polyTopoChanger(polyMesh& mesh)
00101 :
00102     PtrList<polyMeshModifier>(),
00103     regIOobject
00104     (
00105         IOobject
00106         (
00107             "meshModifiers",
00108             mesh.time().findInstance
00109             (
00110                 mesh.meshDir(),
00111                 "meshModifiers",
00112                 IOobject::READ_IF_PRESENT
00113             ),
00114             mesh.meshSubDir,
00115             mesh,
00116             IOobject::READ_IF_PRESENT,
00117             IOobject::NO_WRITE
00118         )
00119     ),
00120     mesh_(mesh)
00121 {
00122     readModifiers();
00123 }
00124 
00125 
00126 // Return a list of modifier types
00127 Foam::wordList Foam::polyTopoChanger::types() const
00128 {
00129     const PtrList<polyMeshModifier>& modifiers = *this;
00130 
00131     wordList t(modifiers.size());
00132 
00133     forAll (modifiers, modifierI)
00134     {
00135         t[modifierI] = modifiers[modifierI].type();
00136     }
00137 
00138     return t;
00139 }
00140 
00141 
00142 // Return a list of modifier names
00143 Foam::wordList Foam::polyTopoChanger::names() const
00144 {
00145     const PtrList<polyMeshModifier>& modifiers = *this;
00146 
00147     wordList t(modifiers.size());
00148 
00149     forAll (modifiers, modifierI)
00150     {
00151         t[modifierI] = modifiers[modifierI].name();
00152     }
00153 
00154     return t;
00155 }
00156 
00157 
00158 // Is topology change required
00159 bool Foam::polyTopoChanger::changeTopology() const
00160 {
00161     // Go through all mesh modifiers and accumulate the morphing information
00162     const PtrList<polyMeshModifier>& topoChanges = *this;
00163 
00164     bool triggerChange = false;
00165 
00166     forAll (topoChanges, morphI)
00167     {
00168         if (topoChanges[morphI].active())
00169         {
00170             bool curTriggerChange = topoChanges[morphI].changeTopology();
00171 
00172             if (debug)
00173             {
00174                 Info<< "Modifier " << morphI << " named "
00175                     << topoChanges[morphI].name();
00176                 
00177                 if (curTriggerChange)
00178                 {
00179                     Info << " morphing" << endl;
00180                 }
00181                 else
00182                 {
00183                     Info << " unchanged" << endl;
00184                 }
00185             }
00186 
00187             triggerChange = triggerChange || curTriggerChange;
00188         }
00189         else
00190         {
00191             if (debug)
00192             {
00193                 Info<< "Modifier " << morphI  << " named "
00194                     << topoChanges[morphI].name() << " inactive" << endl;
00195             }
00196         }
00197             
00198     }
00199 
00200     return triggerChange;
00201 }
00202 
00203 
00204 // Return topology change request
00205 Foam::autoPtr<Foam::polyTopoChange>
00206 Foam::polyTopoChanger::topoChangeRequest() const
00207 {
00208     // Collect changes from all modifiers
00209     const PtrList<polyMeshModifier>& topoChanges = *this;
00210 
00211     polyTopoChange* refPtr(new polyTopoChange(mesh()));
00212     polyTopoChange& ref = *refPtr;
00213 
00214     forAll (topoChanges, morphI)
00215     {
00216         if (topoChanges[morphI].active())
00217         {
00218             topoChanges[morphI].setRefinement(ref);
00219         }
00220     }
00221 
00222     return autoPtr<polyTopoChange>(refPtr);
00223 }
00224 
00225 
00226 // Correct polyTopoChanger after moving points
00227 void Foam::polyTopoChanger::modifyMotionPoints(pointField& p) const
00228 {
00229     const PtrList<polyMeshModifier>& topoChanges = *this;
00230 
00231     forAll (topoChanges, morphI)
00232     {
00233         if (topoChanges[morphI].active())
00234         {
00235             topoChanges[morphI].modifyMotionPoints(p);
00236         }
00237     }
00238 }
00239 
00240 
00241 // Force recalculation of locally stored data on topological change
00242 void Foam::polyTopoChanger::update(const mapPolyMesh& m)
00243 {
00244     // Go through all mesh modifiers and accumulate the morphing information
00245     PtrList<polyMeshModifier>& topoChanges = *this;
00246 
00247     forAll (topoChanges, morphI)
00248     {
00249         topoChanges[morphI].updateMesh(m);
00250     }
00251 
00252     // Force the mesh modifiers to auto-write.  This allows us to
00253     // preserve the current state of modifiers corresponding with
00254     // the mesh.  
00255     writeOpt() = IOobject::AUTO_WRITE;
00256     instance() = mesh_.time().timeName();
00257 }
00258 
00259 
00260 Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChanger::changeMesh
00261 (
00262     const bool inflate,
00263     const bool syncParallel,
00264     const bool orderCells,
00265     const bool orderPoints
00266 )
00267 {
00268     if (changeTopology())
00269     {
00270         autoPtr<polyTopoChange> ref = topoChangeRequest();
00271 
00272         autoPtr<mapPolyMesh> topoChangeMap = ref().changeMesh
00273         (
00274             mesh_,
00275             inflate,
00276             syncParallel,
00277             orderCells,
00278             orderPoints
00279         );
00280 
00281         update(topoChangeMap());
00282         mesh_.updateMesh(topoChangeMap());
00283         return topoChangeMap;
00284     }
00285     else
00286     {
00287         return autoPtr<mapPolyMesh>(NULL);
00288     }
00289 }
00290 
00291 
00292 // Add mesh modifiers to the morph engine
00293 void Foam::polyTopoChanger::addTopologyModifiers
00294 (
00295     const List<polyMeshModifier*>& tm
00296 )
00297 {
00298     setSize(tm.size());
00299 
00300     // Copy the patch pointers
00301     forAll (tm, tmI)
00302     {
00303         if (tm[tmI]->topoChanger() != *this)
00304         {
00305             FatalErrorIn
00306             (
00307                 "void polyTopoChanger::addTopologyModifiers("
00308                 "const List<polyMeshModifier*>& tm)"
00309             )   << "Mesh modifier created with different mesh reference."
00310                 << abort(FatalError);
00311         }
00312         set(tmI, tm[tmI]);
00313     }
00314 
00315     writeOpt() = IOobject::AUTO_WRITE;
00316 }
00317 
00318 
00319 Foam::label Foam::polyTopoChanger::findModifierID
00320 (
00321     const word& modName
00322 ) const
00323 {
00324     const PtrList<polyMeshModifier>& topoChanges = *this;
00325 
00326     forAll (topoChanges, morphI)
00327     {
00328         if (topoChanges[morphI].name() == modName)
00329         {
00330             return morphI;
00331         }
00332     }
00333 
00334     // Modifier not found
00335     if (debug)
00336     {
00337         Info<< "label polyTopoChanger::::findModifierID(const word& "
00338             << "modName) const"
00339             << "Modifier named " << modName << " not found.  "
00340             << "List of available modifier names: " << names() << endl;
00341     }
00342 
00343     // Not found, return -1
00344     return -1;
00345 }
00346 
00347 
00348 // writeData member function required by regIOobject
00349 bool Foam::polyTopoChanger::writeData(Ostream& os) const
00350 {
00351     os << *this;
00352     return os.good();
00353 }
00354 
00355 
00356 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00357 
00358 bool Foam::polyTopoChanger::operator!=(const polyTopoChanger& me) const
00359 {
00360     return &me != this;
00361 }
00362 
00363 
00364 bool Foam::polyTopoChanger::operator==(const polyTopoChanger& me) const
00365 {
00366     return &me == this;
00367 }
00368 
00369 
00370 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
00371 
00372 Foam::Ostream& Foam::operator<<(Ostream& os, const polyTopoChanger& mme)
00373 {
00374     os  << mme.size() << nl << token::BEGIN_LIST;
00375 
00376     forAll(mme, mmeI)
00377     {
00378         mme[mmeI].writeDict(os);
00379     }
00380 
00381     os  << token::END_LIST;
00382 
00383     return os;
00384 }
00385 
00386 
00387 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines