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

patchDataWave.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 \*---------------------------------------------------------------------------*/
00025 
00026 #include "patchDataWave.H"
00027 #include <OpenFOAM/MeshWave.H>
00028 
00029 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00030 
00031 // Set initial set of changed faces (= all wall faces)
00032 template<class TransferType>
00033 void Foam::patchDataWave<TransferType>::setChangedFaces
00034 (
00035     const labelHashSet& patchIDs,
00036     labelList& changedFaces,
00037     List<TransferType>& faceDist
00038 ) const
00039 {
00040     const polyMesh& mesh = cellDistFuncs::mesh();
00041 
00042     label nChangedFaces = 0;
00043 
00044     forAll(mesh.boundaryMesh(), patchI)
00045     {
00046         if (patchIDs.found(patchI))
00047         {
00048             const polyPatch& patch = mesh.boundaryMesh()[patchI];
00049 
00050             const Field<Type>& patchField = initialPatchValuePtrs_[patchI];
00051 
00052             forAll(patch.faceCentres(), patchFaceI)
00053             {
00054                 label meshFaceI = patch.start() + patchFaceI;
00055 
00056                 changedFaces[nChangedFaces] = meshFaceI;
00057 
00058                 faceDist[nChangedFaces] =
00059                     TransferType
00060                     (
00061                         patch.faceCentres()[patchFaceI],
00062                         patchField[patchFaceI],
00063                         0.0
00064                     );
00065 
00066                 nChangedFaces++;
00067             }
00068         }
00069     }
00070 }
00071 
00072 
00073 // Copy from MeshWave data into *this (distance) and field_ (transported data)
00074 template<class TransferType>
00075 Foam::label Foam::patchDataWave<TransferType>::getValues
00076 (
00077     const MeshWave<TransferType>& waveInfo
00078 )
00079 {
00080     const polyMesh& mesh = cellDistFuncs::mesh();
00081 
00082     const List<TransferType>& cellInfo = waveInfo.allCellInfo();
00083     const List<TransferType>& faceInfo = waveInfo.allFaceInfo();
00084 
00085     label nIllegal = 0;
00086 
00087     // Copy cell values
00088     distance_.setSize(cellInfo.size());
00089 
00090     forAll(cellInfo, cellI)
00091     {
00092         const TransferType & wpn = cellInfo[cellI];
00093 
00094         scalar dist = wpn.distSqr();
00095 
00096         if (cellInfo[cellI].valid())
00097         {
00098             distance_[cellI] = Foam::sqrt(dist);
00099 
00100             cellData_[cellI] = cellInfo[cellI].data();
00101         }
00102         else
00103         {
00104             // Illegal/unset value. What to do with data?
00105 
00106             distance_[cellI] = dist;
00107 
00108             //cellData_[cellI] = wallPoint::greatPoint;
00109             cellData_[cellI] = cellInfo[cellI].data();
00110 
00111             nIllegal++;
00112         }
00113     }
00114 
00115     // Copy boundary values
00116     forAll(patchDistance_, patchI)
00117     {
00118         const polyPatch& patch = mesh.boundaryMesh()[patchI];
00119 
00120         // Allocate storage for patchDistance
00121         scalarField* patchFieldPtr = new scalarField(patch.size());
00122 
00123         patchDistance_.set(patchI, patchFieldPtr);
00124 
00125         scalarField& patchField = *patchFieldPtr;
00126 
00127         // Allocate storage for patchData
00128         Field<Type>* patchDataFieldPtr = new Field<Type>(patch.size());
00129 
00130         patchData_.set(patchI, patchDataFieldPtr);
00131 
00132         Field<Type>& patchDataField = *patchDataFieldPtr;
00133 
00134         // Copy distance and data
00135         forAll(patchField, patchFaceI)
00136         {
00137             label meshFaceI = patch.start() + patchFaceI;
00138 
00139             scalar dist = faceInfo[meshFaceI].distSqr();
00140 
00141             if (faceInfo[meshFaceI].valid())
00142             {
00143                 // Adding SMALL to avoid problems with /0 in the turbulence
00144                 // models
00145                 patchField[patchFaceI] = Foam::sqrt(dist) + SMALL;
00146 
00147                 patchDataField[patchFaceI] = faceInfo[meshFaceI].data();
00148             }
00149             else
00150             {
00151                 // Illegal/unset value. What to do with data?
00152 
00153                 patchField[patchFaceI] = dist;
00154 
00155                 //patchDataField[patchFaceI] = wallPoint::greatPoint;
00156                 patchDataField[patchFaceI] = faceInfo[meshFaceI].data();
00157 
00158                 nIllegal++;
00159             }
00160         }
00161     }
00162 
00163     return nIllegal;
00164 }
00165 
00166 
00167 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00168 
00169 // Construct from components
00170 template<class TransferType>
00171 Foam::patchDataWave<TransferType>::patchDataWave
00172 (
00173     const polyMesh& mesh,
00174     const labelHashSet& patchIDs,
00175     const UPtrList<Field<Type> >& initialPatchValuePtrs,
00176     const bool correctWalls
00177 )
00178 :
00179     cellDistFuncs(mesh),
00180     patchIDs_(patchIDs),
00181     initialPatchValuePtrs_(initialPatchValuePtrs),
00182     correctWalls_(correctWalls),
00183     nUnset_(0),
00184     distance_(mesh.nCells()),
00185     patchDistance_(mesh.boundaryMesh().size()),
00186     cellData_(mesh.nCells()),
00187     patchData_(mesh.boundaryMesh().size())
00188 {
00189     patchDataWave<TransferType>::correct();
00190 }
00191 
00192 
00193 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00194 
00195 template<class TransferType>
00196 Foam::patchDataWave<TransferType>::~patchDataWave()
00197 {}
00198 
00199 
00200 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00201 
00202 // Correct for mesh geom/topo changes
00203 template<class TransferType>
00204 void Foam::patchDataWave<TransferType>::correct()
00205 {
00206     //
00207     // Set initial changed faces: set TransferType for wall faces
00208     // to wall centre.
00209     //
00210 
00211     // Count walls
00212     label nWalls = sumPatchSize(patchIDs_);
00213 
00214     List<TransferType> faceDist(nWalls);
00215     labelList changedFaces(nWalls);
00216 
00217     setChangedFaces(patchIDs_, changedFaces, faceDist);
00218 
00219     //
00220     // Do calculate wall distance by 'growing' from faces.
00221     //
00222 
00223     MeshWave<TransferType> waveInfo
00224     (
00225         mesh(),
00226         changedFaces,
00227         faceDist,
00228         mesh().globalData().nTotalCells() // max iterations
00229     );
00230 
00231 
00232     //
00233     // Copy distance into return field
00234     //
00235 
00236     nUnset_ = getValues(waveInfo);
00237 
00238     //
00239     // Correct wall cells for true distance
00240     //
00241 
00242     if (correctWalls_)
00243     {
00244         Map<label> nearestFace(2 * nWalls);
00245 
00246         // Get distance and indices of nearest face
00247         correctBoundaryFaceCells
00248         (
00249             patchIDs_,
00250             distance_,
00251             nearestFace
00252         );
00253 
00254         correctBoundaryPointCells
00255         (
00256             patchIDs_,
00257             distance_,
00258             nearestFace
00259         );
00260 
00261         // Transfer data from nearest face to cell
00262         const List<TransferType>& faceInfo = waveInfo.allFaceInfo();
00263 
00264         const labelList wallCells(nearestFace.toc());
00265 
00266         forAll(wallCells, wallCellI)
00267         {
00268             label cellI = wallCells[wallCellI];
00269 
00270             label faceI = nearestFace[cellI];
00271 
00272             cellData_[cellI] = faceInfo[faceI].data();
00273         }
00274     }
00275 }
00276 
00277 
00278 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines