1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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
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"
36 #include "primitiveMesh.H"
37 #include "polyTopoChange.H"
38 #include "addToRunTimeSelectionTable.H"
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
44 defineTypeNameAndDebug(attachDetach, 0);
45 addToRunTimeSelectionTable
54 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
56 void Foam::attachDetach::checkDefinition()
61 || !masterPatchID_.active()
62 || !slavePatchID_.active()
67 "void Foam::attachDetach::checkDefinition()"
68 ) << "Not all zones and patches needed in the definition "
69 << "have been found. Please check your mesh definition."
73 const polyMesh& mesh = topoChanger().mesh();
77 Pout<< "Attach/detach object " << name() << " :" << nl
78 << " faceZoneID: " << faceZoneID_ << nl
79 << " masterPatchID: " << masterPatchID_ << nl
80 << " slavePatchID: " << slavePatchID_ << endl;
83 // Check the sizes and set up state
86 mesh.boundaryMesh()[masterPatchID_.index()].empty()
87 && mesh.boundaryMesh()[slavePatchID_.index()].empty()
90 // Boundary is attached
93 Pout<< " Attached on construction" << endl;
98 // Check if there are faces in the master zone
99 if (mesh.faceZones()[faceZoneID_.index()].empty())
103 "void Foam::attachDetach::checkDefinition()"
104 ) << "Attach/detach zone contains no faces. Please check your "
105 << "mesh definition."
106 << abort(FatalError);
109 // Check that all the faces in the face zone are internal
112 const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
114 DynamicList<label> bouFacesInZone(addr.size());
118 if (!mesh.isInternalFace(addr[faceI]))
120 bouFacesInZone.append(addr[faceI]);
124 if (bouFacesInZone.size())
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);
140 // Boundary is detached
143 Pout<< " Detached on construction" << endl;
148 // Check that the sizes of master and slave patch are identical
149 // and identical to the size of the face zone
153 mesh.boundaryMesh()[masterPatchID_.index()].size()
154 != mesh.boundaryMesh()[slavePatchID_.index()].size()
157 mesh.boundaryMesh()[masterPatchID_.index()].size()
158 != mesh.faceZones()[faceZoneID_.index()].size()
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
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);
177 // Check that all the faces belong to either master or slave patch
180 const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
182 DynamicList<label> zoneProblemFaces(addr.size());
187 mesh.boundaryMesh().whichPatch(addr[faceI]);
191 facePatch != masterPatchID_.index()
192 && facePatch != slavePatchID_.index()
195 zoneProblemFaces.append(addr[faceI]);
199 if (zoneProblemFaces.size())
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);
214 // Check that trigger times are in ascending order
215 bool triggersOK = true;
217 for (label i = 0; i < triggerTimes_.size() - 1; i++)
219 triggersOK = triggersOK && (triggerTimes_[i] < triggerTimes_[i + 1]);
225 || (triggerTimes_.empty() && !manualTrigger())
230 "void Foam::attachDetach::checkDefinition()"
231 ) << "Problem with definition of trigger times: "
233 << abort(FatalError);
238 void Foam::attachDetach::clearAddressing() const
240 deleteDemandDrivenData(pointMatchMapPtr_);
244 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
246 // Construct from components
247 Foam::attachDetach::attachDetach
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),
268 pointMatchMapPtr_(NULL)
274 // Construct from components
275 Foam::attachDetach::attachDetach
278 const dictionary& dict,
280 const polyTopoChanger& mme
283 polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
286 dict.lookup("faceZoneName"),
287 mme.mesh().faceZones()
291 dict.lookup("masterPatchName"),
292 mme.mesh().boundaryMesh()
296 dict.lookup("slavePatchName"),
297 mme.mesh().boundaryMesh()
299 triggerTimes_(dict.lookup("triggerTimes")),
300 manualTrigger_(dict.lookup("manualTrigger")),
304 pointMatchMapPtr_(NULL)
310 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
312 Foam::attachDetach::~attachDetach()
318 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
320 bool Foam::attachDetach::setAttach() const
335 bool Foam::attachDetach::setDetach() const
350 bool Foam::attachDetach::changeTopology() const
356 Pout<< "bool attachDetach::changeTopology() const "
357 << " for object " << name() << " : "
358 << "Manual trigger" << endl;
364 // To deal with multiple calls within the same time step, return true
365 // if trigger is already set
370 Pout<< "bool attachDetach::changeTopology() const "
371 << " for object " << name() << " : "
372 << "Already triggered for current time step" << endl;
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())
384 Pout<< "bool attachDetach::changeTopology() const "
385 << " for object " << name() << " : "
386 << "Reached end of trigger list" << endl;
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;
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_])
407 // Increment the trigger index
413 // No topological change
418 void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
420 // Insert the attach/detach instructions into the topological change
424 // Clear point addressing from previous attach/detach event
427 if (state_ == ATTACHED)
429 detachInterface(ref);
431 // Set the state to detached
434 else if (state_ == DETACHED)
436 attachInterface(ref);
438 // Set the state to attached
445 "void attachDetach::setRefinement(polyTopoChange&) const"
446 ) << "Requested attach/detach event and currect state "
448 << abort(FatalError);
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());
469 void Foam::attachDetach::write(Ostream& os) const
471 os << nl << type() << 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 // ************************************************************************* //