1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. 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
162 oldPatchSizes[patchI],
167 // Create new patchField with same type as existing one.
169 // - boundaryField already in new order so access with newPatchI
170 // - fld.boundaryField()[newPatchI] both used for type and old
172 // - hope that field mapping allows aliasing since old and new
174 fld.boundaryField().set
177 fvPatchField<Type>::New
179 fld.boundaryField()[newPatchI], // old field
180 mesh.boundary()[newPatchI], // new fvPatch
181 fld.dimensionedInternalField(), // new internal field
182 patchMapper // mapper (new to old)
191 // Patch fields from added mesh
192 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195 const labelList& addedPatchMap = meshMap.addedPatchMap();
197 // Add addedMesh patches
198 forAll(addedPatchMap, patchI)
200 label newPatchI = addedPatchMap[patchI];
204 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
205 const polyPatch& oldPatch =
206 fldToAdd.mesh().boundaryMesh()[patchI];
208 if (!fld.boundaryField()(newPatchI))
210 // First occurrence of newPatchI. Map from existing
213 // From new patch faces to patch faces on added mesh.
220 meshMap.addedFaceMap(),
226 directFvPatchFieldMapper patchMapper
232 fld.boundaryField().set
235 fvPatchField<Type>::New
237 fldToAdd.boundaryField()[patchI], // added field
238 mesh.boundary()[newPatchI], // new fvPatch
239 fld.dimensionedInternalField(), // new int. field
240 patchMapper // mapper
246 // PatchField will have correct size already. Just slot in
249 // From new patch faces to patch faces on added mesh. This
250 // time keep unmapped elements -1.
257 meshMap.addedFaceMap(),
259 -1 // unmapped values
263 const fvPatchField<Type>& addedFld =
264 fldToAdd.boundaryField()[patchI];
266 fvPatchField<Type>& newFld = fld.boundaryField()[newPatchI];
270 label oldFaceI = newToAdded[i];
272 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
274 newFld[i] = addedFld[oldFaceI];
285 void Foam::fvMeshAdder::MapVolFields
287 const mapAddedPolyMesh& meshMap,
289 const fvMesh& meshToAdd
292 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fields
294 mesh.objectRegistry::lookupClass
295 <GeometricField<Type, fvPatchField, volMesh> >
299 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fieldsToAdd
301 meshToAdd.objectRegistry::lookupClass
302 <GeometricField<Type, fvPatchField, volMesh> >
306 // It is necessary to enforce that all old-time fields are stored
307 // before the mapping is performed. Otherwise, if the
308 // old-time-level field is mapped before the field itself, sizes
313 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
314 iterator fieldIter = fields.begin();
315 fieldIter != fields.end();
319 const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
326 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
327 iterator fieldIter = fields.begin();
328 fieldIter != fields.end();
332 GeometricField<Type, fvPatchField, volMesh>& fld =
333 const_cast<GeometricField<Type, fvPatchField, volMesh>&>
338 if (fieldsToAdd.found(fld.name()))
340 Pout<< "Mapping field " << fld.name() << endl;
342 const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
343 *fieldsToAdd[fld.name()];
345 MapVolField<Type>(meshMap, fld, fldToAdd);
349 WarningIn("fvMeshAdder::MapVolFields")
350 << "Not mapping field " << fld.name()
351 << " since not present on mesh to add"
359 void Foam::fvMeshAdder::MapSurfaceField
361 const mapAddedPolyMesh& meshMap,
363 GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
364 const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd
367 const fvMesh& mesh = fld.mesh();
368 const labelList& oldPatchStarts = meshMap.oldPatchStarts();
373 // Store old internal field
375 Field<Type> oldField(fld);
377 // Modify internal field
378 Field<Type>& intFld = fld.internalField();
380 intFld.setSize(mesh.nInternalFaces());
382 map(oldField, meshMap.oldFaceMap(), intFld);
383 map(fldToAdd, meshMap.addedFaceMap(), intFld);
385 // Faces that were boundary faces but are not anymore.
386 // Use owner value (so lowest numbered cell, i.e. from 'old' not 'added'
388 forAll(fld.boundaryField(), patchI)
390 const fvsPatchField<Type>& pf = fld.boundaryField()[patchI];
392 label start = oldPatchStarts[patchI];
396 label newFaceI = meshMap.oldFaceMap()[start + i];
398 if (newFaceI >= 0 && newFaceI < mesh.nInternalFaces())
400 intFld[newFaceI] = pf[i];
407 // Patch fields from old mesh
408 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
411 const labelList& oldPatchMap = meshMap.oldPatchMap();
412 const labelList& oldPatchSizes = meshMap.oldPatchSizes();
414 // Reorder old patches in order of new ones. Put removed patches at end.
416 label unusedPatchI = 0;
418 forAll(oldPatchMap, patchI)
420 label newPatchI = oldPatchMap[patchI];
428 label nUsedPatches = unusedPatchI;
430 // Reorder list for patchFields
431 labelList oldToNew(oldPatchMap.size());
433 forAll(oldPatchMap, patchI)
435 label newPatchI = oldPatchMap[patchI];
439 oldToNew[patchI] = newPatchI;
443 oldToNew[patchI] = unusedPatchI++;
448 // Sort deleted ones last so is now in newPatch ordering
449 fld.boundaryField().reorder(oldToNew);
450 // Extend to covers all patches
451 fld.boundaryField().setSize(mesh.boundaryMesh().size());
452 // Delete unused patches
455 label newPatchI = nUsedPatches;
456 newPatchI < fld.boundaryField().size();
460 fld.boundaryField().set(newPatchI, NULL);
467 forAll(oldPatchMap, patchI)
469 label newPatchI = oldPatchMap[patchI];
477 oldPatchStarts[patchI],
478 oldPatchSizes[patchI],
479 meshMap.oldFaceMap(),
480 mesh.boundaryMesh()[newPatchI],
485 directFvPatchFieldMapper patchMapper
487 oldPatchSizes[patchI],
492 // Create new patchField with same type as existing one.
494 // - boundaryField already in new order so access with newPatchI
495 // - fld.boundaryField()[newPatchI] both used for type and old
497 // - hope that field mapping allows aliasing since old and new
499 fld.boundaryField().set
502 fvsPatchField<Type>::New
504 fld.boundaryField()[newPatchI], // old field
505 mesh.boundary()[newPatchI], // new fvPatch
506 fld.dimensionedInternalField(), // new internal field
507 patchMapper // mapper (new to old)
516 // Patch fields from added mesh
517 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520 const labelList& addedPatchMap = meshMap.addedPatchMap();
522 // Add addedMesh patches
523 forAll(addedPatchMap, patchI)
525 label newPatchI = addedPatchMap[patchI];
529 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
530 const polyPatch& oldPatch =
531 fldToAdd.mesh().boundaryMesh()[patchI];
533 if (!fld.boundaryField()(newPatchI))
535 // First occurrence of newPatchI. Map from existing
538 // From new patch faces to patch faces on added mesh.
545 meshMap.addedFaceMap(),
551 directFvPatchFieldMapper patchMapper
557 fld.boundaryField().set
560 fvsPatchField<Type>::New
562 fldToAdd.boundaryField()[patchI],// added field
563 mesh.boundary()[newPatchI], // new fvPatch
564 fld.dimensionedInternalField(), // new int. field
565 patchMapper // mapper
571 // PatchField will have correct size already. Just slot in
574 // From new patch faces to patch faces on added mesh. This
575 // time keep unmapped elements -1.
582 meshMap.addedFaceMap(),
584 -1 // unmapped values
588 const fvsPatchField<Type>& addedFld =
589 fldToAdd.boundaryField()[patchI];
591 fvsPatchField<Type>& newFld =
592 fld.boundaryField()[newPatchI];
596 label oldFaceI = newToAdded[i];
598 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
600 newFld[i] = addedFld[oldFaceI];
611 void Foam::fvMeshAdder::MapSurfaceFields
613 const mapAddedPolyMesh& meshMap,
615 const fvMesh& meshToAdd
618 typedef GeometricField<Type, fvsPatchField, surfaceMesh> fldType;
620 HashTable<const fldType*> fields
622 mesh.objectRegistry::lookupClass<fldType>()
625 HashTable<const fldType*> fieldsToAdd
627 meshToAdd.objectRegistry::lookupClass<fldType>()
630 // It is necessary to enforce that all old-time fields are stored
631 // before the mapping is performed. Otherwise, if the
632 // old-time-level field is mapped before the field itself, sizes
637 typename HashTable<const fldType*>::
638 iterator fieldIter = fields.begin();
639 fieldIter != fields.end();
643 const_cast<fldType*>(fieldIter())
650 typename HashTable<const fldType*>::
651 iterator fieldIter = fields.begin();
652 fieldIter != fields.end();
656 fldType& fld = const_cast<fldType&>(*fieldIter());
658 if (fieldsToAdd.found(fld.name()))
660 Pout<< "Mapping field " << fld.name() << endl;
662 const fldType& fldToAdd = *fieldsToAdd[fld.name()];
664 MapSurfaceField<Type>(meshMap, fld, fldToAdd);
668 WarningIn("fvMeshAdder::MapSurfaceFields")
669 << "Not mapping field " << fld.name()
670 << " since not present on mesh to add"
677 // ************************************************************************* //