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 #include "perfectInterface.H"
00031 #include <dynamicMesh/polyTopoChanger.H>
00032 #include <OpenFOAM/polyMesh.H>
00033 #include <dynamicMesh/polyTopoChange.H>
00034 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00035 #include <OpenFOAM/mapPolyMesh.H>
00036 #include <OpenFOAM/matchPoints.H>
00037 #include <dynamicMesh/polyModifyFace.H>
00038 #include <dynamicMesh/polyRemovePoint.H>
00039 #include <dynamicMesh/polyRemoveFace.H>
00040
00041
00042
00043 namespace Foam
00044 {
00045 defineTypeNameAndDebug(perfectInterface, 0);
00046 addToRunTimeSelectionTable
00047 (
00048 polyMeshModifier,
00049 perfectInterface,
00050 dictionary
00051 );
00052 }
00053
00054
00055
00056 const Foam::scalar Foam::perfectInterface::tol_ = 1E-3;
00057
00058
00059
00060
00061 Foam::pointField Foam::perfectInterface::calcFaceCentres
00062 (
00063 const primitivePatch& pp
00064 )
00065 {
00066 const pointField& points = pp.points();
00067
00068 pointField ctrs(pp.size());
00069
00070 forAll(ctrs, patchFaceI)
00071 {
00072 ctrs[patchFaceI] = pp[patchFaceI].centre(points);
00073 }
00074
00075 return ctrs;
00076 }
00077
00078
00079
00080
00081
00082 Foam::perfectInterface::perfectInterface
00083 (
00084 const word& name,
00085 const label index,
00086 const polyTopoChanger& mme,
00087 const word& faceZoneName,
00088 const word& masterPatchName,
00089 const word& slavePatchName
00090 )
00091 :
00092 polyMeshModifier(name, index, mme, true),
00093 faceZoneID_(faceZoneName, mme.mesh().faceZones()),
00094 masterPatchID_(masterPatchName, mme.mesh().boundaryMesh()),
00095 slavePatchID_(slavePatchName, mme.mesh().boundaryMesh())
00096 {}
00097
00098
00099
00100 Foam::perfectInterface::perfectInterface
00101 (
00102 const word& name,
00103 const dictionary& dict,
00104 const label index,
00105 const polyTopoChanger& mme
00106 )
00107 :
00108 polyMeshModifier(name, index, mme, readBool(dict.lookup("active"))),
00109 faceZoneID_
00110 (
00111 dict.lookup("faceZoneName"),
00112 mme.mesh().faceZones()
00113 ),
00114 masterPatchID_
00115 (
00116 dict.lookup("masterPatchName"),
00117 mme.mesh().boundaryMesh()
00118 ),
00119 slavePatchID_
00120 (
00121 dict.lookup("slavePatchName"),
00122 mme.mesh().boundaryMesh()
00123 )
00124 {}
00125
00126
00127
00128
00129 Foam::perfectInterface::~perfectInterface()
00130 {}
00131
00132
00133
00134
00135 bool Foam::perfectInterface::changeTopology() const
00136 {
00137
00138 if (!active())
00139 {
00140 if (debug)
00141 {
00142 Pout<< "bool perfectInterface::changeTopology() const "
00143 << "for object " << name() << " : "
00144 << "Inactive" << endl;
00145 }
00146
00147 return false;
00148 }
00149 else
00150 {
00151
00152 return true;
00153 }
00154 }
00155
00156
00157 void Foam::perfectInterface::setRefinement(polyTopoChange& ref) const
00158 {
00159 if (debug)
00160 {
00161 Pout<< "bool perfectInterface::setRefinement(polyTopoChange&) const : "
00162 << "for object " << name() << " : "
00163 << "masterPatchID_:" << masterPatchID_
00164 << " slavePatchID_:" << slavePatchID_
00165 << " faceZoneID_:" << faceZoneID_ << endl;
00166 }
00167
00168 if
00169 (
00170 masterPatchID_.active()
00171 && slavePatchID_.active()
00172 && faceZoneID_.active()
00173 )
00174 {
00175 const polyMesh& mesh = topoChanger().mesh();
00176
00177 const polyBoundaryMesh& patches = mesh.boundaryMesh();
00178
00179 const polyPatch& pp0 = patches[masterPatchID_.index()];
00180 const polyPatch& pp1 = patches[slavePatchID_.index()];
00181
00182
00183 const edgeList& edges0 = pp0.edges();
00184 const pointField& pts0 = pp0.localPoints();
00185 const pointField& pts1 = pp1.localPoints();
00186 const labelList& meshPts0 = pp0.meshPoints();
00187 const labelList& meshPts1 = pp1.meshPoints();
00188
00189
00190
00191
00192 scalar minLen = GREAT;
00193
00194 forAll(edges0, edgeI)
00195 {
00196 minLen = min(minLen, edges0[edgeI].mag(pts0));
00197 }
00198 scalar typDim = tol_*minLen;
00199
00200 if (debug)
00201 {
00202 Pout<< "typDim:" << typDim << " edges0:" << edges0.size()
00203 << " pts0:" << pts0.size() << " pts1:" << pts1.size()
00204 << " pp0:" << pp0.size() << " pp1:" << pp1.size() << endl;
00205 }
00206
00207
00208
00209
00210
00211 labelList renumberPoints(mesh.points().size());
00212 forAll(renumberPoints, i)
00213 {
00214 renumberPoints[i] = i;
00215 }
00216 {
00217 labelList from1To0Points(pts1.size());
00218
00219 bool matchOk = matchPoints
00220 (
00221 pts1,
00222 pts0,
00223 scalarField(pts1.size(), typDim),
00224 true,
00225 from1To0Points
00226 );
00227
00228 if (!matchOk)
00229 {
00230 FatalErrorIn
00231 (
00232 "perfectInterface::setRefinement(polyTopoChange& ref) const"
00233 ) << "Points on patches " << pp0.name() << " and "
00234 << pp1.name() << " do not match to within tolerance "
00235 << typDim << exit(FatalError);
00236 }
00237
00238 forAll(pts1, i)
00239 {
00240 renumberPoints[meshPts1[i]] = meshPts0[from1To0Points[i]];
00241 }
00242 }
00243
00244
00245
00246
00247
00248 labelList from0To1Faces(pp1.size());
00249
00250 bool matchOk = matchPoints
00251 (
00252 calcFaceCentres(pp0),
00253 calcFaceCentres(pp1),
00254 scalarField(pp0.size(), typDim),
00255 true,
00256 from0To1Faces
00257 );
00258
00259 if (!matchOk)
00260 {
00261 FatalErrorIn
00262 (
00263 "perfectInterface::setRefinement(polyTopoChange& ref) const"
00264 ) << "Face centres of patches " << pp0.name() << " and "
00265 << pp1.name() << " do not match to within tolerance " << typDim
00266 << exit(FatalError);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 labelHashSet affectedFaces(2*pp1.size());
00278 forAll(meshPts1, i)
00279 {
00280 label meshPointI = meshPts1[i];
00281
00282 if (meshPointI != renumberPoints[meshPointI])
00283 {
00284 const labelList& pFaces = mesh.pointFaces()[meshPointI];
00285
00286 forAll(pFaces, pFaceI)
00287 {
00288 affectedFaces.insert(pFaces[pFaceI]);
00289 }
00290 }
00291 }
00292 forAll(pp1, i)
00293 {
00294 affectedFaces.erase(pp1.start() + i);
00295 }
00296
00297
00298
00299
00300 forAll(pp0, i)
00301 {
00302 if (affectedFaces.erase(pp0.start() + i))
00303 {
00304 WarningIn
00305 (
00306 "perfectInterface::setRefinement(polyTopoChange&) const"
00307 ) << "Found face " << pp0.start() + i << " vertices "
00308 << mesh.faces()[pp0.start() + i] << " whose points are"
00309 << " used both by master patch " << pp0.name()
00310 << " and slave patch " << pp1.name()
00311 << endl;
00312 }
00313 }
00314
00315
00316
00317 for
00318 (
00319 labelHashSet::const_iterator iter = affectedFaces.begin();
00320 iter != affectedFaces.end();
00321 ++iter
00322 )
00323 {
00324 label faceI = iter.key();
00325
00326 const face& f = mesh.faces()[faceI];
00327
00328 face newFace(f.size());
00329
00330 forAll(newFace, fp)
00331 {
00332 newFace[fp] = renumberPoints[f[fp]];
00333 }
00334
00335 label nbr = -1;
00336
00337 label patchI = -1;
00338
00339 if (mesh.isInternalFace(faceI))
00340 {
00341 nbr = mesh.faceNeighbour()[faceI];
00342 }
00343 else
00344 {
00345 patchI = patches.whichPatch(faceI);
00346 }
00347
00348 label zoneID = mesh.faceZones().whichZone(faceI);
00349
00350 bool zoneFlip = false;
00351
00352 if (zoneID >= 0)
00353 {
00354 const faceZone& fZone = mesh.faceZones()[zoneID];
00355
00356 zoneFlip = fZone.flipMap()[fZone.whichFace(faceI)];
00357 }
00358
00359 ref.setAction
00360 (
00361 polyModifyFace
00362 (
00363 newFace,
00364 faceI,
00365 mesh.faceOwner()[faceI],
00366 nbr,
00367 false,
00368 patchI,
00369 false,
00370 zoneID,
00371 zoneFlip
00372 )
00373 );
00374 }
00375
00376
00377
00378 forAll(meshPts1, i)
00379 {
00380 label meshPointI = meshPts1[i];
00381
00382 if (meshPointI != renumberPoints[meshPointI])
00383 {
00384 ref.setAction(polyRemovePoint(meshPointI));
00385 }
00386 }
00387
00388
00389
00390 forAll(pp1, i)
00391 {
00392 ref.setAction(polyRemoveFace(pp1.start() + i));
00393 }
00394
00395
00396
00397
00398
00399 const boolList& mfFlip =
00400 mesh.faceZones()[faceZoneID_.index()].flipMap();
00401
00402 forAll(pp0, i)
00403 {
00404 label faceI = pp0.start() + i;
00405
00406 const face& f = mesh.faces()[faceI];
00407
00408 face newFace(f.size());
00409
00410 forAll(newFace, fp)
00411 {
00412 newFace[fp] = renumberPoints[f[fp]];
00413 }
00414
00415 label own = mesh.faceOwner()[faceI];
00416
00417 label pp1FaceI = pp1.start() + from0To1Faces[i];
00418
00419 label nbr = mesh.faceOwner()[pp1FaceI];
00420
00421 if (own < nbr)
00422 {
00423 ref.setAction
00424 (
00425 polyModifyFace
00426 (
00427 newFace,
00428 faceI,
00429 own,
00430 nbr,
00431 false,
00432 -1,
00433 false,
00434 faceZoneID_.index(),
00435 mfFlip[i]
00436 )
00437 );
00438 }
00439 else
00440 {
00441 ref.setAction
00442 (
00443 polyModifyFace
00444 (
00445 newFace.reverseFace(),
00446 faceI,
00447 nbr,
00448 own,
00449 false,
00450 -1,
00451 false,
00452 faceZoneID_.index(),
00453 !mfFlip[i]
00454 )
00455 );
00456 }
00457 }
00458 }
00459 }
00460
00461
00462 void Foam::perfectInterface::modifyMotionPoints(pointField& motionPoints) const
00463 {
00464
00465
00466 }
00467
00468
00469 void Foam::perfectInterface::updateMesh(const mapPolyMesh& morphMap)
00470 {
00471
00472 const polyMesh& mesh = topoChanger().mesh();
00473
00474 faceZoneID_.update(mesh.faceZones());
00475 masterPatchID_.update(mesh.boundaryMesh());
00476 slavePatchID_.update(mesh.boundaryMesh());
00477 }
00478
00479
00480 void Foam::perfectInterface::write(Ostream& os) const
00481 {
00482 os << nl << type() << nl
00483 << name()<< nl
00484 << faceZoneID_.name() << nl
00485 << masterPatchID_.name() << nl
00486 << slavePatchID_.name() << endl;
00487 }
00488
00489
00490 void Foam::perfectInterface::writeDict(Ostream& os) const
00491 {
00492 os << nl << name() << nl << token::BEGIN_BLOCK << nl
00493
00494 << " type " << type()
00495 << token::END_STATEMENT << nl
00496
00497 << " active " << active()
00498 << token::END_STATEMENT << nl
00499
00500 << " faceZoneName " << faceZoneID_.name()
00501 << token::END_STATEMENT << nl
00502
00503 << " masterPatchName " << masterPatchID_.name()
00504 << token::END_STATEMENT << nl
00505
00506 << " slavePatchName " << slavePatchID_.name()
00507 << token::END_STATEMENT << nl
00508
00509 << token::END_BLOCK << endl;
00510 }
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522