1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright held by original author
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 the
13 Free Software Foundation; either version 2 of the License, or (at your
14 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, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
28 #include "volFields.H"
29 #include "surfaceFields.H"
30 #include "emptyFvPatchField.H"
32 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 void Foam::fvMeshAdder::map
37 const Field<Type>& oldFld,
38 const labelList& oldToNew,
44 label newCellI = oldToNew[cellI];
46 if (newCellI >= 0 && newCellI < fld.size())
48 fld[newCellI] = oldFld[cellI];
55 void Foam::fvMeshAdder::MapVolField
57 const mapAddedPolyMesh& meshMap,
59 GeometricField<Type, fvPatchField, volMesh>& fld,
60 const GeometricField<Type, fvPatchField, volMesh>& fldToAdd
63 const fvMesh& mesh = fld.mesh();
69 // Store old internal field
70 Field<Type> oldInternalField(fld.internalField());
72 // Modify internal field
73 Field<Type>& intFld = fld.internalField();
75 intFld.setSize(mesh.nCells());
77 map(oldInternalField, meshMap.oldCellMap(), intFld);
78 map(fldToAdd.internalField(), meshMap.addedCellMap(), intFld);
82 // Patch fields from old mesh
83 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
86 const labelList& oldPatchMap = meshMap.oldPatchMap();
87 const labelList& oldPatchStarts = meshMap.oldPatchStarts();
88 const labelList& oldPatchSizes = meshMap.oldPatchSizes();
90 // Reorder old patches in order of new ones. Put removed patches at end.
92 label unusedPatchI = 0;
94 forAll(oldPatchMap, patchI)
96 label newPatchI = oldPatchMap[patchI];
104 label nUsedPatches = unusedPatchI;
106 // Reorder list for patchFields
107 labelList oldToNew(oldPatchMap.size());
109 forAll(oldPatchMap, patchI)
111 label newPatchI = oldPatchMap[patchI];
115 oldToNew[patchI] = newPatchI;
119 oldToNew[patchI] = unusedPatchI++;
124 // Sort deleted ones last so is now in newPatch ordering
125 fld.boundaryField().reorder(oldToNew);
126 // Extend to covers all patches
127 fld.boundaryField().setSize(mesh.boundaryMesh().size());
128 // Delete unused patches
131 label newPatchI = nUsedPatches;
132 newPatchI < fld.boundaryField().size();
136 fld.boundaryField().set(newPatchI, NULL);
143 forAll(oldPatchMap, patchI)
145 label newPatchI = oldPatchMap[patchI];
153 oldPatchStarts[patchI],
154 oldPatchSizes[patchI],
155 meshMap.oldFaceMap(),
156 mesh.boundaryMesh()[newPatchI],
161 directFvPatchFieldMapper patchMapper
163 oldPatchSizes[patchI],
168 // Create new patchField with same type as existing one.
170 // - boundaryField already in new order so access with newPatchI
171 // - fld.boundaryField()[newPatchI] both used for type and old
173 // - hope that field mapping allows aliasing since old and new
175 fld.boundaryField().set
178 fvPatchField<Type>::New
180 fld.boundaryField()[newPatchI], // old field
181 mesh.boundary()[newPatchI], // new fvPatch
182 fld.dimensionedInternalField(), // new internal field
183 patchMapper // mapper (new to old)
192 // Patch fields from added mesh
193 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
196 const labelList& addedPatchMap = meshMap.addedPatchMap();
198 // Add addedMesh patches
199 forAll(addedPatchMap, patchI)
201 label newPatchI = addedPatchMap[patchI];
205 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
206 const polyPatch& oldPatch =
207 fldToAdd.mesh().boundaryMesh()[patchI];
209 if (!fld.boundaryField()(newPatchI))
211 // First occurrence of newPatchI. Map from existing
214 // From new patch faces to patch faces on added mesh.
221 meshMap.addedFaceMap(),
227 directFvPatchFieldMapper patchMapper
233 fld.boundaryField().set
236 fvPatchField<Type>::New
238 fldToAdd.boundaryField()[patchI], // added field
239 mesh.boundary()[newPatchI], // new fvPatch
240 fld.dimensionedInternalField(), // new int. field
241 patchMapper // mapper
247 // PatchField will have correct size already. Just slot in
250 // From new patch faces to patch faces on added mesh. This
251 // time keep unmapped elements -1.
258 meshMap.addedFaceMap(),
260 -1 // unmapped values
264 const fvPatchField<Type>& addedFld =
265 fldToAdd.boundaryField()[patchI];
267 fvPatchField<Type>& newFld = fld.boundaryField()[newPatchI];
271 label oldFaceI = newToAdded[i];
273 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
275 newFld[i] = addedFld[oldFaceI];
286 void Foam::fvMeshAdder::MapVolFields
288 const mapAddedPolyMesh& meshMap,
290 const fvMesh& meshToAdd
293 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fields
295 mesh.objectRegistry::lookupClass
296 <GeometricField<Type, fvPatchField, volMesh> >
300 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fieldsToAdd
302 meshToAdd.objectRegistry::lookupClass
303 <GeometricField<Type, fvPatchField, volMesh> >
307 // It is necessary to enforce that all old-time fields are stored
308 // before the mapping is performed. Otherwise, if the
309 // old-time-level field is mapped before the field itself, sizes
314 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
315 iterator fieldIter = fields.begin();
316 fieldIter != fields.end();
320 const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
327 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
328 iterator fieldIter = fields.begin();
329 fieldIter != fields.end();
333 GeometricField<Type, fvPatchField, volMesh>& fld =
334 const_cast<GeometricField<Type, fvPatchField, volMesh>&>
339 if (fieldsToAdd.found(fld.name()))
341 Pout<< "Mapping field " << fld.name() << endl;
343 const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
344 *fieldsToAdd[fld.name()];
346 MapVolField<Type>(meshMap, fld, fldToAdd);
350 WarningIn("fvMeshAdder::MapVolFields")
351 << "Not mapping field " << fld.name()
352 << " since not present on mesh to add"
360 void Foam::fvMeshAdder::MapSurfaceField
362 const mapAddedPolyMesh& meshMap,
364 GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
365 const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd
368 const fvMesh& mesh = fld.mesh();
369 const labelList& oldPatchStarts = meshMap.oldPatchStarts();
374 // Store old internal field
376 Field<Type> oldField(fld);
378 // Modify internal field
379 Field<Type>& intFld = fld.internalField();
381 intFld.setSize(mesh.nInternalFaces());
383 map(oldField, meshMap.oldFaceMap(), intFld);
384 map(fldToAdd, meshMap.addedFaceMap(), intFld);
386 // Faces that were boundary faces but are not anymore.
387 // Use owner value (so lowest numbered cell, i.e. from 'old' not 'added'
389 forAll(fld.boundaryField(), patchI)
391 const fvsPatchField<Type>& pf = fld.boundaryField()[patchI];
393 label start = oldPatchStarts[patchI];
397 label newFaceI = meshMap.oldFaceMap()[start + i];
399 if (newFaceI >= 0 && newFaceI < mesh.nInternalFaces())
401 intFld[newFaceI] = pf[i];
408 // Patch fields from old mesh
409 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
412 const labelList& oldPatchMap = meshMap.oldPatchMap();
413 const labelList& oldPatchSizes = meshMap.oldPatchSizes();
415 // Reorder old patches in order of new ones. Put removed patches at end.
417 label unusedPatchI = 0;
419 forAll(oldPatchMap, patchI)
421 label newPatchI = oldPatchMap[patchI];
429 label nUsedPatches = unusedPatchI;
431 // Reorder list for patchFields
432 labelList oldToNew(oldPatchMap.size());
434 forAll(oldPatchMap, patchI)
436 label newPatchI = oldPatchMap[patchI];
440 oldToNew[patchI] = newPatchI;
444 oldToNew[patchI] = unusedPatchI++;
449 // Sort deleted ones last so is now in newPatch ordering
450 fld.boundaryField().reorder(oldToNew);
451 // Extend to covers all patches
452 fld.boundaryField().setSize(mesh.boundaryMesh().size());
453 // Delete unused patches
456 label newPatchI = nUsedPatches;
457 newPatchI < fld.boundaryField().size();
461 fld.boundaryField().set(newPatchI, NULL);
468 forAll(oldPatchMap, patchI)
470 label newPatchI = oldPatchMap[patchI];
478 oldPatchStarts[patchI],
479 oldPatchSizes[patchI],
480 meshMap.oldFaceMap(),
481 mesh.boundaryMesh()[newPatchI],
486 directFvPatchFieldMapper patchMapper
488 oldPatchSizes[patchI],
493 // Create new patchField with same type as existing one.
495 // - boundaryField already in new order so access with newPatchI
496 // - fld.boundaryField()[newPatchI] both used for type and old
498 // - hope that field mapping allows aliasing since old and new
500 fld.boundaryField().set
503 fvsPatchField<Type>::New
505 fld.boundaryField()[newPatchI], // old field
506 mesh.boundary()[newPatchI], // new fvPatch
507 fld.dimensionedInternalField(), // new internal field
508 patchMapper // mapper (new to old)
517 // Patch fields from added mesh
518 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
521 const labelList& addedPatchMap = meshMap.addedPatchMap();
523 // Add addedMesh patches
524 forAll(addedPatchMap, patchI)
526 label newPatchI = addedPatchMap[patchI];
530 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
531 const polyPatch& oldPatch =
532 fldToAdd.mesh().boundaryMesh()[patchI];
534 if (!fld.boundaryField()(newPatchI))
536 // First occurrence of newPatchI. Map from existing
539 // From new patch faces to patch faces on added mesh.
546 meshMap.addedFaceMap(),
552 directFvPatchFieldMapper patchMapper
558 fld.boundaryField().set
561 fvsPatchField<Type>::New
563 fldToAdd.boundaryField()[patchI],// added field
564 mesh.boundary()[newPatchI], // new fvPatch
565 fld.dimensionedInternalField(), // new int. field
566 patchMapper // mapper
572 // PatchField will have correct size already. Just slot in
575 // From new patch faces to patch faces on added mesh. This
576 // time keep unmapped elements -1.
583 meshMap.addedFaceMap(),
585 -1 // unmapped values
589 const fvsPatchField<Type>& addedFld =
590 fldToAdd.boundaryField()[patchI];
592 fvsPatchField<Type>& newFld =
593 fld.boundaryField()[newPatchI];
597 label oldFaceI = newToAdded[i];
599 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
601 newFld[i] = addedFld[oldFaceI];
612 void Foam::fvMeshAdder::MapSurfaceFields
614 const mapAddedPolyMesh& meshMap,
616 const fvMesh& meshToAdd
619 typedef GeometricField<Type, fvsPatchField, surfaceMesh> fldType;
621 HashTable<const fldType*> fields
623 mesh.objectRegistry::lookupClass<fldType>()
626 HashTable<const fldType*> fieldsToAdd
628 meshToAdd.objectRegistry::lookupClass<fldType>()
631 // It is necessary to enforce that all old-time fields are stored
632 // before the mapping is performed. Otherwise, if the
633 // old-time-level field is mapped before the field itself, sizes
638 typename HashTable<const fldType*>::
639 iterator fieldIter = fields.begin();
640 fieldIter != fields.end();
644 const_cast<fldType*>(fieldIter())
651 typename HashTable<const fldType*>::
652 iterator fieldIter = fields.begin();
653 fieldIter != fields.end();
657 fldType& fld = const_cast<fldType&>(*fieldIter());
659 if (fieldsToAdd.found(fld.name()))
661 Pout<< "Mapping field " << fld.name() << endl;
663 const fldType& fldToAdd = *fieldsToAdd[fld.name()];
665 MapSurfaceField<Type>(meshMap, fld, fldToAdd);
669 WarningIn("fvMeshAdder::MapSurfaceFields")
670 << "Not mapping field " << fld.name()
671 << " since not present on mesh to add"
678 // ************************************************************************* //