1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
27 #include "volFields.H"
28 #include "surfaceFields.H"
29 #include "emptyFvPatchField.H"
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
34 void Foam::fvMeshAdder::map
36 const Field<Type>& oldFld,
37 const labelList& oldToNew,
43 label newCellI = oldToNew[cellI];
45 if (newCellI >= 0 && newCellI < fld.size())
47 fld[newCellI] = oldFld[cellI];
54 void Foam::fvMeshAdder::MapVolField
56 const mapAddedPolyMesh& meshMap,
58 GeometricField<Type, fvPatchField, volMesh>& fld,
59 const GeometricField<Type, fvPatchField, volMesh>& fldToAdd
62 const fvMesh& mesh = fld.mesh();
68 // Store old internal field
69 Field<Type> oldInternalField(fld.internalField());
71 // Modify internal field
72 Field<Type>& intFld = fld.internalField();
74 intFld.setSize(mesh.nCells());
76 map(oldInternalField, meshMap.oldCellMap(), intFld);
77 map(fldToAdd.internalField(), meshMap.addedCellMap(), intFld);
81 // Patch fields from old mesh
82 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
85 const labelList& oldPatchMap = meshMap.oldPatchMap();
86 const labelList& oldPatchStarts = meshMap.oldPatchStarts();
87 const labelList& oldPatchSizes = meshMap.oldPatchSizes();
89 // Reorder old patches in order of new ones. Put removed patches at end.
91 label unusedPatchI = 0;
93 forAll(oldPatchMap, patchI)
95 label newPatchI = oldPatchMap[patchI];
103 label nUsedPatches = unusedPatchI;
105 // Reorder list for patchFields
106 labelList oldToNew(oldPatchMap.size());
108 forAll(oldPatchMap, patchI)
110 label newPatchI = oldPatchMap[patchI];
114 oldToNew[patchI] = newPatchI;
118 oldToNew[patchI] = unusedPatchI++;
123 // Sort deleted ones last so is now in newPatch ordering
124 fld.boundaryField().reorder(oldToNew);
125 // Extend to covers all patches
126 fld.boundaryField().setSize(mesh.boundaryMesh().size());
127 // Delete unused patches
130 label newPatchI = nUsedPatches;
131 newPatchI < fld.boundaryField().size();
135 fld.boundaryField().set(newPatchI, NULL);
142 forAll(oldPatchMap, patchI)
144 label newPatchI = oldPatchMap[patchI];
152 oldPatchStarts[patchI],
153 oldPatchSizes[patchI],
154 meshMap.oldFaceMap(),
155 mesh.boundaryMesh()[newPatchI],
160 directFvPatchFieldMapper patchMapper(newToOld);
163 // Create new patchField with same type as existing one.
165 // - boundaryField already in new order so access with newPatchI
166 // - fld.boundaryField()[newPatchI] both used for type and old
168 // - hope that field mapping allows aliasing since old and new
170 fld.boundaryField().set
173 fvPatchField<Type>::New
175 fld.boundaryField()[newPatchI], // old field
176 mesh.boundary()[newPatchI], // new fvPatch
177 fld.dimensionedInternalField(), // new internal field
178 patchMapper // mapper (new to old)
187 // Patch fields from added mesh
188 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
191 const labelList& addedPatchMap = meshMap.addedPatchMap();
193 // Add addedMesh patches
194 forAll(addedPatchMap, patchI)
196 label newPatchI = addedPatchMap[patchI];
200 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
201 const polyPatch& oldPatch =
202 fldToAdd.mesh().boundaryMesh()[patchI];
204 if (!fld.boundaryField()(newPatchI))
206 // First occurrence of newPatchI. Map from existing
209 // From new patch faces to patch faces on added mesh.
216 meshMap.addedFaceMap(),
222 directFvPatchFieldMapper patchMapper(newToAdded);
224 fld.boundaryField().set
227 fvPatchField<Type>::New
229 fldToAdd.boundaryField()[patchI], // added field
230 mesh.boundary()[newPatchI], // new fvPatch
231 fld.dimensionedInternalField(), // new int. field
232 patchMapper // mapper
238 // PatchField will have correct size already. Just slot in
241 // From new patch faces to patch faces on added mesh. This
242 // time keep unmapped elements -1.
249 meshMap.addedFaceMap(),
251 -1 // unmapped values
255 const fvPatchField<Type>& addedFld =
256 fldToAdd.boundaryField()[patchI];
258 fvPatchField<Type>& newFld = fld.boundaryField()[newPatchI];
262 label oldFaceI = newToAdded[i];
264 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
266 newFld[i] = addedFld[oldFaceI];
277 void Foam::fvMeshAdder::MapVolFields
279 const mapAddedPolyMesh& meshMap,
281 const fvMesh& meshToAdd
284 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fields
286 mesh.objectRegistry::lookupClass
287 <GeometricField<Type, fvPatchField, volMesh> >
291 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fieldsToAdd
293 meshToAdd.objectRegistry::lookupClass
294 <GeometricField<Type, fvPatchField, volMesh> >
298 // It is necessary to enforce that all old-time fields are stored
299 // before the mapping is performed. Otherwise, if the
300 // old-time-level field is mapped before the field itself, sizes
305 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
306 iterator fieldIter = fields.begin();
307 fieldIter != fields.end();
311 const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
318 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
319 iterator fieldIter = fields.begin();
320 fieldIter != fields.end();
324 GeometricField<Type, fvPatchField, volMesh>& fld =
325 const_cast<GeometricField<Type, fvPatchField, volMesh>&>
330 if (fieldsToAdd.found(fld.name()))
332 const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
333 *fieldsToAdd[fld.name()];
335 MapVolField<Type>(meshMap, fld, fldToAdd);
339 WarningIn("fvMeshAdder::MapVolFields(..)")
340 << "Not mapping field " << fld.name()
341 << " since not present on mesh to add"
349 void Foam::fvMeshAdder::MapSurfaceField
351 const mapAddedPolyMesh& meshMap,
353 GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
354 const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd
357 const fvMesh& mesh = fld.mesh();
358 const labelList& oldPatchStarts = meshMap.oldPatchStarts();
363 // Store old internal field
365 Field<Type> oldField(fld);
367 // Modify internal field
368 Field<Type>& intFld = fld.internalField();
370 intFld.setSize(mesh.nInternalFaces());
372 map(oldField, meshMap.oldFaceMap(), intFld);
373 map(fldToAdd, meshMap.addedFaceMap(), intFld);
375 // Faces that were boundary faces but are not anymore.
376 // Use owner value (so lowest numbered cell, i.e. from 'old' not 'added'
378 forAll(fld.boundaryField(), patchI)
380 const fvsPatchField<Type>& pf = fld.boundaryField()[patchI];
382 label start = oldPatchStarts[patchI];
386 label newFaceI = meshMap.oldFaceMap()[start + i];
388 if (newFaceI >= 0 && newFaceI < mesh.nInternalFaces())
390 intFld[newFaceI] = pf[i];
397 // Patch fields from old mesh
398 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
401 const labelList& oldPatchMap = meshMap.oldPatchMap();
402 const labelList& oldPatchSizes = meshMap.oldPatchSizes();
404 // Reorder old patches in order of new ones. Put removed patches at end.
406 label unusedPatchI = 0;
408 forAll(oldPatchMap, patchI)
410 label newPatchI = oldPatchMap[patchI];
418 label nUsedPatches = unusedPatchI;
420 // Reorder list for patchFields
421 labelList oldToNew(oldPatchMap.size());
423 forAll(oldPatchMap, patchI)
425 label newPatchI = oldPatchMap[patchI];
429 oldToNew[patchI] = newPatchI;
433 oldToNew[patchI] = unusedPatchI++;
438 // Sort deleted ones last so is now in newPatch ordering
439 fld.boundaryField().reorder(oldToNew);
440 // Extend to covers all patches
441 fld.boundaryField().setSize(mesh.boundaryMesh().size());
442 // Delete unused patches
445 label newPatchI = nUsedPatches;
446 newPatchI < fld.boundaryField().size();
450 fld.boundaryField().set(newPatchI, NULL);
457 forAll(oldPatchMap, patchI)
459 label newPatchI = oldPatchMap[patchI];
467 oldPatchStarts[patchI],
468 oldPatchSizes[patchI],
469 meshMap.oldFaceMap(),
470 mesh.boundaryMesh()[newPatchI],
475 directFvPatchFieldMapper patchMapper(newToOld);
478 // Create new patchField with same type as existing one.
480 // - boundaryField already in new order so access with newPatchI
481 // - fld.boundaryField()[newPatchI] both used for type and old
483 // - hope that field mapping allows aliasing since old and new
485 fld.boundaryField().set
488 fvsPatchField<Type>::New
490 fld.boundaryField()[newPatchI], // old field
491 mesh.boundary()[newPatchI], // new fvPatch
492 fld.dimensionedInternalField(), // new internal field
493 patchMapper // mapper (new to old)
502 // Patch fields from added mesh
503 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
506 const labelList& addedPatchMap = meshMap.addedPatchMap();
508 // Add addedMesh patches
509 forAll(addedPatchMap, patchI)
511 label newPatchI = addedPatchMap[patchI];
515 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
516 const polyPatch& oldPatch =
517 fldToAdd.mesh().boundaryMesh()[patchI];
519 if (!fld.boundaryField()(newPatchI))
521 // First occurrence of newPatchI. Map from existing
524 // From new patch faces to patch faces on added mesh.
531 meshMap.addedFaceMap(),
537 directFvPatchFieldMapper patchMapper(newToAdded);
539 fld.boundaryField().set
542 fvsPatchField<Type>::New
544 fldToAdd.boundaryField()[patchI],// added field
545 mesh.boundary()[newPatchI], // new fvPatch
546 fld.dimensionedInternalField(), // new int. field
547 patchMapper // mapper
553 // PatchField will have correct size already. Just slot in
556 // From new patch faces to patch faces on added mesh. This
557 // time keep unmapped elements -1.
564 meshMap.addedFaceMap(),
566 -1 // unmapped values
570 const fvsPatchField<Type>& addedFld =
571 fldToAdd.boundaryField()[patchI];
573 fvsPatchField<Type>& newFld =
574 fld.boundaryField()[newPatchI];
578 label oldFaceI = newToAdded[i];
580 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
582 newFld[i] = addedFld[oldFaceI];
593 void Foam::fvMeshAdder::MapSurfaceFields
595 const mapAddedPolyMesh& meshMap,
597 const fvMesh& meshToAdd
600 typedef GeometricField<Type, fvsPatchField, surfaceMesh> fldType;
602 HashTable<const fldType*> fields
604 mesh.objectRegistry::lookupClass<fldType>()
607 HashTable<const fldType*> fieldsToAdd
609 meshToAdd.objectRegistry::lookupClass<fldType>()
612 // It is necessary to enforce that all old-time fields are stored
613 // before the mapping is performed. Otherwise, if the
614 // old-time-level field is mapped before the field itself, sizes
619 typename HashTable<const fldType*>::
620 iterator fieldIter = fields.begin();
621 fieldIter != fields.end();
625 const_cast<fldType*>(fieldIter())
632 typename HashTable<const fldType*>::
633 iterator fieldIter = fields.begin();
634 fieldIter != fields.end();
638 fldType& fld = const_cast<fldType&>(*fieldIter());
640 if (fieldsToAdd.found(fld.name()))
642 const fldType& fldToAdd = *fieldsToAdd[fld.name()];
644 MapSurfaceField<Type>(meshMap, fld, fldToAdd);
648 WarningIn("fvMeshAdder::MapSurfaceFields(..)")
649 << "Not mapping field " << fld.name()
650 << " since not present on mesh to add"
657 // ************************************************************************* //