ENH: cylinderAnnulusToCell: new cellSource for cellSets
[OpenFOAM-1.7.x.git] / src / dynamicMesh / attachDetach / attachDetach.C
blob22d89376fb1a3f527ba913a71ecd87e9b39c8295
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 Description
25     Attach/detach boundary mesh modifier.  This modifier takes a set of
26     internal faces and converts them into boundary faces and vice versa
27     based on the given activation switch.
29 \*---------------------------------------------------------------------------*/
31 #include "attachDetach.H"
32 #include "polyTopoChanger.H"
33 #include "polyMesh.H"
34 #include "Time.H"
35 #include "primitiveMesh.H"
36 #include "polyTopoChange.H"
37 #include "addToRunTimeSelectionTable.H"
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 namespace Foam
43     defineTypeNameAndDebug(attachDetach, 0);
44     addToRunTimeSelectionTable
45     (
46         polyMeshModifier,
47         attachDetach,
48         dictionary
49     );
53 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
55 void Foam::attachDetach::checkDefinition()
57     if
58     (
59         !faceZoneID_.active()
60      || !masterPatchID_.active()
61      || !slavePatchID_.active()
62     )
63     {
64         FatalErrorIn
65         (
66             "void Foam::attachDetach::checkDefinition()"
67         )   << "Not all zones and patches needed in the definition "
68             << "have been found.  Please check your mesh definition."
69             << abort(FatalError);
70     }
72     const polyMesh& mesh = topoChanger().mesh();
74     if (debug)
75     {
76         Pout<< "Attach/detach object " << name() << " :" << nl
77             << "    faceZoneID:   " << faceZoneID_ << nl
78             << "    masterPatchID: " << masterPatchID_ << nl
79             << "    slavePatchID: " << slavePatchID_ << endl;
80     }
82     // Check the sizes and set up state
83     if
84     (
85         mesh.boundaryMesh()[masterPatchID_.index()].empty()
86      && mesh.boundaryMesh()[slavePatchID_.index()].empty()
87     )
88     {
89         // Boundary is attached
90         if (debug)
91         {
92             Pout<< "    Attached on construction" << endl;
93         }
95         state_ = ATTACHED;
97         // Check if there are faces in the master zone
98         if (mesh.faceZones()[faceZoneID_.index()].empty())
99         {
100             FatalErrorIn
101             (
102                 "void Foam::attachDetach::checkDefinition()"
103             )   << "Attach/detach zone contains no faces.  Please check your "
104                 << "mesh definition."
105                 << abort(FatalError);
106         }
108         // Check that all the faces in the face zone are internal
109         if (debug)
110         {
111             const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
113             DynamicList<label> bouFacesInZone(addr.size());
115             forAll (addr, faceI)
116             {
117                 if (!mesh.isInternalFace(addr[faceI]))
118                 {
119                     bouFacesInZone.append(addr[faceI]);
120                 }
121             }
123             if (bouFacesInZone.size())
124             {
125                 FatalErrorIn
126                 (
127                     "void Foam::attachDetach::checkDefinition()"
128                 )   << "Found boundary faces in the zone defining "
129                     << "attach/detach boundary "
130                     << " for object " << name()
131                     << " : .  This is not allowed." << nl
132                     << "Boundary faces: " << bouFacesInZone
133                     << abort(FatalError);
134             }
135         }
136     }
137     else
138     {
139         // Boundary is detached
140         if (debug)
141         {
142             Pout<< "    Detached on construction" << endl;
143         }
145         state_ = DETACHED;
147         // Check that the sizes of master and slave patch are identical
148         // and identical to the size of the face zone
149         if
150         (
151             (
152                 mesh.boundaryMesh()[masterPatchID_.index()].size()
153              != mesh.boundaryMesh()[slavePatchID_.index()].size()
154             )
155          || (
156                 mesh.boundaryMesh()[masterPatchID_.index()].size()
157              != mesh.faceZones()[faceZoneID_.index()].size()
158             )
159         )
160         {
161             FatalErrorIn
162             (
163                 "void Foam::attachDetach::checkDefinition()"
164             )   << "Problem with sizes in mesh modifier. The face zone,"
165                 << " master and slave patch should have the same size"
166                 << " for object " << name() << ". " << nl
167                 << "Zone size: "
168                 << mesh.faceZones()[faceZoneID_.index()].size()
169                 << " Master patch size: "
170                 << mesh.boundaryMesh()[masterPatchID_.index()].size()
171                 << " Slave patch size: "
172                 << mesh.boundaryMesh()[slavePatchID_.index()].size()
173                 << abort(FatalError);
174         }
176         // Check that all the faces belong to either master or slave patch
177         if (debug)
178         {
179             const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
181             DynamicList<label> zoneProblemFaces(addr.size());
183             forAll (addr, faceI)
184             {
185                 label facePatch =
186                     mesh.boundaryMesh().whichPatch(addr[faceI]);
188                 if
189                 (
190                     facePatch != masterPatchID_.index()
191                  && facePatch != slavePatchID_.index()
192                 )
193                 {
194                     zoneProblemFaces.append(addr[faceI]);
195                 }
196             }
198             if (zoneProblemFaces.size())
199             {
200                 FatalErrorIn
201                 (
202                     "void Foam::attachDetach::checkDefinition()"
203                 )   << "Found faces in the zone defining "
204                     << "attach/detach boundary which do not belong to "
205                     << "either master or slave patch.  "
206                     << "This is not allowed." << nl
207                     << "Problem faces: " << zoneProblemFaces
208                     << abort(FatalError);
209             }
210         }
211     }
213     // Check that trigger times are in ascending order
214     bool triggersOK = true;
216     for (label i = 0; i < triggerTimes_.size() - 1; i++)
217     {
218         triggersOK = triggersOK && (triggerTimes_[i] < triggerTimes_[i + 1]);
219     }
221     if
222     (
223         !triggersOK
224      || (triggerTimes_.empty() && !manualTrigger())
225     )
226     {
227         FatalErrorIn
228         (
229             "void Foam::attachDetach::checkDefinition()"
230         )   << "Problem with definition of trigger times: "
231             << triggerTimes_
232             << abort(FatalError);
233     }
237 void Foam::attachDetach::clearAddressing() const
239     deleteDemandDrivenData(pointMatchMapPtr_);
243 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
245 // Construct from components
246 Foam::attachDetach::attachDetach
248     const word& name,
249     const label index,
250     const polyTopoChanger& mme,
251     const word& faceZoneName,
252     const word& masterPatchName,
253     const word& slavePatchName,
254     const scalarField& triggerTimes,
255     const bool manualTrigger
258     polyMeshModifier(name, index, mme, true),
259     faceZoneID_(faceZoneName, mme.mesh().faceZones()),
260     masterPatchID_(masterPatchName, mme.mesh().boundaryMesh()),
261     slavePatchID_(slavePatchName, mme.mesh().boundaryMesh()),
262     triggerTimes_(triggerTimes),
263     manualTrigger_(manualTrigger),
264     triggerIndex_(0),
265     state_(UNKNOWN),
266     trigger_(false),
267     pointMatchMapPtr_(NULL)
269     checkDefinition();
273 // Construct from components
274 Foam::attachDetach::attachDetach
276     const word& name,
277     const dictionary& dict,
278     const label index,
279     const polyTopoChanger& mme
282     polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
283     faceZoneID_
284     (
285         dict.lookup("faceZoneName"),
286         mme.mesh().faceZones()
287     ),
288     masterPatchID_
289     (
290         dict.lookup("masterPatchName"),
291         mme.mesh().boundaryMesh()
292     ),
293     slavePatchID_
294     (
295         dict.lookup("slavePatchName"),
296         mme.mesh().boundaryMesh()
297     ),
298     triggerTimes_(dict.lookup("triggerTimes")),
299     manualTrigger_(dict.lookup("manualTrigger")),
300     triggerIndex_(0),
301     state_(UNKNOWN),
302     trigger_(false),
303     pointMatchMapPtr_(NULL)
305     checkDefinition();
309 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
311 Foam::attachDetach::~attachDetach()
313     clearAddressing();
317 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
319 bool Foam::attachDetach::setAttach() const
321     if (!attached())
322     {
323         trigger_ = true;
324     }
325     else
326     {
327         trigger_ = false;
328     }
330     return trigger_;
334 bool Foam::attachDetach::setDetach() const
336     if (attached())
337     {
338         trigger_ = true;
339     }
340     else
341     {
342         trigger_ = false;
343     }
345     return trigger_;
349 bool Foam::attachDetach::changeTopology() const
351     if (manualTrigger())
352     {
353         if (debug)
354         {
355             Pout<< "bool attachDetach::changeTopology() const "
356                 << " for object " << name() << " : "
357                 << "Manual trigger" << endl;
358         }
360         return trigger_;
361     }
363     // To deal with multiple calls within the same time step, return true
364     // if trigger is already set
365     if (trigger_)
366     {
367         if (debug)
368         {
369             Pout<< "bool attachDetach::changeTopology() const "
370                 << " for object " << name() << " : "
371                 << "Already triggered for current time step" << endl;
372         }
374         return true;
375     }
377     // If the end of the list of trigger times has been reached, no
378     // new topological changes will happen
379     if (triggerIndex_ >= triggerTimes_.size())
380     {
381         if (debug)
382         {
383             Pout<< "bool attachDetach::changeTopology() const "
384                 << " for object " << name() << " : "
385                 << "Reached end of trigger list" << endl;
386         }
387         return false;
388     }
390     if (debug)
391     {
392         Pout<< "bool attachDetach::changeTopology() const "
393             << " for object " << name() << " : "
394             << "Triggering attach/detach topology change." << nl
395             << "Current time: " << topoChanger().mesh().time().value()
396             << " current trigger time: " << triggerTimes_[triggerIndex_]
397             << " trigger index: " << triggerIndex_ << endl;
398     }
400     // Check if the time is greater than the currentTime.  If so, increment
401     // the current lookup and request topology change
402     if (topoChanger().mesh().time().value() >= triggerTimes_[triggerIndex_])
403     {
404         trigger_ = true;
406         // Increment the trigger index
407         triggerIndex_++;
409         return true;
410     }
412     // No topological change
413     return false;
417 void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
419     // Insert the attach/detach instructions into the topological change
421     if (trigger_)
422     {
423         // Clear point addressing from previous attach/detach event
424         clearAddressing();
426         if (state_ == ATTACHED)
427         {
428             detachInterface(ref);
430             // Set the state to detached
431             state_ = DETACHED;
432         }
433         else if (state_ == DETACHED)
434         {
435             attachInterface(ref);
437             // Set the state to attached
438             state_ = ATTACHED;
439         }
440         else
441         {
442             FatalErrorIn
443             (
444                 "void attachDetach::setRefinement(polyTopoChange&) const"
445             )   << "Requested attach/detach event and currect state "
446                 << "is not known."
447                 << abort(FatalError);
448         }
450         trigger_ = false;
451     }
455 void Foam::attachDetach::updateMesh(const mapPolyMesh&)
457     // Mesh has changed topologically.  Update local topological data
458     const polyMesh& mesh = topoChanger().mesh();
460     faceZoneID_.update(mesh.faceZones());
461     masterPatchID_.update(mesh.boundaryMesh());
462     slavePatchID_.update(mesh.boundaryMesh());
464     clearAddressing();
468 void Foam::attachDetach::write(Ostream& os) const
470     os  << nl << type() << nl
471         << name()<< nl
472         << faceZoneID_.name() << nl
473         << masterPatchID_.name() << nl
474         << slavePatchID_.name() << nl
475         << triggerTimes_ << endl;
479 void Foam::attachDetach::writeDict(Ostream& os) const
481     os  << nl << name() << nl << token::BEGIN_BLOCK << nl
482         << "    type " << type()
483         << token::END_STATEMENT << nl
484         << "    faceZoneName " << faceZoneID_.name()
485         << token::END_STATEMENT << nl
486         << "    masterPatchName " << masterPatchID_.name()
487         << token::END_STATEMENT << nl
488         << "    slavePatchName " << slavePatchID_.name()
489         << token::END_STATEMENT << nl
490         << "    triggerTimes " << triggerTimes_
491         << token::END_STATEMENT << nl
492         << "    manualTrigger " << manualTrigger()
493         << token::END_STATEMENT << nl
494         << "    active " << active()
495         << token::END_STATEMENT << nl
496         << token::END_BLOCK << endl;
500 // ************************************************************************* //