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