FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

enrichedPatchFaces.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Description
00025 
00026 \*---------------------------------------------------------------------------*/
00027 
00028 #include "enrichedPatch.H"
00029 #include <OpenFOAM/DynamicList.H>
00030 
00031 
00032 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00033 
00034 const Foam::label Foam::enrichedPatch::enrichedFaceRatio_ = 3;
00035 
00036 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00037 
00038 void Foam::enrichedPatch::calcEnrichedFaces
00039 (
00040     const labelListList& pointsIntoMasterEdges,
00041     const labelListList& pointsIntoSlaveEdges,
00042     const pointField& projectedSlavePoints
00043 )
00044 {
00045     if (enrichedFacesPtr_)
00046     {
00047         FatalErrorIn
00048         (
00049             "void enrichedPatch::calcEnrichedFaces\n"
00050             "(\n"
00051             "    const labelListList& pointsIntoMasterEdges,\n"
00052             "    const labelListList& pointsIntoSlaveEdges,\n"
00053             "    const pointField& projectedSlavePoints\n"
00054             ")"
00055         )   << "Enriched faces already calculated."
00056             << abort(FatalError);
00057     }
00058 
00059     // Create a list of enriched faces
00060     // Algorithm:
00061     // 1) Grab the original face and start from point zero.
00062     // 2) If the point has been merged away, grab the merge label;
00063     //    otherwise, keep the original label.
00064     // 3) Go to the next edge. Collect all the points to be added along
00065     //    the edge; order them in the necessary direction and insert onto the
00066     //    face.
00067     // 4) Grab the next point and return on step 2.
00068     enrichedFacesPtr_ = new faceList(masterPatch_.size() + slavePatch_.size());
00069     faceList& enrichedFaces = *enrichedFacesPtr_;
00070 
00071     label nEnrichedFaces = 0;
00072 
00073     const pointField& masterLocalPoints = masterPatch_.localPoints();
00074     const faceList& masterLocalFaces = masterPatch_.localFaces();
00075     const labelListList& masterFaceEdges = masterPatch_.faceEdges();
00076 
00077     const faceList& slaveLocalFaces = slavePatch_.localFaces();
00078     const labelListList& slaveFaceEdges = slavePatch_.faceEdges();
00079 
00080     // For correct functioning of the enrichedPatch class, the slave
00081     // faces need to be inserted first.  See comments in
00082     // enrichedPatch.H
00083 
00084     // Get reference to the point merge map
00085     const Map<label>& pmm = pointMergeMap();
00086 
00087     // Add slave faces into the enriched faces list
00088 
00089     forAll (slavePatch_, faceI)
00090     {
00091         const face oldFace = slavePatch_[faceI];
00092         const face oldLocalFace = slaveLocalFaces[faceI];
00093 //         Info << "old slave face " << faceI << ": " << oldFace << endl;
00094         const labelList& curEdges = slaveFaceEdges[faceI];
00095 
00096         DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
00097 
00098         // Note: The number of points and edges in a face is always identical
00099         // so both can be done is the same loop
00100         forAll (oldFace, i)
00101         {
00102             // Add the point
00103             Map<label>::const_iterator mpIter =
00104                 pmm.find(oldFace[i]);
00105 
00106             if (mpIter == pmm.end())
00107             {
00108                 // Point not mapped
00109                 newFace.append(oldFace[i]);
00110 
00111                 // Add the projected point into the patch support
00112                 pointMap().insert
00113                 (
00114                     oldFace[i],    // Global label of point
00115                     projectedSlavePoints[oldLocalFace[i]] // Projected position
00116                 );
00117             }
00118             else
00119             {
00120                 // Point mapped
00121                 newFace.append(mpIter());
00122 
00123                 // Add the projected point into the patch support
00124                 pointMap().insert
00125                 (
00126                     mpIter(),    // Merged global label of point
00127                     projectedSlavePoints[oldLocalFace[i]] // Projected position
00128                 );
00129             }
00130 
00131             // Grab the edge points
00132 
00133             const labelList& slavePointsOnEdge =
00134                 pointsIntoSlaveEdges[curEdges[i]];
00135 //             Info << "slavePointsOnEdge for " << curEdges[i] << ": " << slavePointsOnEdge << endl;
00136             // If there are no points on the edge, skip everything
00137             // If there is only one point, no need for sorting
00138             if (slavePointsOnEdge.size())
00139             {
00140                 // Sort edge points in order
00141                 scalarField edgePointWeights(slavePointsOnEdge.size());
00142                 const point& startPoint = projectedSlavePoints[oldLocalFace[i]];
00143 
00144                 vector e =
00145                     projectedSlavePoints[oldLocalFace.nextLabel(i)]
00146                   - startPoint;
00147 
00148                 scalar magSqrE = magSqr(e);
00149 
00150                 if (magSqrE > SMALL)
00151                 {
00152                     e /= magSqrE;
00153                 }
00154                 else
00155                 {
00156                     FatalErrorIn
00157                     (
00158                         "void enrichedPatch::calcEnrichedFaces\n"
00159                         "(\n"
00160                         "    const labelListList& pointsIntoMasterEdges,\n"
00161                         "    const labelListList& pointsIntoSlaveEdges,\n"
00162                         "    const pointField& projectedSlavePoints\n"
00163                         ")"
00164                     )   << "Zero length edge in slave patch for face " << i
00165                         << ".  This is not allowed."
00166                         << abort(FatalError);
00167                 }
00168 
00169                 pointField slavePosOnEdge(slavePointsOnEdge.size());
00170 
00171                 forAll (slavePointsOnEdge, edgePointI)
00172                 {
00173                     slavePosOnEdge[edgePointI] =
00174                         pointMap().find(slavePointsOnEdge[edgePointI])();
00175 
00176                     edgePointWeights[edgePointI] =
00177                         (e & (slavePosOnEdge[edgePointI] - startPoint));
00178                 }
00179 
00180                 if (debug)
00181                 {
00182                     // Check weights: all new points should be on the edge
00183                     if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
00184                     {
00185                         FatalErrorIn
00186                         (
00187                             "void enrichedPatch::calcEnrichedFaces\n"
00188                             "(\n"
00189                             "    const labelListList& pointsIntoMasterEdges,\n"
00190                             "    const labelListList& pointsIntoSlaveEdges,\n"
00191                             "    const pointField& projectedSlavePoints\n"
00192                             ")"
00193                         )   << "Invalid point edge weights.  Some of points are"
00194                             << " not on the edge for edge " << curEdges[i]
00195                             << " of face " << faceI << " in slave patch." << nl
00196                             << "Min weight: " << min(edgePointWeights)
00197                             << " Max weight: " << max(edgePointWeights)
00198                             << abort(FatalError);
00199                     }
00200                 }
00201 
00202                 // Go through the points and collect them based on
00203                 // weights from lower to higher.  This gives the
00204                 // correct order of points along the edge.
00205                 for (label passI = 0; passI < edgePointWeights.size(); passI++)
00206                 {
00207                     // Max weight can only be one, so the sorting is
00208                     // done by elimination.
00209                     label nextPoint = -1;
00210                     scalar dist = 2;
00211 
00212                     forAll (edgePointWeights, wI)
00213                     {
00214                         if (edgePointWeights[wI] < dist)
00215                         {
00216                             dist = edgePointWeights[wI];
00217                             nextPoint = wI;
00218                         }
00219                     }
00220 
00221                     // Insert the next point and reset its weight to exclude it
00222                     // from future picks
00223                     newFace.append(slavePointsOnEdge[nextPoint]);
00224                     edgePointWeights[nextPoint] = GREAT;
00225 
00226                     // Add the point into patch support
00227                     pointMap().insert
00228                     (
00229                         slavePointsOnEdge[nextPoint],
00230                         slavePosOnEdge[nextPoint]
00231                     );
00232                 }
00233             }
00234         }
00235         // Info<< "New slave face " << faceI << ": " << newFace << endl;
00236 
00237         // Add the new face to the list
00238         enrichedFaces[nEnrichedFaces].transfer(newFace);
00239         nEnrichedFaces++;
00240     }
00241 
00242     // Add master faces into the enriched faces list
00243 
00244     forAll (masterPatch_, faceI)
00245     {
00246         const face& oldFace = masterPatch_[faceI];
00247         const face& oldLocalFace = masterLocalFaces[faceI];
00248 //         Info << "old master face: " << oldFace << endl;
00249         const labelList& curEdges = masterFaceEdges[faceI];
00250 
00251         DynamicList<label> newFace(oldFace.size()*enrichedFaceRatio_);
00252 
00253         // Note: The number of points and edges in a face is always identical
00254         // so both can be done is the same loop
00255         forAll (oldFace, i)
00256         {
00257             // Add the point
00258             Map<label>::const_iterator mpIter =
00259                 pmm.find(oldFace[i]);
00260 
00261             if (mpIter == pmm.end())
00262             {
00263                 // Point not mapped
00264                 newFace.append(oldFace[i]);
00265 
00266                 // Add the point into patch support
00267                 pointMap().insert
00268                 (
00269                     oldFace[i],
00270                     masterLocalPoints[oldLocalFace[i]]
00271                 );
00272             }
00273             else
00274             {
00275                 // Point mapped
00276                 newFace.append(mpIter());
00277 
00278                 // Add the point into support
00279                 pointMap().insert(mpIter(), masterLocalPoints[oldLocalFace[i]]);
00280             }
00281 
00282             // Grab the edge points
00283 
00284             const labelList& masterPointsOnEdge =
00285                 pointsIntoMasterEdges[curEdges[i]];
00286 
00287             // If there are no points on the edge, skip everything
00288             // If there is only one point, no need for sorting
00289             if (masterPointsOnEdge.size())
00290             {
00291                 // Sort edge points in order
00292                 scalarField edgePointWeights(masterPointsOnEdge.size());
00293                 const point& startPoint = masterLocalPoints[oldLocalFace[i]];
00294 
00295                 vector e =
00296                     masterLocalPoints[oldLocalFace.nextLabel(i)]
00297                   - startPoint;
00298 
00299                 scalar magSqrE = magSqr(e);
00300 
00301                 if (magSqrE > SMALL)
00302                 {
00303                     e /= magSqrE;
00304                 }
00305                 else
00306                 {
00307                     FatalErrorIn
00308                     (
00309                         "void enrichedPatch::calcEnrichedFaces\n"
00310                         "(\n"
00311                         "    const labelListList& pointsIntoMasterEdges,\n"
00312                         "    const labelListList& pointsIntoSlaveEdges,\n"
00313                         "    const pointField& projectedSlavePoints\n"
00314                         ")"
00315                     )   << "Zero length edge in master patch for face " << i
00316                         << ".  This is not allowed."
00317                         << abort(FatalError);
00318                 }
00319 
00320                 pointField masterPosOnEdge(masterPointsOnEdge.size());
00321 
00322                 forAll (masterPointsOnEdge, edgePointI)
00323                 {
00324                     masterPosOnEdge[edgePointI] =
00325                         pointMap().find(masterPointsOnEdge[edgePointI])();
00326 
00327                     edgePointWeights[edgePointI] =
00328                         (e & (masterPosOnEdge[edgePointI] - startPoint));
00329                 }
00330 
00331                 if (debug)
00332                 {
00333                     // Check weights: all new points should be on the edge
00334                     if (min(edgePointWeights) < 0 || max(edgePointWeights) > 1)
00335                     {
00336                         FatalErrorIn
00337                         (
00338                             "void enrichedPatch::calcEnrichedFaces\n"
00339                             "(\n"
00340                             "    const labelListList& pointsIntoMasterEdges,\n"
00341                             "    const labelListList& pointsIntoSlaveEdges,\n"
00342                             "    const pointField& projectedSlavePoints\n"
00343                             ")"
00344                         )   << "Invalid point edge weights.  Some of points are"
00345                             << " not on the edge for edge " << curEdges[i]
00346                             << " of face " << faceI << " in master patch." << nl
00347                             << "Min weight: " << min(edgePointWeights)
00348                             << " Max weight: " << max(edgePointWeights)
00349                             << abort(FatalError);
00350                     }
00351                 }
00352 
00353                 // Go through the points and collect them based on
00354                 // weights from lower to higher.  This gives the
00355                 // correct order of points along the edge.
00356                 for (label pass = 0; pass < edgePointWeights.size(); pass++)
00357                 {
00358                     // Max weight can only be one, so the sorting is
00359                     // done by elimination.
00360                     label nextPoint = -1;
00361                     scalar dist = 2;
00362 
00363                     forAll (edgePointWeights, wI)
00364                     {
00365                         if (edgePointWeights[wI] < dist)
00366                         {
00367                             dist = edgePointWeights[wI];
00368                             nextPoint = wI;
00369                         }
00370                     }
00371 
00372                     // Insert the next point and reset its weight to exclude it
00373                     // from future picks
00374                     newFace.append(masterPointsOnEdge[nextPoint]);
00375                     edgePointWeights[nextPoint] = GREAT;
00376 
00377                     // Add the point into patch support
00378                     pointMap().insert
00379                     (
00380                         masterPointsOnEdge[nextPoint],
00381                         masterPosOnEdge[nextPoint]
00382                     );
00383                 }
00384             }
00385         }
00386         // Info<< "New master face: " << newFace << endl;
00387 
00388         // Add the new face to the list
00389         enrichedFaces[nEnrichedFaces].transfer(newFace);
00390         nEnrichedFaces++;
00391     }
00392 
00393     // Check the support for the enriched patch
00394     if (debug)
00395     {
00396         if (!checkSupport())
00397         {
00398             Info<< "Enriched patch support OK. Slave faces: "
00399                 << slavePatch_.size() << " Master faces: "
00400                 << masterPatch_.size() << endl;
00401         }
00402         else
00403         {
00404             FatalErrorIn
00405             (
00406                 "void enrichedPatch::calcEnrichedFaces\n"
00407                 "(\n"
00408                 "    const labelListList& pointsIntoMasterEdges,\n"
00409                 "    const labelListList& pointsIntoSlaveEdges,\n"
00410                 "    const pointField& projectedSlavePoints\n"
00411                 ")"
00412             )   << "Error in enriched patch support"
00413                 << abort(FatalError);
00414         }
00415     }
00416 }
00417 
00418 
00419 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00420 
00421 const Foam::faceList& Foam::enrichedPatch::enrichedFaces() const
00422 {
00423     if (!enrichedFacesPtr_)
00424     {
00425         FatalErrorIn("const faceList& enrichedPatch::enrichedFaces() const")
00426             << "Enriched faces not available yet.  Please use "
00427             << "void enrichedPatch::calcEnrichedFaces\n"
00428             << "(\n"
00429             << "    const labelListList& pointsIntoMasterEdges,\n"
00430             << "    const labelListList& pointsIntoSlaveEdges,\n"
00431             << "    const pointField& projectedSlavePoints\n"
00432             << ")"
00433             << " before trying to access faces."
00434             << abort(FatalError);
00435     }
00436 
00437     return *enrichedFacesPtr_;
00438 }
00439 
00440 
00441 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines