1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 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
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
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/>.
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"
35 #include "primitiveMesh.H"
36 #include "polyTopoChange.H"
37 #include "addToRunTimeSelectionTable.H"
39 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
43 defineTypeNameAndDebug(attachDetach, 0);
44 addToRunTimeSelectionTable
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
55 void Foam::attachDetach::checkDefinition()
60 || !masterPatchID_.active()
61 || !slavePatchID_.active()
66 "void Foam::attachDetach::checkDefinition()"
67 ) << "Not all zones and patches needed in the definition "
68 << "have been found. Please check your mesh definition."
72 const polyMesh& mesh = topoChanger().mesh();
76 Pout<< "Attach/detach object " << name() << " :" << nl
77 << " faceZoneID: " << faceZoneID_ << nl
78 << " masterPatchID: " << masterPatchID_ << nl
79 << " slavePatchID: " << slavePatchID_ << endl;
82 // Check the sizes and set up state
85 mesh.boundaryMesh()[masterPatchID_.index()].empty()
86 && mesh.boundaryMesh()[slavePatchID_.index()].empty()
89 // Boundary is attached
92 Pout<< " Attached on construction" << endl;
97 // Check if there are faces in the master zone
98 if (mesh.faceZones()[faceZoneID_.index()].empty())
102 "void Foam::attachDetach::checkDefinition()"
103 ) << "Attach/detach zone contains no faces. Please check your "
104 << "mesh definition."
105 << abort(FatalError);
108 // Check that all the faces in the face zone are internal
111 const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
113 DynamicList<label> bouFacesInZone(addr.size());
117 if (!mesh.isInternalFace(addr[faceI]))
119 bouFacesInZone.append(addr[faceI]);
123 if (bouFacesInZone.size())
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);
139 // Boundary is detached
142 Pout<< " Detached on construction" << endl;
147 // Check that the sizes of master and slave patch are identical
148 // and identical to the size of the face zone
152 mesh.boundaryMesh()[masterPatchID_.index()].size()
153 != mesh.boundaryMesh()[slavePatchID_.index()].size()
156 mesh.boundaryMesh()[masterPatchID_.index()].size()
157 != mesh.faceZones()[faceZoneID_.index()].size()
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
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);
176 // Check that all the faces belong to either master or slave patch
179 const labelList& addr = mesh.faceZones()[faceZoneID_.index()];
181 DynamicList<label> zoneProblemFaces(addr.size());
186 mesh.boundaryMesh().whichPatch(addr[faceI]);
190 facePatch != masterPatchID_.index()
191 && facePatch != slavePatchID_.index()
194 zoneProblemFaces.append(addr[faceI]);
198 if (zoneProblemFaces.size())
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);
213 // Check that trigger times are in ascending order
214 bool triggersOK = true;
216 for (label i = 0; i < triggerTimes_.size() - 1; i++)
218 triggersOK = triggersOK && (triggerTimes_[i] < triggerTimes_[i + 1]);
224 || (triggerTimes_.empty() && !manualTrigger())
229 "void Foam::attachDetach::checkDefinition()"
230 ) << "Problem with definition of trigger times: "
232 << abort(FatalError);
237 void Foam::attachDetach::clearAddressing() const
239 deleteDemandDrivenData(pointMatchMapPtr_);
243 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
245 // Construct from components
246 Foam::attachDetach::attachDetach
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),
267 pointMatchMapPtr_(NULL)
273 // Construct from components
274 Foam::attachDetach::attachDetach
277 const dictionary& dict,
279 const polyTopoChanger& mme
282 polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
285 dict.lookup("faceZoneName"),
286 mme.mesh().faceZones()
290 dict.lookup("masterPatchName"),
291 mme.mesh().boundaryMesh()
295 dict.lookup("slavePatchName"),
296 mme.mesh().boundaryMesh()
298 triggerTimes_(dict.lookup("triggerTimes")),
299 manualTrigger_(dict.lookup("manualTrigger")),
303 pointMatchMapPtr_(NULL)
309 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
311 Foam::attachDetach::~attachDetach()
317 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
319 bool Foam::attachDetach::setAttach() const
334 bool Foam::attachDetach::setDetach() const
349 bool Foam::attachDetach::changeTopology() const
355 Pout<< "bool attachDetach::changeTopology() const "
356 << " for object " << name() << " : "
357 << "Manual trigger" << endl;
363 // To deal with multiple calls within the same time step, return true
364 // if trigger is already set
369 Pout<< "bool attachDetach::changeTopology() const "
370 << " for object " << name() << " : "
371 << "Already triggered for current time step" << endl;
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())
383 Pout<< "bool attachDetach::changeTopology() const "
384 << " for object " << name() << " : "
385 << "Reached end of trigger list" << endl;
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;
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_])
406 // Increment the trigger index
412 // No topological change
417 void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
419 // Insert the attach/detach instructions into the topological change
423 // Clear point addressing from previous attach/detach event
426 if (state_ == ATTACHED)
428 detachInterface(ref);
430 // Set the state to detached
433 else if (state_ == DETACHED)
435 attachInterface(ref);
437 // Set the state to attached
444 "void attachDetach::setRefinement(polyTopoChange&) const"
445 ) << "Requested attach/detach event and currect state "
447 << abort(FatalError);
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());
468 void Foam::attachDetach::write(Ostream& os) const
470 os << nl << type() << 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 // ************************************************************************* //