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

fvMeshSubsetInterpolate.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 "fvMeshSubset.H"
00027 #include <finiteVolume/emptyFvsPatchField.H>
00028 #include <OpenFOAM/emptyPointPatchField.H>
00029 #include <finiteVolume/emptyFvPatchFields.H>
00030 
00031 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00032 
00033 namespace Foam
00034 {
00035 
00036 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00037 
00038 template<class Type>
00039 tmp<GeometricField<Type, fvPatchField, volMesh> > fvMeshSubset::interpolate
00040 (
00041     const GeometricField<Type, fvPatchField, volMesh>& vf,
00042     const fvMesh& sMesh,
00043     const labelList& patchMap,
00044     const labelList& cellMap,
00045     const labelList& faceMap
00046 )
00047 {
00048     // Create and map the internal-field values
00049     Field<Type> internalField(vf.internalField(), cellMap);
00050 
00051     // Create and map the patch field values
00052     PtrList<fvPatchField<Type> > patchFields(patchMap.size());
00053 
00054     forAll (patchFields, patchI)
00055     {
00056         // Set the first one by hand as it corresponds to the
00057         // exposed internal faces.  Additional interpolation can be put here
00058         // as necessary.  
00059         if (patchMap[patchI] == -1)
00060         {
00061             patchFields.set
00062             (
00063                 patchI,
00064                 new emptyFvPatchField<Type>
00065                 (
00066                     sMesh.boundary()[patchI],
00067                     DimensionedField<Type, volMesh>::null()
00068                 )
00069             );
00070         }
00071         else
00072         {
00073             // Construct addressing
00074             const fvPatch& subPatch = sMesh.boundary()[patchI];
00075             const fvPatch& basePatch = vf.mesh().boundary()[patchMap[patchI]];
00076             label baseStart = basePatch.patch().start();
00077             label baseSize = basePatch.size();
00078 
00079             labelList directAddressing(subPatch.size());
00080 
00081             forAll(directAddressing, i)
00082             {
00083                 label baseFaceI = faceMap[subPatch.patch().start()+i];
00084 
00085                 if (baseFaceI >= baseStart && baseFaceI < baseStart+baseSize)
00086                 {
00087                     directAddressing[i] = baseFaceI-baseStart;
00088                 }
00089                 else
00090                 {
00091                     // Mapped from internal face. Do what? Map from element
00092                     // 0 for now.
00093                     directAddressing[i] = 0;
00094                 }
00095             }
00096 
00097             patchFields.set
00098             (
00099                 patchI,
00100                 fvPatchField<Type>::New
00101                 (
00102                     vf.boundaryField()[patchMap[patchI]],
00103                     sMesh.boundary()[patchI],
00104                     DimensionedField<Type, volMesh>::null(),
00105                     patchFieldSubset(directAddressing)
00106                 )
00107             );
00108 
00109             // What to do with exposed internal faces if put into this patch?
00110         }
00111     }
00112 
00113 
00114     // Create the complete field from the pieces
00115     tmp<GeometricField<Type, fvPatchField, volMesh> > tresF
00116     (
00117         new GeometricField<Type, fvPatchField, volMesh>
00118         (
00119             IOobject
00120             (
00121                 "subset"+vf.name(),
00122                 sMesh.time().timeName(),
00123                 sMesh,
00124                 IOobject::NO_READ,
00125                 IOobject::NO_WRITE
00126             ),
00127             sMesh,
00128             vf.dimensions(),
00129             internalField,
00130             patchFields
00131         )
00132     );
00133 
00134     return tresF;
00135 }
00136 
00137 
00138 template<class Type>
00139 tmp<GeometricField<Type, fvPatchField, volMesh> > fvMeshSubset::interpolate
00140 (
00141     const GeometricField<Type, fvPatchField, volMesh>& vf
00142 ) const
00143 {
00144     return interpolate
00145     (
00146         vf,
00147         subMesh(),
00148         patchMap(),
00149         cellMap(),
00150         faceMap()
00151     );
00152 }
00153 
00154 
00155 template<class Type>
00156 tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
00157 (
00158     const GeometricField<Type, fvsPatchField, surfaceMesh>& vf,
00159     const fvMesh& sMesh,
00160     const labelList& patchMap,
00161     const labelList& faceMap
00162 )
00163 {
00164     // Create and map the internal-field values
00165     Field<Type> internalField
00166     (
00167         vf.internalField(),
00168         SubList<label>
00169         (
00170             faceMap,
00171             sMesh.nInternalFaces()
00172         )
00173     );
00174 
00175     // Create and map the patch field values
00176     PtrList<fvsPatchField<Type> > patchFields(patchMap.size());
00177 
00178     forAll (patchFields, patchI)
00179     {
00180         // Set the first one by hand as it corresponds to the
00181         // exposed internal faces.  Additional interpolation can be put here
00182         // as necessary.  
00183         if (patchMap[patchI] == -1)
00184         {
00185             patchFields.set
00186             (
00187                 patchI,
00188                 new emptyFvsPatchField<Type>
00189                 (
00190                     sMesh.boundary()[patchI],
00191                     DimensionedField<Type, surfaceMesh>::null()
00192                 )
00193             );
00194         }
00195         else
00196         {
00197             // Construct addressing
00198             const fvPatch& subPatch = sMesh.boundary()[patchI];
00199             const fvPatch& basePatch = vf.mesh().boundary()[patchMap[patchI]];
00200             label baseStart = basePatch.patch().start();
00201             label baseSize = basePatch.size();
00202 
00203             labelList directAddressing(subPatch.size());
00204 
00205             forAll(directAddressing, i)
00206             {
00207                 label baseFaceI = faceMap[subPatch.patch().start()+i];
00208 
00209                 if (baseFaceI >= baseStart && baseFaceI < baseStart+baseSize)
00210                 {
00211                     directAddressing[i] = baseFaceI-baseStart;
00212                 }
00213                 else
00214                 {
00215                     // Mapped from internal face. Do what? Map from element
00216                     // 0 for now.
00217                     directAddressing[i] = 0;
00218                 }
00219             }
00220 
00221             patchFields.set
00222             (
00223                 patchI,
00224                 fvsPatchField<Type>::New
00225                 (
00226                     vf.boundaryField()[patchMap[patchI]],
00227                     sMesh.boundary()[patchI],
00228                     DimensionedField<Type, surfaceMesh>::null(),
00229                     patchFieldSubset(directAddressing)
00230                 )
00231             );
00232         }
00233     }
00234 
00235 
00236     // Map exposed internal faces. Note: Only nessecary if exposed faces added
00237     // into existing patch but since we don't know that at this point...
00238     forAll(patchFields, patchI)
00239     {
00240         fvsPatchField<Type>& pfld = patchFields[patchI];
00241 
00242         label meshFaceI = pfld.patch().patch().start();
00243 
00244         forAll(pfld, i)
00245         {
00246             label oldFaceI = faceMap[meshFaceI++];
00247 
00248             if (oldFaceI < vf.internalField().size())
00249             {
00250                 pfld[i] = vf.internalField()[oldFaceI];
00251             }
00252         }
00253     }
00254 
00255     // Create the complete field from the pieces
00256     tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > tresF
00257     (
00258         new GeometricField<Type, fvsPatchField, surfaceMesh>
00259         (
00260             IOobject
00261             (
00262                 "subset"+vf.name(),
00263                 sMesh.time().timeName(),
00264                 sMesh,
00265                 IOobject::NO_READ,
00266                 IOobject::NO_WRITE
00267             ),
00268             sMesh,
00269             vf.dimensions(),
00270             internalField,
00271             patchFields
00272         )
00273     );
00274 
00275     return tresF;
00276 }
00277 
00278 
00279 template<class Type>
00280 tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > fvMeshSubset::interpolate
00281 (
00282     const GeometricField<Type, fvsPatchField, surfaceMesh>& sf
00283 ) const
00284 {
00285     return interpolate
00286     (
00287         sf,
00288         subMesh(),
00289         patchMap(),
00290         faceMap()
00291     );
00292 }
00293 
00294 
00295 template<class Type>
00296 tmp<GeometricField<Type, pointPatchField, pointMesh> >
00297 fvMeshSubset::interpolate
00298 (
00299     const GeometricField<Type, pointPatchField, pointMesh>& vf,
00300     const pointMesh& sMesh,
00301     const labelList& patchMap,
00302     const labelList& pointMap
00303 )
00304 {
00305     // Create and map the internal-field values
00306     Field<Type> internalField(vf.internalField(), pointMap);
00307 
00308     // Create and map the patch field values
00309     PtrList<pointPatchField<Type> > patchFields(patchMap.size());
00310 
00311     forAll (patchFields, patchI)
00312     {
00313         // Set the first one by hand as it corresponds to the
00314         // exposed internal faces.  Additional interpolation can be put here
00315         // as necessary.  
00316         if (patchMap[patchI] == -1)
00317         {
00318             patchFields.set
00319             (
00320                 patchI,
00321                 new emptyPointPatchField<Type>
00322                 (
00323                     sMesh.boundary()[patchI],
00324                     DimensionedField<Type, pointMesh>::null()
00325                 )
00326             );
00327         }
00328         else
00329         {
00330             // Construct addressing
00331             const pointPatch& basePatch =
00332                 vf.mesh().boundary()[patchMap[patchI]];
00333 
00334             const labelList& meshPoints = basePatch.meshPoints();
00335 
00336             // Make addressing from mesh to patch point
00337             Map<label> meshPointMap(2*meshPoints.size());
00338             forAll(meshPoints, localI)
00339             {
00340                 meshPointMap.insert(meshPoints[localI], localI);
00341             }
00342 
00343             // Find which subpatch points originate from which patch point
00344             const pointPatch& subPatch = sMesh.boundary()[patchI];
00345             const labelList& subMeshPoints = subPatch.meshPoints();
00346 
00347             // If mapped from outside patch use point 0 for lack of better.
00348             labelList directAddressing(subPatch.size(), 0);
00349 
00350             forAll(subMeshPoints, localI)
00351             {
00352                 // Get mesh point on original mesh.
00353                 label meshPointI = pointMap[subMeshPoints[localI]];
00354 
00355                 Map<label>::const_iterator iter = meshPointMap.find(meshPointI);
00356 
00357                 if (iter != meshPointMap.end())
00358                 {
00359                     directAddressing[localI] = iter();
00360                 }
00361             }
00362 
00363             patchFields.set
00364             (
00365                 patchI,
00366                 pointPatchField<Type>::New
00367                 (
00368                     vf.boundaryField()[patchMap[patchI]],
00369                     subPatch,
00370                     DimensionedField<Type, pointMesh>::null(),
00371                     pointPatchFieldSubset(directAddressing)
00372                 )
00373             );
00374         }
00375     }
00376 
00377     // Create the complete field from the pieces
00378     tmp<GeometricField<Type, pointPatchField, pointMesh> > tresF
00379     (
00380         new GeometricField<Type, pointPatchField, pointMesh>
00381         (
00382             IOobject
00383             (
00384                 "subset"+vf.name(),
00385                 vf.time().timeName(),
00386                 sMesh.thisDb(),
00387                 IOobject::NO_READ,
00388                 IOobject::NO_WRITE
00389             ),
00390             sMesh,
00391             vf.dimensions(),
00392             internalField,
00393             patchFields
00394         )
00395     );
00396 
00397     return tresF;
00398 }
00399 
00400 
00401 template<class Type>
00402 tmp<GeometricField<Type, pointPatchField, pointMesh> > fvMeshSubset::interpolate
00403 (
00404     const GeometricField<Type, pointPatchField, pointMesh>& sf
00405 ) const
00406 {
00407     return interpolate
00408     (
00409         sf,
00410         pointMesh::New(subMesh()),     // subsetted point mesh
00411         patchMap(),
00412         pointMap()
00413     );
00414 }
00415 
00416 
00417 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00418 
00419 } // End namespace Foam
00420 
00421 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines