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

cellMatcher.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 <OpenFOAM/cellMatcher.H>
00029 
00030 #include <OpenFOAM/primitiveMesh.H>
00031 #include <OpenFOAM/Map.H>
00032 #include <OpenFOAM/faceList.H>
00033 #include <OpenFOAM/labelList.H>
00034 
00035 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00036 
00037 Foam::labelList Foam::cellMatcher::makeIdentity(const label nElems)
00038 {
00039     labelList result(nElems);
00040 
00041     forAll(result, elemI)
00042     {
00043         result[elemI] = elemI;
00044     }
00045     return result;
00046 }
00047 
00048 
00049 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00050 
00051 // Construct from components
00052 Foam::cellMatcher::cellMatcher
00053 (
00054     const label vertPerCell,
00055     const label facePerCell,
00056     const label maxVertPerFace,
00057     const word& cellModelName
00058 )
00059 :
00060     localPoint_(100),
00061     localFaces_(facePerCell),
00062     faceSize_(facePerCell, -1),
00063     pointMap_(vertPerCell),
00064     faceMap_(facePerCell),
00065     edgeFaces_(2*vertPerCell*vertPerCell),
00066     pointFaceIndex_(vertPerCell),
00067     vertLabels_(vertPerCell),
00068     faceLabels_(facePerCell),
00069     cellModelName_(cellModelName),
00070     cellModelPtr_(NULL)
00071 {
00072     forAll(localFaces_, faceI)
00073     {
00074         face& f = localFaces_[faceI];
00075 
00076         f.setSize(maxVertPerFace);
00077     }
00078 
00079     forAll(pointFaceIndex_, vertI)
00080     {
00081         pointFaceIndex_[vertI].setSize(facePerCell);
00082     }
00083 }
00084 
00085 
00086 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00087 
00088 // Create localFaces_ , pointMap_ , faceMap_
00089 Foam::label Foam::cellMatcher::calcLocalFaces
00090 (
00091     const faceList& faces,
00092     const labelList& myFaces
00093 )
00094 {
00095     // Clear map from global to cell numbering
00096     localPoint_.clear();
00097 
00098     // Renumber face vertices and insert directly into localFaces_
00099     label newVertI = 0;
00100     forAll(myFaces, myFaceI)
00101     {
00102         label faceI = myFaces[myFaceI];
00103 
00104         const face& f = faces[faceI];
00105         face& localFace = localFaces_[myFaceI];
00106 
00107         // Size of localFace
00108         faceSize_[myFaceI] = f.size();
00109 
00110         forAll(f, localVertI)
00111         {
00112             label vertI = f[localVertI];
00113 
00114             Map<label>::iterator iter = localPoint_.find(vertI);
00115             if (iter == localPoint_.end())
00116             {
00117                 // Not found. Assign local vertex number.
00118 
00119                 if (newVertI >= pointMap_.size())
00120                 {
00121                     // Illegal face: more unique vertices than vertPerCell
00122                     return -1;
00123                 }
00124 
00125                 localFace[localVertI] = newVertI;
00126                 localPoint_.insert(vertI, newVertI);
00127                 newVertI++;
00128             }
00129             else
00130             {
00131                 // Reuse local vertex number.
00132                 localFace[localVertI] = *iter;
00133             }
00134         }
00135 
00136         // Create face from localvertex labels
00137         faceMap_[myFaceI] = faceI;
00138     }
00139 
00140     // Create local to global vertex mapping
00141     for
00142     (
00143         Map<label>::iterator iter = localPoint_.begin();
00144         iter != localPoint_.end();
00145         ++iter
00146     )
00147     {
00148         label fp = iter();
00149         pointMap_[fp] = iter.key();
00150     }
00151 
00153     //write(Info);
00154 
00155     return newVertI;
00156 }
00157 
00158 
00159 // Create edgeFaces_ : map from edge to two localFaces for single cell.
00160 void Foam::cellMatcher::calcEdgeAddressing(const label numVert)
00161 {
00162     edgeFaces_ = -1;
00163 
00164     forAll(localFaces_, localFaceI)
00165     {
00166         const face& f = localFaces_[localFaceI];
00167 
00168         label prevVertI = faceSize_[localFaceI] - 1;
00169         //forAll(f, fp)
00170         for
00171         (
00172             label fp = 0;
00173             fp < faceSize_[localFaceI];
00174             fp++
00175         )
00176         {
00177             label start = f[prevVertI];
00178             label end = f[fp];
00179             
00180             label key1 = edgeKey(numVert, start, end);
00181             label key2 = edgeKey(numVert, end, start);
00182 
00183             if (edgeFaces_[key1] == -1)
00184             {
00185                 // Entry key1 unoccupied. Store both permutations.
00186                 edgeFaces_[key1] = localFaceI;
00187                 edgeFaces_[key2] = localFaceI;
00188             }
00189             else if (edgeFaces_[key1+1] == -1)
00190             {
00191                 // Entry key1+1 unoccupied
00192                 edgeFaces_[key1+1] = localFaceI;
00193                 edgeFaces_[key2+1] = localFaceI;
00194             }
00195             else
00196             {
00197                 FatalErrorIn
00198                 (
00199                     "calcEdgeAddressing"
00200                     "(const faceList&, const label)"
00201                 )   << "edgeFaces_ full at entry:" << key1
00202                     << " for edge " << start << " " << end
00203                     << abort(FatalError);
00204             }
00205 
00206             prevVertI = fp;
00207         }
00208     }
00209 }
00210 
00211 
00212 // Create pointFaceIndex_ : map from vertI, faceI to index of vertI on faceI.
00213 void Foam::cellMatcher::calcPointFaceIndex()
00214 {
00215     // Fill pointFaceIndex_ with -1
00216     forAll(pointFaceIndex_, i)
00217     {
00218         labelList& faceIndices = pointFaceIndex_[i];
00219 
00220         faceIndices = -1;
00221     }
00222 
00223     forAll(localFaces_, localFaceI)
00224     {
00225         const face& f = localFaces_[localFaceI];
00226 
00227         for
00228         (
00229             label fp = 0;
00230             fp < faceSize_[localFaceI];
00231             fp++
00232         )
00233         {
00234             label vert = f[fp];
00235             pointFaceIndex_[vert][localFaceI] = fp;
00236         }
00237     }
00238 }
00239 
00240 
00241 // Given edge(v0,v1) and (local)faceI return the other face
00242 Foam::label Foam::cellMatcher::otherFace
00243 (
00244     const label numVert,
00245     const label v0,
00246     const label v1,
00247     const label localFaceI
00248 ) const
00249 {
00250     label key = edgeKey(numVert, v0, v1);
00251 
00252     if (edgeFaces_[key] == localFaceI)
00253     {
00254         return edgeFaces_[key+1];
00255     }
00256     else if (edgeFaces_[key+1] == localFaceI)
00257     {
00258         return edgeFaces_[key];
00259     }
00260     else
00261     {
00262         FatalErrorIn
00263         (
00264             "otherFace"
00265             "(const label, const labelList&, const label, const label, "
00266             "const label)"
00267         )   << "edgeFaces_ does not contain:" << localFaceI
00268             << " for edge " << v0 << " " << v1 << " at key " << key
00269             << " edgeFaces_[key, key+1]:" <<  edgeFaces_[key]
00270             << " , " << edgeFaces_[key+1]
00271             << abort(FatalError);
00272 
00273         return -1;
00274     }
00275 }
00276 
00277 
00278 void Foam::cellMatcher::write(Foam::Ostream& os) const
00279 {
00280     os  << "Faces:" << endl;
00281 
00282     forAll(localFaces_, faceI)
00283     {
00284         os  << "    ";
00285 
00286         for(label fp = 0; fp < faceSize_[faceI]; fp++)
00287         {
00288             os  << ' ' << localFaces_[faceI][fp];
00289         }
00290         os  << endl;
00291     }
00292 
00293     os  <<  "Face map  : " << faceMap_ << endl;
00294     os  <<  "Point map : " << pointMap_ << endl;
00295 }
00296 
00297 
00298 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines