initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / dynamicMesh / attachDetach / attachDetach.C
blob43305938cb8355009a8f8f3f9df35dedacda6d94
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 Description
26     Attach/detach boundary mesh modifier.  This modifier takes a set of
27     internal faces and converts them into boundary faces and vice versa
28     based on the given activation switch.
30 \*---------------------------------------------------------------------------*/
32 #include "attachDetach.H"
33 #include "polyTopoChanger.H"
34 #include "polyMesh.H"
35 #include "Time.H"
36 #include "primitiveMesh.H"
37 #include "polyTopoChange.H"
38 #include "addToRunTimeSelectionTable.H"
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 namespace Foam
44     defineTypeNameAndDebug(attachDetach, 0);
45     addToRunTimeSelectionTable
46     (
47         polyMeshModifier,
48         attachDetach,
49         dictionary
50     );
54 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
56 void Foam::attachDetach::checkDefinition()
58     if
59     (
60         !faceZoneID_.active()
61      || !masterPatchID_.active()
62      || !slavePatchID_.active()
63     )
64     {
65         FatalErrorIn
66         (
67             "void Foam::attachDetach::checkDefinition()"
68         )   << "Not all zones and patches needed in the definition "
69             << "have been found.  Please check your mesh definition."
70             << abort(FatalError);
71     }
73     const polyMesh& mesh = topoChanger().mesh();
75     if (debug)
76     {
77         Pout<< "Attach/detach object " << name() << " :" << nl
78             << "    faceZoneID:   " << faceZoneID_ << nl
79             << "    masterPatchID: " << masterPatchID_ << nl
80             << "    slavePatchID: " << slavePatchID_ << endl;
81     }
83     // Check the sizes and set up state
84     if
85     (
86         mesh.boundaryMesh()[masterPatchID_.index()].empty()
87      && mesh.boundaryMesh()[slavePatchID_.index()].empty()
88     )
89     {
90         // Boundary is attached
91         if (debug)
92         {
93             Pout<< "    Attached on construction" << endl;
94         }
96         state_ = ATTACHED;
98         // Check if there are faces in the master zone
99         if (mesh.faceZones()[faceZoneID_.index()].empty())
100         {
101             FatalErrorIn
102             (
103                 "void Foam::attachDetach::checkDefinition()"
104             )   << "Attach/detach zone contains no faces.  Please check your "
105                 << "mesh definition."
106                 << abort(FatalError);
107         }
109         // Check that all the faces in the face zone are internal
110         if (debug)
111         {
112             const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
114             DynamicList<label> bouFacesInZone(addr.size());
116             forAll (addr, faceI)
117             {
118                 if (!mesh.isInternalFace(addr[faceI]))
119                 {
120                     bouFacesInZone.append(addr[faceI]);
121                 }
122             }
124             if (bouFacesInZone.size())
125             {
126                 FatalErrorIn
127                 (
128                     "void Foam::attachDetach::checkDefinition()"
129                 )   << "Found boundary faces in the zone defining "
130                     << "attach/detach boundary "
131                     << " for object " << name()
132                     << " : .  This is not allowed." << nl
133                     << "Boundary faces: " << bouFacesInZone
134                     << abort(FatalError);
135             }
136         }
137     }
138     else
139     {
140         // Boundary is detached
141         if (debug)
142         {
143             Pout<< "    Detached on construction" << endl;
144         }
146         state_ = DETACHED;
148         // Check that the sizes of master and slave patch are identical
149         // and identical to the size of the face zone
150         if
151         (
152             (
153                 mesh.boundaryMesh()[masterPatchID_.index()].size()
154              != mesh.boundaryMesh()[slavePatchID_.index()].size()
155             )
156          || (
157                 mesh.boundaryMesh()[masterPatchID_.index()].size()
158              != mesh.faceZones()[faceZoneID_.index()].size()
159             )
160         )
161         {
162             FatalErrorIn
163             (
164                 "void Foam::attachDetach::checkDefinition()"
165             )   << "Problem with sizes in mesh modifier. The face zone,"
166                 << " master and slave patch should have the same size"
167                 << " for object " << name() << ". " << nl
168                 << "Zone size: "
169                 << mesh.faceZones()[faceZoneID_.index()].size()
170                 << " Master patch size: "
171                 << mesh.boundaryMesh()[masterPatchID_.index()].size()
172                 << " Slave patch size: "
173                 << mesh.boundaryMesh()[slavePatchID_.index()].size()
174                 << abort(FatalError);
175         }
177         // Check that all the faces belong to either master or slave patch
178         if (debug)
179         {
180             const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
182             DynamicList<label> zoneProblemFaces(addr.size());
184             forAll (addr, faceI)
185             {
186                 label facePatch =
187                     mesh.boundaryMesh().whichPatch(addr[faceI]);
189                 if
190                 (
191                     facePatch != masterPatchID_.index()
192                  && facePatch != slavePatchID_.index()
193                 )
194                 {
195                     zoneProblemFaces.append(addr[faceI]);
196                 }
197             }
199             if (zoneProblemFaces.size())
200             {
201                 FatalErrorIn
202                 (
203                     "void Foam::attachDetach::checkDefinition()"
204                 )   << "Found faces in the zone defining "
205                     << "attach/detach boundary which do not belong to "
206                     << "either master or slave patch.  "
207                     << "This is not allowed." << nl
208                     << "Problem faces: " << zoneProblemFaces
209                     << abort(FatalError);
210             }
211         }
212     }
214     // Check that trigger times are in ascending order
215     bool triggersOK = true;
217     for (label i = 0; i < triggerTimes_.size() - 1; i++)
218     {
219         triggersOK = triggersOK && (triggerTimes_[i] < triggerTimes_[i + 1]);
220     }
222     if
223     (
224         !triggersOK
225      || (triggerTimes_.empty() && !manualTrigger())
226     )
227     {
228         FatalErrorIn
229         (
230             "void Foam::attachDetach::checkDefinition()"
231         )   << "Problem with definition of trigger times: "
232             << triggerTimes_
233             << abort(FatalError);
234     }
238 void Foam::attachDetach::clearAddressing() const
240     deleteDemandDrivenData(pointMatchMapPtr_);
244 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
246 // Construct from components
247 Foam::attachDetach::attachDetach
249     const word& name,
250     const label index,
251     const polyTopoChanger& mme,
252     const word& faceZoneName,
253     const word& masterPatchName,
254     const word& slavePatchName,
255     const scalarField& triggerTimes,
256     const bool manualTrigger
259     polyMeshModifier(name, index, mme, true),
260     faceZoneID_(faceZoneName, mme.mesh().faceZones()),
261     masterPatchID_(masterPatchName, mme.mesh().boundaryMesh()),
262     slavePatchID_(slavePatchName, mme.mesh().boundaryMesh()),
263     triggerTimes_(triggerTimes),
264     manualTrigger_(manualTrigger),
265     triggerIndex_(0),
266     state_(UNKNOWN),
267     trigger_(false),
268     pointMatchMapPtr_(NULL)
270     checkDefinition();
274 // Construct from components
275 Foam::attachDetach::attachDetach
277     const word& name,
278     const dictionary& dict,
279     const label index,
280     const polyTopoChanger& mme
283     polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
284     faceZoneID_
285     (
286         dict.lookup("faceZoneName"),
287         mme.mesh().faceZones()
288     ),
289     masterPatchID_
290     (
291         dict.lookup("masterPatchName"),
292         mme.mesh().boundaryMesh()
293     ),
294     slavePatchID_
295     (
296         dict.lookup("slavePatchName"),
297         mme.mesh().boundaryMesh()
298     ),
299     triggerTimes_(dict.lookup("triggerTimes")),
300     manualTrigger_(dict.lookup("manualTrigger")),
301     triggerIndex_(0),
302     state_(UNKNOWN),
303     trigger_(false),
304     pointMatchMapPtr_(NULL)
306     checkDefinition();
310 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
312 Foam::attachDetach::~attachDetach()
314     clearAddressing();
318 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
320 bool Foam::attachDetach::setAttach() const
322     if (!attached())
323     {
324         trigger_ = true;
325     }
326     else
327     {
328         trigger_ = false;
329     }
331     return trigger_;
335 bool Foam::attachDetach::setDetach() const
337     if (attached())
338     {
339         trigger_ = true;
340     }
341     else
342     {
343         trigger_ = false;
344     }
346     return trigger_;
350 bool Foam::attachDetach::changeTopology() const
352     if (manualTrigger())
353     {
354         if (debug)
355         {
356             Pout<< "bool attachDetach::changeTopology() const "
357                 << " for object " << name() << " : "
358                 << "Manual trigger" << endl;
359         }
361         return trigger_;
362     }
364     // To deal with multiple calls within the same time step, return true
365     // if trigger is already set
366     if (trigger_)
367     {
368         if (debug)
369         {
370             Pout<< "bool attachDetach::changeTopology() const "
371                 << " for object " << name() << " : "
372                 << "Already triggered for current time step" << endl;
373         }
375         return true;
376     }
378     // If the end of the list of trigger times has been reached, no
379     // new topological changes will happen
380     if (triggerIndex_ >= triggerTimes_.size())
381     {
382         if (debug)
383         {
384             Pout<< "bool attachDetach::changeTopology() const "
385                 << " for object " << name() << " : "
386                 << "Reached end of trigger list" << endl;
387         }
388         return false;
389     }
391     if (debug)
392     {
393         Pout<< "bool attachDetach::changeTopology() const "
394             << " for object " << name() << " : "
395             << "Triggering attach/detach topology change." << nl
396             << "Current time: " << topoChanger().mesh().time().value()
397             << " current trigger time: " << triggerTimes_[triggerIndex_]
398             << " trigger index: " << triggerIndex_ << endl;
399     }
401     // Check if the time is greater than the currentTime.  If so, increment
402     // the current lookup and request topology change
403     if (topoChanger().mesh().time().value() >= triggerTimes_[triggerIndex_])
404     {
405         trigger_ = true;
407         // Increment the trigger index
408         triggerIndex_++;
410         return true;
411     }
413     // No topological change
414     return false;
418 void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
420     // Insert the attach/detach instructions into the topological change
422     if (trigger_)
423     {
424         // Clear point addressing from previous attach/detach event
425         clearAddressing();
427         if (state_ == ATTACHED)
428         {
429             detachInterface(ref);
431             // Set the state to detached
432             state_ = DETACHED;
433         }
434         else if (state_ == DETACHED)
435         {
436             attachInterface(ref);
438             // Set the state to attached
439             state_ = ATTACHED;
440         }
441         else
442         {
443             FatalErrorIn
444             (
445                 "void attachDetach::setRefinement(polyTopoChange&) const"
446             )   << "Requested attach/detach event and currect state "
447                 << "is not known."
448                 << abort(FatalError);
449         }
451         trigger_ = false;
452     }
456 void Foam::attachDetach::updateMesh(const mapPolyMesh&)
458     // Mesh has changed topologically.  Update local topological data
459     const polyMesh& mesh = topoChanger().mesh();
461     faceZoneID_.update(mesh.faceZones());
462     masterPatchID_.update(mesh.boundaryMesh());
463     slavePatchID_.update(mesh.boundaryMesh());
465     clearAddressing();
469 void Foam::attachDetach::write(Ostream& os) const
471     os  << nl << type() << nl
472         << name()<< nl
473         << faceZoneID_.name() << nl
474         << masterPatchID_.name() << nl
475         << slavePatchID_.name() << nl
476         << triggerTimes_ << endl;
480 void Foam::attachDetach::writeDict(Ostream& os) const
482     os  << nl << name() << nl << token::BEGIN_BLOCK << nl
483         << "    type " << type()
484         << token::END_STATEMENT << nl
485         << "    faceZoneName " << faceZoneID_.name()
486         << token::END_STATEMENT << nl
487         << "    masterPatchName " << masterPatchID_.name()
488         << token::END_STATEMENT << nl
489         << "    slavePatchName " << slavePatchID_.name()
490         << token::END_STATEMENT << nl
491         << "    triggerTimes " << triggerTimes_
492         << token::END_STATEMENT << nl
493         << "    manualTrigger " << manualTrigger()
494         << token::END_STATEMENT << nl
495         << "    active " << active()
496         << token::END_STATEMENT << nl
497         << token::END_BLOCK << endl;
501 // ************************************************************************* //