00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00040
00041 namespace Foam
00042 {
00043 defineTypeNameAndDebug(attachDetach, 0);
00044 addToRunTimeSelectionTable
00045 (
00046 polyMeshModifier,
00047 attachDetach,
00048 dictionary
00049 );
00050 }
00051
00052
00053
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
00083 if
00084 (
00085 mesh.boundaryMesh()[masterPatchID_.index()].empty()
00086 && mesh.boundaryMesh()[slavePatchID_.index()].empty()
00087 )
00088 {
00089
00090 if (debug)
00091 {
00092 Pout<< " Attached on construction" << endl;
00093 }
00094
00095 state_ = ATTACHED;
00096
00097
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
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
00140 if (debug)
00141 {
00142 Pout<< " Detached on construction" << endl;
00143 }
00144
00145 state_ = DETACHED;
00146
00147
00148
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
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
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
00244
00245
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
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
00310
00311 Foam::attachDetach::~attachDetach()
00312 {
00313 clearAddressing();
00314 }
00315
00316
00317
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
00364
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
00378
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
00401
00402 if (topoChanger().mesh().time().value() >= triggerTimes_[triggerIndex_])
00403 {
00404 trigger_ = true;
00405
00406
00407 triggerIndex_++;
00408
00409 return true;
00410 }
00411
00412
00413 return false;
00414 }
00415
00416
00417 void Foam::attachDetach::setRefinement(polyTopoChange& ref) const
00418 {
00419
00420
00421 if (trigger_)
00422 {
00423
00424 clearAddressing();
00425
00426 if (state_ == ATTACHED)
00427 {
00428 detachInterface(ref);
00429
00430
00431 state_ = DETACHED;
00432 }
00433 else if (state_ == DETACHED)
00434 {
00435 attachInterface(ref);
00436
00437
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
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