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

attachDetach.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 Description
00025     Attach/detach boundary mesh modifier.  This modifier takes a set of
00026     internal faces and converts them into boundary faces and vice versa
00027     based on the given activation switch.
00028 
00029 \*---------------------------------------------------------------------------*/
00030 
00031 #include "attachDetach.H"
00032 #include <dynamicMesh/polyTopoChanger.H>
00033 #include <OpenFOAM/polyMesh.H>
00034 #include <OpenFOAM/Time.H>
00035 #include <OpenFOAM/primitiveMesh.H>
00036 #include <dynamicMesh/polyTopoChange.H>
00037 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00038 
00039 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00040 
00041 namespace Foam
00042 {
00043     defineTypeNameAndDebug(attachDetach, 0);
00044     addToRunTimeSelectionTable
00045     (
00046         polyMeshModifier,
00047         attachDetach,
00048         dictionary
00049     );
00050 }
00051 
00052 
00053 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00054 
00055 void Foam::attachDetach::checkDefinition()
00056 {
00057     if
00058     (
00059         !faceZoneID_.active()
00060      || !masterPatchID_.active()
00061      || !slavePatchID_.active()
00062     )
00063     {
00064         FatalErrorIn
00065         (
00066             "void Foam::attachDetach::checkDefinition()"
00067         )   << "Not all zones and patches needed in the definition "
00068             << "have been found.  Please check your mesh definition."
00069             << abort(FatalError);
00070     }
00071 
00072     const polyMesh& mesh = topoChanger().mesh();
00073 
00074     if (debug)
00075     {
00076         Pout<< "Attach/detach object " << name() << " :" << nl
00077             << "    faceZoneID:   " << faceZoneID_ << nl
00078             << "    masterPatchID: " << masterPatchID_ << nl
00079             << "    slavePatchID: " << slavePatchID_ << endl;
00080     }
00081 
00082     // Check the sizes and set up state
00083     if
00084     (
00085         mesh.boundaryMesh()[masterPatchID_.index()].empty()
00086      && mesh.boundaryMesh()[slavePatchID_.index()].empty()
00087     )
00088     {
00089         // Boundary is attached
00090         if (debug)
00091         {
00092             Pout<< "    Attached on construction" << endl;
00093         }
00094 
00095         state_ = ATTACHED;
00096 
00097         // Check if there are faces in the master zone
00098         if (mesh.faceZones()[faceZoneID_.index()].empty())
00099         {
00100             FatalErrorIn
00101             (
00102                 "void Foam::attachDetach::checkDefinition()"
00103             )   << "Attach/detach zone contains no faces.  Please check your "
00104                 << "mesh definition."
00105                 << abort(FatalError);
00106         }
00107 
00108         // Check that all the faces in the face zone are internal
00109         if (debug)
00110         {
00111             const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
00112 
00113             DynamicList<label> bouFacesInZone(addr.size());
00114 
00115             forAll (addr, faceI)
00116             {
00117                 if (!mesh.isInternalFace(addr[faceI]))
00118                 {
00119                     bouFacesInZone.append(addr[faceI]);
00120                 }
00121             }
00122 
00123             if (bouFacesInZone.size())
00124             {
00125                 FatalErrorIn
00126                 (
00127                     "void Foam::attachDetach::checkDefinition()"
00128                 )   << "Found boundary faces in the zone defining "
00129                     << "attach/detach boundary "
00130                     << " for object " << name()
00131                     << " : .  This is not allowed." << nl
00132                     << "Boundary faces: " << bouFacesInZone
00133                     << abort(FatalError);
00134             }
00135         }
00136     }
00137     else
00138     {
00139         // Boundary is detached
00140         if (debug)
00141         {
00142             Pout<< "    Detached on construction" << endl;
00143         }
00144 
00145         state_ = DETACHED;
00146 
00147         // Check that the sizes of master and slave patch are identical
00148         // and identical to the size of the face zone
00149         if
00150         (
00151             (
00152                 mesh.boundaryMesh()[masterPatchID_.index()].size()
00153              != mesh.boundaryMesh()[slavePatchID_.index()].size()
00154             )
00155          || (
00156                 mesh.boundaryMesh()[masterPatchID_.index()].size()
00157              != mesh.faceZones()[faceZoneID_.index()].size()
00158             )
00159         )
00160         {
00161             FatalErrorIn
00162             (
00163                 "void Foam::attachDetach::checkDefinition()"
00164             )   << "Problem with sizes in mesh modifier. The face zone,"
00165                 << " master and slave patch should have the same size"
00166                 << " for object " << name() << ". " << nl
00167                 << "Zone size: "
00168                 << mesh.faceZones()[faceZoneID_.index()].size()
00169                 << " Master patch size: "
00170                 << mesh.boundaryMesh()[masterPatchID_.index()].size()
00171                 << " Slave patch size: "
00172                 << mesh.boundaryMesh()[slavePatchID_.index()].size()
00173                 << abort(FatalError);
00174         }
00175 
00176         // Check that all the faces belong to either master or slave patch
00177         if (debug)
00178         {
00179             const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
00180 
00181             DynamicList<label> zoneProblemFaces(addr.size());
00182 
00183             forAll (addr, faceI)
00184             {
00185                 label facePatch =
00186                     mesh.boundaryMesh().whichPatch(addr[faceI]);
00187 
00188                 if
00189                 (
00190                     facePatch != masterPatchID_.index()
00191                  && facePatch != slavePatchID_.index()
00192                 )
00193                 {
00194                     zoneProblemFaces.append(addr[faceI]);
00195                 }
00196             }
00197 
00198             if (zoneProblemFaces.size())
00199             {
00200                 FatalErrorIn
00201                 (
00202                     "void Foam::attachDetach::checkDefinition()"
00203                 )   << "Found faces in the zone defining "
00204                     << "attach/detach boundary which do not belong to "
00205                     << "either master or slave patch.  "
00206                     << "This is not allowed." << nl
00207                     << "Problem faces: " << zoneProblemFaces
00208                     << abort(FatalError);
00209             }
00210         }
00211     }
00212 
00213     // Check that trigger times are in ascending order
00214     bool triggersOK = true;
00215 
00216     for (label i = 0; i < triggerTimes_.size() - 1; i++)
00217     {
00218         triggersOK = triggersOK && (triggerTimes_[i] < triggerTimes_[i + 1]);
00219     }
00220 
00221     if
00222     (
00223         !triggersOK
00224      || (triggerTimes_.empty() && !manualTrigger())
00225     )
00226     {
00227         FatalErrorIn
00228         (
00229             "void Foam::attachDetach::checkDefinition()"
00230         )   << "Problem with definition of trigger times: "
00231             << triggerTimes_
00232             << abort(FatalError);
00233     }
00234 }
00235 
00236 
00237 void Foam::attachDetach::clearAddressing() const
00238 {
00239     deleteDemandDrivenData(pointMatchMapPtr_);
00240 }
00241 
00242 
00243 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00244 
00245 // Construct from components
00246 Foam::attachDetach::attachDetach
00247 (
00248     const word& name,
00249     const label index,
00250     const polyTopoChanger& mme,
00251     const word& faceZoneName,
00252     const word& masterPatchName,
00253     const word& slavePatchName,
00254     const scalarField& triggerTimes,
00255     const bool manualTrigger
00256 )
00257 :
00258     polyMeshModifier(name, index, mme, true),
00259     faceZoneID_(faceZoneName, mme.mesh().faceZones()),
00260     masterPatchID_(masterPatchName, mme.mesh().boundaryMesh()),
00261     slavePatchID_(slavePatchName, mme.mesh().boundaryMesh()),
00262     triggerTimes_(triggerTimes),
00263     manualTrigger_(manualTrigger),
00264     triggerIndex_(0),
00265     state_(UNKNOWN),
00266     trigger_(false),
00267     pointMatchMapPtr_(NULL)
00268 {
00269     checkDefinition();
00270 }
00271 
00272 
00273 // Construct from components
00274 Foam::attachDetach::attachDetach
00275 (
00276     const word& name,
00277     const dictionary& dict,
00278     const label index,
00279     const polyTopoChanger& mme
00280 )
00281 :
00282     polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
00283     faceZoneID_
00284     (
00285         dict.lookup("faceZoneName"),
00286         mme.mesh().faceZones()
00287     ),
00288     masterPatchID_
00289     (
00290         dict.lookup("masterPatchName"),
00291         mme.mesh().boundaryMesh()
00292     ),
00293     slavePatchID_
00294     (
00295         dict.lookup("slavePatchName"),
00296         mme.mesh().boundaryMesh()
00297     ),
00298     triggerTimes_(dict.lookup("triggerTimes")),
00299     manualTrigger_(dict.lookup("manualTrigger")),
00300     triggerIndex_(0),
00301     state_(UNKNOWN),
00302     trigger_(false),
00303     pointMatchMapPtr_(NULL)
00304 {
00305     checkDefinition();
00306 }
00307 
00308 
00309 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00310 
00311 Foam::attachDetach::~attachDetach()
00312 {
00313     clearAddressing();
00314 }
00315 
00316 
00317 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00318 
00319 bool Foam::attachDetach::setAttach() const
00320 {
00321     if (!attached())
00322     {
00323         trigger_ = true;
00324     }
00325     else
00326     {
00327         trigger_ = false;
00328     }
00329 
00330     return trigger_;
00331 }
00332 
00333 
00334 bool Foam::attachDetach::setDetach() const
00335 {
00336     if (attached())
00337     {
00338         trigger_ = true;
00339     }
00340     else
00341     {
00342         trigger_ = false;
00343     }
00344 
00345     return trigger_;
00346 }
00347 
00348 
00349 bool Foam::attachDetach::changeTopology() const
00350 {
00351     if (manualTrigger())
00352     {
00353         if (debug)
00354         {
00355             Pout<< "bool attachDetach::changeTopology() const "
00356                 << " for object " << name() << " : "
00357                 << "Manual trigger" << endl;
00358         }
00359 
00360         return trigger_;
00361     }
00362 
00363     // To deal with multiple calls within the same time step, return true
00364     // if trigger is already set
00365     if (trigger_)
00366     {
00367         if (debug)
00368         {
00369             Pout<< "bool attachDetach::changeTopology() const "
00370                 << " for object " << name() << " : "
00371                 << "Already triggered for current time step" << endl;
00372         }
00373 
00374         return true;
00375     }
00376 
00377     // If the end of the list of trigger times has been reached, no
00378     // new topological changes will happen
00379     if (triggerIndex_ >= triggerTimes_.size())
00380     {
00381         if (debug)
00382         {
00383             Pout<< "bool attachDetach::changeTopology() const "
00384                 << " for object " << name() << " : "
00385                 << "Reached end of trigger list" << endl;
00386         }
00387         return false;
00388     }
00389 
00390     if (debug)
00391     {
00392         Pout<< "bool attachDetach::changeTopology() const "
00393             << " for object " << name() << " : "
00394             << "Triggering attach/detach topology change." << nl
00395             << "Current time: " << topoChanger().mesh().time().value()
00396             << " current trigger time: " << triggerTimes_[triggerIndex_]
00397             << " trigger index: " << triggerIndex_ << endl;
00398     }
00399 
00400     // Check if the time is greater than the currentTime.  If so, increment
00401     // the current lookup and request topology change
00402     if (topoChanger().mesh().time().value() >= triggerTimes_[triggerIndex_])
00403     {
00404         trigger_ = true;
00405 
00406         // Increment the trigger index
00407         triggerIndex_++;
00408 
00409         return true;
00410     }
00411 
00412     // No topological change
00413     return false;
00414 }
00415 
00416 
00417 void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
00418 {
00419     // Insert the attach/detach instructions into the topological change
00420 
00421     if (trigger_)
00422     {
00423         // Clear point addressing from previous attach/detach event
00424         clearAddressing();
00425 
00426         if (state_ == ATTACHED)
00427         {
00428             detachInterface(ref);
00429 
00430             // Set the state to detached
00431             state_ = DETACHED;
00432         }
00433         else if (state_ == DETACHED)
00434         {
00435             attachInterface(ref);
00436 
00437             // Set the state to attached
00438             state_ = ATTACHED;
00439         }
00440         else
00441         {
00442             FatalErrorIn
00443             (
00444                 "void attachDetach::setRefinement(polyTopoChange&) const"
00445             )   << "Requested attach/detach event and currect state "
00446                 << "is not known."
00447                 << abort(FatalError);
00448         }
00449 
00450         trigger_ = false;
00451     }
00452 }
00453 
00454 
00455 void Foam::attachDetach::updateMesh(const mapPolyMesh&)
00456 {
00457     // Mesh has changed topologically.  Update local topological data
00458     const polyMesh& mesh = topoChanger().mesh();
00459 
00460     faceZoneID_.update(mesh.faceZones());
00461     masterPatchID_.update(mesh.boundaryMesh());
00462     slavePatchID_.update(mesh.boundaryMesh());
00463 
00464     clearAddressing();
00465 }
00466 
00467 
00468 void Foam::attachDetach::write(Ostream& os) const
00469 {
00470     os  << nl << type() << nl
00471         << name()<< nl
00472         << faceZoneID_.name() << nl
00473         << masterPatchID_.name() << nl
00474         << slavePatchID_.name() << nl
00475         << triggerTimes_ << endl;
00476 }
00477 
00478 
00479 void Foam::attachDetach::writeDict(Ostream& os) const
00480 {
00481     os  << nl << name() << nl << token::BEGIN_BLOCK << nl
00482         << "    type " << type()
00483         << token::END_STATEMENT << nl
00484         << "    faceZoneName " << faceZoneID_.name()
00485         << token::END_STATEMENT << nl
00486         << "    masterPatchName " << masterPatchID_.name()
00487         << token::END_STATEMENT << nl
00488         << "    slavePatchName " << slavePatchID_.name()
00489         << token::END_STATEMENT << nl
00490         << "    triggerTimes " << triggerTimes_
00491         << token::END_STATEMENT << nl
00492         << "    manualTrigger " << manualTrigger()
00493         << token::END_STATEMENT << nl
00494         << "    active " << active()
00495         << token::END_STATEMENT << nl
00496         << token::END_BLOCK << endl;
00497 }
00498 
00499 
00500 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines