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

fvMeshAdderTemplates.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 
00027 #include <finiteVolume/volFields.H>
00028 #include <finiteVolume/surfaceFields.H>
00029 #include <finiteVolume/emptyFvPatchField.H>
00030 
00031 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00032 
00033 template<class Type>
00034 void Foam::fvMeshAdder::map
00035 (
00036     const Field<Type>& oldFld,
00037     const labelList& oldToNew,
00038     Field<Type>& fld
00039 )
00040 {
00041     forAll(oldFld, cellI)
00042     {
00043         label newCellI = oldToNew[cellI];
00044 
00045         if (newCellI >= 0 && newCellI < fld.size())
00046         {
00047             fld[newCellI] = oldFld[cellI];
00048         }
00049     }
00050 }
00051 
00052 
00053 template<class Type>
00054 void Foam::fvMeshAdder::MapVolField
00055 (
00056     const mapAddedPolyMesh& meshMap,
00057 
00058     GeometricField<Type, fvPatchField, volMesh>& fld,
00059     const GeometricField<Type, fvPatchField, volMesh>& fldToAdd
00060 )
00061 {
00062     const fvMesh& mesh = fld.mesh();
00063 
00064     // Internal field
00065     // ~~~~~~~~~~~~~~
00066 
00067     {
00068         // Store old internal field
00069         Field<Type> oldInternalField(fld.internalField());
00070 
00071         // Modify internal field
00072         Field<Type>& intFld = fld.internalField();
00073 
00074         intFld.setSize(mesh.nCells());
00075 
00076         map(oldInternalField, meshMap.oldCellMap(), intFld);
00077         map(fldToAdd.internalField(), meshMap.addedCellMap(), intFld);
00078     }
00079 
00080 
00081     // Patch fields from old mesh
00082     // ~~~~~~~~~~~~~~~~~~~~~~~~~~
00083 
00084     {
00085         const labelList& oldPatchMap = meshMap.oldPatchMap();
00086         const labelList& oldPatchStarts = meshMap.oldPatchStarts();
00087         const labelList& oldPatchSizes = meshMap.oldPatchSizes();
00088 
00089         // Reorder old patches in order of new ones. Put removed patches at end.
00090 
00091         label unusedPatchI = 0;
00092 
00093         forAll(oldPatchMap, patchI)
00094         {
00095             label newPatchI = oldPatchMap[patchI];
00096 
00097             if (newPatchI != -1)
00098             {
00099                 unusedPatchI++;
00100             }
00101         }
00102 
00103         label nUsedPatches = unusedPatchI;
00104 
00105         // Reorder list for patchFields
00106         labelList oldToNew(oldPatchMap.size());
00107 
00108         forAll(oldPatchMap, patchI)
00109         {
00110             label newPatchI = oldPatchMap[patchI];
00111 
00112             if (newPatchI != -1)
00113             {
00114                 oldToNew[patchI] = newPatchI;
00115             }
00116             else
00117             {
00118                 oldToNew[patchI] = unusedPatchI++;
00119             }
00120         }
00121 
00122 
00123         // Sort deleted ones last so is now in newPatch ordering
00124         fld.boundaryField().reorder(oldToNew);
00125         // Extend to covers all patches
00126         fld.boundaryField().setSize(mesh.boundaryMesh().size());
00127         // Delete unused patches
00128         for
00129         (
00130             label newPatchI = nUsedPatches;
00131             newPatchI < fld.boundaryField().size();
00132             newPatchI++
00133         )
00134         {
00135             fld.boundaryField().set(newPatchI, NULL);
00136         }
00137 
00138 
00139         // Map old values
00140         // ~~~~~~~~~~~~~~
00141 
00142         forAll(oldPatchMap, patchI)
00143         {
00144             label newPatchI = oldPatchMap[patchI];
00145 
00146             if (newPatchI != -1)
00147             {
00148                 labelList newToOld
00149                 (   
00150                     calcPatchMap
00151                     (
00152                         oldPatchStarts[patchI],
00153                         oldPatchSizes[patchI],
00154                         meshMap.oldFaceMap(),
00155                         mesh.boundaryMesh()[newPatchI],
00156                         0                   // unmapped value
00157                     )
00158                 );
00159 
00160                 directFvPatchFieldMapper patchMapper(newToOld);
00161 
00162 
00163                 // Create new patchField with same type as existing one.
00164                 // Note:
00165                 // - boundaryField already in new order so access with newPatchI
00166                 // - fld.boundaryField()[newPatchI] both used for type and old
00167                 //   value
00168                 // - hope that field mapping allows aliasing since old and new
00169                 //   are same memory!
00170                 fld.boundaryField().set
00171                 (
00172                     newPatchI,
00173                     fvPatchField<Type>::New
00174                     (
00175                         fld.boundaryField()[newPatchI], // old field
00176                         mesh.boundary()[newPatchI],     // new fvPatch
00177                         fld.dimensionedInternalField(), // new internal field
00178                         patchMapper                     // mapper (new to old)
00179                     )
00180                 );
00181             }
00182         }
00183     }
00184 
00185 
00186 
00187     // Patch fields from added mesh
00188     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00189 
00190     {
00191         const labelList& addedPatchMap = meshMap.addedPatchMap();
00192 
00193         // Add addedMesh patches
00194         forAll(addedPatchMap, patchI)
00195         {
00196             label newPatchI = addedPatchMap[patchI];
00197 
00198             if (newPatchI != -1)
00199             {
00200                 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
00201                 const polyPatch& oldPatch =
00202                     fldToAdd.mesh().boundaryMesh()[patchI];
00203 
00204                 if (!fld.boundaryField()(newPatchI))
00205                 {
00206                     // First occurrence of newPatchI. Map from existing
00207                     // patchField
00208 
00209                     // From new patch faces to patch faces on added mesh.
00210                     labelList newToAdded
00211                     (   
00212                         calcPatchMap
00213                         (
00214                             oldPatch.start(),
00215                             oldPatch.size(),
00216                             meshMap.addedFaceMap(),
00217                             newPatch,
00218                             0                       // unmapped values
00219                         )
00220                     );
00221 
00222                     directFvPatchFieldMapper patchMapper(newToAdded);
00223 
00224                     fld.boundaryField().set
00225                     (
00226                         newPatchI,
00227                         fvPatchField<Type>::New
00228                         (
00229                             fldToAdd.boundaryField()[patchI], // added field
00230                             mesh.boundary()[newPatchI],       // new fvPatch
00231                             fld.dimensionedInternalField(),   // new int. field
00232                             patchMapper                       // mapper
00233                         )
00234                     );
00235                 }
00236                 else
00237                 {
00238                     // PatchField will have correct size already. Just slot in
00239                     // my elements.
00240 
00241                     // From new patch faces to patch faces on added mesh. This
00242                     // time keep unmapped elements -1.
00243                     labelList newToAdded
00244                     (   
00245                         calcPatchMap
00246                         (
00247                             oldPatch.start(),
00248                             oldPatch.size(),
00249                             meshMap.addedFaceMap(),
00250                             newPatch,
00251                             -1                      // unmapped values
00252                         )
00253                     );
00254 
00255                     const fvPatchField<Type>& addedFld =
00256                         fldToAdd.boundaryField()[patchI];
00257 
00258                     fvPatchField<Type>& newFld = fld.boundaryField()[newPatchI];
00259 
00260                     forAll(newFld, i)
00261                     {
00262                         label oldFaceI = newToAdded[i];
00263 
00264                         if (oldFaceI >= 0 && oldFaceI < addedFld.size())
00265                         {
00266                             newFld[i] = addedFld[oldFaceI];
00267                         }
00268                     }
00269                 }
00270             }
00271         }
00272     }
00273 }
00274 
00275 
00276 template<class Type>
00277 void Foam::fvMeshAdder::MapVolFields
00278 (
00279     const mapAddedPolyMesh& meshMap,
00280     const fvMesh& mesh,
00281     const fvMesh& meshToAdd
00282 )
00283 {
00284     HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fields
00285     (
00286         mesh.objectRegistry::lookupClass
00287         <GeometricField<Type, fvPatchField, volMesh> >
00288         ()
00289     );
00290 
00291     HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fieldsToAdd
00292     (
00293         meshToAdd.objectRegistry::lookupClass
00294         <GeometricField<Type, fvPatchField, volMesh> >
00295         ()
00296     );
00297 
00298     // It is necessary to enforce that all old-time fields are stored
00299     // before the mapping is performed.  Otherwise, if the
00300     // old-time-level field is mapped before the field itself, sizes
00301     // will not match.  
00302 
00303     for
00304     (
00305         typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
00306             iterator fieldIter = fields.begin();
00307         fieldIter != fields.end();
00308         ++fieldIter
00309     )
00310     {
00311         const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
00312             ->storeOldTimes();
00313     }
00314 
00315 
00316     for
00317     (
00318         typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
00319             iterator fieldIter = fields.begin();
00320         fieldIter != fields.end();
00321         ++fieldIter
00322     )
00323     {
00324         GeometricField<Type, fvPatchField, volMesh>& fld =
00325             const_cast<GeometricField<Type, fvPatchField, volMesh>&>
00326             (
00327                 *fieldIter()
00328             );
00329 
00330         if (fieldsToAdd.found(fld.name()))
00331         {
00332             Pout<< "Mapping field " << fld.name() << endl;
00333 
00334             const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
00335                 *fieldsToAdd[fld.name()];
00336 
00337             MapVolField<Type>(meshMap, fld, fldToAdd);
00338         }
00339         else
00340         {
00341             WarningIn("fvMeshAdder::MapVolFields")
00342                 << "Not mapping field " << fld.name()
00343                 << " since not present on mesh to add"
00344                 << endl;
00345         }
00346     }
00347 }
00348 
00349 
00350 template<class Type>
00351 void Foam::fvMeshAdder::MapSurfaceField
00352 (
00353     const mapAddedPolyMesh& meshMap,
00354 
00355     GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
00356     const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd
00357 )
00358 {
00359     const fvMesh& mesh = fld.mesh();
00360     const labelList& oldPatchStarts = meshMap.oldPatchStarts();
00361 
00362     // Internal field
00363     // ~~~~~~~~~~~~~~
00364 
00365     // Store old internal field
00366     {
00367         Field<Type> oldField(fld);
00368 
00369         // Modify internal field
00370         Field<Type>& intFld = fld.internalField();
00371 
00372         intFld.setSize(mesh.nInternalFaces());
00373 
00374         map(oldField, meshMap.oldFaceMap(), intFld);
00375         map(fldToAdd, meshMap.addedFaceMap(), intFld);
00376 
00377         // Faces that were boundary faces but are not anymore.
00378         // Use owner value (so lowest numbered cell, i.e. from 'old' not 'added'
00379         // mesh)
00380         forAll(fld.boundaryField(), patchI)
00381         {
00382             const fvsPatchField<Type>& pf = fld.boundaryField()[patchI];
00383 
00384             label start = oldPatchStarts[patchI];
00385 
00386             forAll(pf, i)
00387             {
00388                 label newFaceI = meshMap.oldFaceMap()[start + i];
00389 
00390                 if (newFaceI >= 0 && newFaceI < mesh.nInternalFaces())
00391                 {
00392                     intFld[newFaceI] = pf[i];
00393                 }
00394             }
00395         }
00396     }
00397 
00398 
00399     // Patch fields from old mesh
00400     // ~~~~~~~~~~~~~~~~~~~~~~~~~~
00401 
00402     {
00403         const labelList& oldPatchMap = meshMap.oldPatchMap();
00404         const labelList& oldPatchSizes = meshMap.oldPatchSizes();
00405 
00406         // Reorder old patches in order of new ones. Put removed patches at end.
00407 
00408         label unusedPatchI = 0;
00409 
00410         forAll(oldPatchMap, patchI)
00411         {
00412             label newPatchI = oldPatchMap[patchI];
00413 
00414             if (newPatchI != -1)
00415             {
00416                 unusedPatchI++;
00417             }
00418         }
00419 
00420         label nUsedPatches = unusedPatchI;
00421 
00422         // Reorder list for patchFields
00423         labelList oldToNew(oldPatchMap.size());
00424 
00425         forAll(oldPatchMap, patchI)
00426         {
00427             label newPatchI = oldPatchMap[patchI];
00428 
00429             if (newPatchI != -1)
00430             {
00431                 oldToNew[patchI] = newPatchI;
00432             }
00433             else
00434             {
00435                 oldToNew[patchI] = unusedPatchI++;
00436             }
00437         }
00438 
00439 
00440         // Sort deleted ones last so is now in newPatch ordering
00441         fld.boundaryField().reorder(oldToNew);
00442         // Extend to covers all patches
00443         fld.boundaryField().setSize(mesh.boundaryMesh().size());
00444         // Delete unused patches
00445         for
00446         (
00447             label newPatchI = nUsedPatches;
00448             newPatchI < fld.boundaryField().size();
00449             newPatchI++
00450         )
00451         {
00452             fld.boundaryField().set(newPatchI, NULL);
00453         }
00454 
00455 
00456         // Map old values
00457         // ~~~~~~~~~~~~~~
00458 
00459         forAll(oldPatchMap, patchI)
00460         {
00461             label newPatchI = oldPatchMap[patchI];
00462 
00463             if (newPatchI != -1)
00464             {
00465                 labelList newToOld
00466                 (   
00467                     calcPatchMap
00468                     (
00469                         oldPatchStarts[patchI],
00470                         oldPatchSizes[patchI],
00471                         meshMap.oldFaceMap(),
00472                         mesh.boundaryMesh()[newPatchI],
00473                         0                   // unmapped value
00474                     )
00475                 );
00476 
00477                 directFvPatchFieldMapper patchMapper(newToOld);
00478 
00479 
00480                 // Create new patchField with same type as existing one.
00481                 // Note:
00482                 // - boundaryField already in new order so access with newPatchI
00483                 // - fld.boundaryField()[newPatchI] both used for type and old
00484                 //   value
00485                 // - hope that field mapping allows aliasing since old and new
00486                 //   are same memory!
00487                 fld.boundaryField().set
00488                 (
00489                     newPatchI,
00490                     fvsPatchField<Type>::New
00491                     (
00492                         fld.boundaryField()[newPatchI], // old field
00493                         mesh.boundary()[newPatchI],     // new fvPatch
00494                         fld.dimensionedInternalField(), // new internal field
00495                         patchMapper                     // mapper (new to old)
00496                     )
00497                 );
00498             }
00499         }
00500     }
00501 
00502 
00503 
00504     // Patch fields from added mesh
00505     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00506 
00507     {
00508         const labelList& addedPatchMap = meshMap.addedPatchMap();
00509 
00510         // Add addedMesh patches
00511         forAll(addedPatchMap, patchI)
00512         {
00513             label newPatchI = addedPatchMap[patchI];
00514 
00515             if (newPatchI != -1)
00516             {
00517                 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
00518                 const polyPatch& oldPatch =
00519                     fldToAdd.mesh().boundaryMesh()[patchI];
00520 
00521                 if (!fld.boundaryField()(newPatchI))
00522                 {
00523                     // First occurrence of newPatchI. Map from existing
00524                     // patchField
00525 
00526                     // From new patch faces to patch faces on added mesh.
00527                     labelList newToAdded
00528                     (   
00529                         calcPatchMap
00530                         (
00531                             oldPatch.start(),
00532                             oldPatch.size(),
00533                             meshMap.addedFaceMap(),
00534                             newPatch,
00535                             0                       // unmapped values
00536                         )
00537                     );
00538 
00539                     directFvPatchFieldMapper patchMapper(newToAdded);
00540 
00541                     fld.boundaryField().set
00542                     (
00543                         newPatchI,
00544                         fvsPatchField<Type>::New
00545                         (
00546                             fldToAdd.boundaryField()[patchI],// added field
00547                             mesh.boundary()[newPatchI],      // new fvPatch
00548                             fld.dimensionedInternalField(),  // new int. field
00549                             patchMapper                      // mapper
00550                         )
00551                     );
00552                 }
00553                 else
00554                 {
00555                     // PatchField will have correct size already. Just slot in
00556                     // my elements.
00557 
00558                     // From new patch faces to patch faces on added mesh. This
00559                     // time keep unmapped elements -1.
00560                     labelList newToAdded
00561                     (   
00562                         calcPatchMap
00563                         (
00564                             oldPatch.start(),
00565                             oldPatch.size(),
00566                             meshMap.addedFaceMap(),
00567                             newPatch,
00568                             -1                      // unmapped values
00569                         )
00570                     );
00571 
00572                     const fvsPatchField<Type>& addedFld =
00573                         fldToAdd.boundaryField()[patchI];
00574 
00575                     fvsPatchField<Type>& newFld =
00576                         fld.boundaryField()[newPatchI];
00577 
00578                     forAll(newFld, i)
00579                     {
00580                         label oldFaceI = newToAdded[i];
00581 
00582                         if (oldFaceI >= 0 && oldFaceI < addedFld.size())
00583                         {
00584                             newFld[i] = addedFld[oldFaceI];
00585                         }
00586                     }
00587                 }
00588             }
00589         }
00590     }
00591 }
00592 
00593 
00594 template<class Type>
00595 void Foam::fvMeshAdder::MapSurfaceFields
00596 (
00597     const mapAddedPolyMesh& meshMap,
00598     const fvMesh& mesh,
00599     const fvMesh& meshToAdd
00600 )
00601 {
00602     typedef GeometricField<Type, fvsPatchField, surfaceMesh> fldType;
00603 
00604     HashTable<const fldType*> fields
00605     (
00606         mesh.objectRegistry::lookupClass<fldType>()
00607     );
00608 
00609     HashTable<const fldType*> fieldsToAdd
00610     (
00611         meshToAdd.objectRegistry::lookupClass<fldType>()
00612     );
00613 
00614     // It is necessary to enforce that all old-time fields are stored
00615     // before the mapping is performed.  Otherwise, if the
00616     // old-time-level field is mapped before the field itself, sizes
00617     // will not match.  
00618 
00619     for
00620     (
00621         typename HashTable<const fldType*>::
00622             iterator fieldIter = fields.begin();
00623         fieldIter != fields.end();
00624         ++fieldIter
00625     )
00626     {
00627         const_cast<fldType*>(fieldIter())
00628             ->storeOldTimes();
00629     }
00630 
00631 
00632     for
00633     (
00634         typename HashTable<const fldType*>::
00635             iterator fieldIter = fields.begin();
00636         fieldIter != fields.end();
00637         ++fieldIter
00638     )
00639     {
00640         fldType& fld = const_cast<fldType&>(*fieldIter());
00641 
00642         if (fieldsToAdd.found(fld.name()))
00643         {
00644             Pout<< "Mapping field " << fld.name() << endl;
00645 
00646             const fldType& fldToAdd = *fieldsToAdd[fld.name()];
00647 
00648             MapSurfaceField<Type>(meshMap, fld, fldToAdd);
00649         }
00650         else
00651         {
00652             WarningIn("fvMeshAdder::MapSurfaceFields")
00653                 << "Not mapping field " << fld.name()
00654                 << " since not present on mesh to add"
00655                 << endl;
00656         }
00657     }
00658 }
00659 
00660 
00661 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines