1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
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(newToOld);
164 // Create new patchField with same type as existing one.
166 // - boundaryField already in new order so access with newPatchI
167 // - fld.boundaryField()[newPatchI] both used for type and old
169 // - hope that field mapping allows aliasing since old and new
171 fld.boundaryField().set
174 fvPatchField<Type>::New
176 fld.boundaryField()[newPatchI], // old field
177 mesh.boundary()[newPatchI], // new fvPatch
178 fld.dimensionedInternalField(), // new internal field
179 patchMapper // mapper (new to old)
188 // Patch fields from added mesh
189 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
192 const labelList& addedPatchMap = meshMap.addedPatchMap();
194 // Add addedMesh patches
195 forAll(addedPatchMap, patchI)
197 label newPatchI = addedPatchMap[patchI];
201 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
202 const polyPatch& oldPatch =
203 fldToAdd.mesh().boundaryMesh()[patchI];
205 if (!fld.boundaryField()(newPatchI))
207 // First occurrence of newPatchI. Map from existing
210 // From new patch faces to patch faces on added mesh.
217 meshMap.addedFaceMap(),
223 directFvPatchFieldMapper patchMapper(newToAdded);
225 fld.boundaryField().set
228 fvPatchField<Type>::New
230 fldToAdd.boundaryField()[patchI], // added field
231 mesh.boundary()[newPatchI], // new fvPatch
232 fld.dimensionedInternalField(), // new int. field
233 patchMapper // mapper
239 // PatchField will have correct size already. Just slot in
242 // From new patch faces to patch faces on added mesh. This
243 // time keep unmapped elements -1.
250 meshMap.addedFaceMap(),
252 -1 // unmapped values
256 const fvPatchField<Type>& addedFld =
257 fldToAdd.boundaryField()[patchI];
259 fvPatchField<Type>& newFld = fld.boundaryField()[newPatchI];
263 label oldFaceI = newToAdded[i];
265 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
267 newFld[i] = addedFld[oldFaceI];
278 void Foam::fvMeshAdder::MapVolFields
280 const mapAddedPolyMesh& meshMap,
282 const fvMesh& meshToAdd
285 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fields
287 mesh.objectRegistry::lookupClass
288 <GeometricField<Type, fvPatchField, volMesh> >
292 HashTable<const GeometricField<Type, fvPatchField, volMesh>*> fieldsToAdd
294 meshToAdd.objectRegistry::lookupClass
295 <GeometricField<Type, fvPatchField, volMesh> >
299 // It is necessary to enforce that all old-time fields are stored
300 // before the mapping is performed. Otherwise, if the
301 // old-time-level field is mapped before the field itself, sizes
306 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
307 iterator fieldIter = fields.begin();
308 fieldIter != fields.end();
312 const_cast<GeometricField<Type, fvPatchField, volMesh>*>(fieldIter())
319 typename HashTable<const GeometricField<Type, fvPatchField, volMesh>*>::
320 iterator fieldIter = fields.begin();
321 fieldIter != fields.end();
325 GeometricField<Type, fvPatchField, volMesh>& fld =
326 const_cast<GeometricField<Type, fvPatchField, volMesh>&>
331 if (fieldsToAdd.found(fld.name()))
333 Pout<< "Mapping field " << fld.name() << endl;
335 const GeometricField<Type, fvPatchField, volMesh>& fldToAdd =
336 *fieldsToAdd[fld.name()];
338 MapVolField<Type>(meshMap, fld, fldToAdd);
342 WarningIn("fvMeshAdder::MapVolFields")
343 << "Not mapping field " << fld.name()
344 << " since not present on mesh to add"
352 void Foam::fvMeshAdder::MapSurfaceField
354 const mapAddedPolyMesh& meshMap,
356 GeometricField<Type, fvsPatchField, surfaceMesh>& fld,
357 const GeometricField<Type, fvsPatchField, surfaceMesh>& fldToAdd
360 const fvMesh& mesh = fld.mesh();
361 const labelList& oldPatchStarts = meshMap.oldPatchStarts();
366 // Store old internal field
368 Field<Type> oldField(fld);
370 // Modify internal field
371 Field<Type>& intFld = fld.internalField();
373 intFld.setSize(mesh.nInternalFaces());
375 map(oldField, meshMap.oldFaceMap(), intFld);
376 map(fldToAdd, meshMap.addedFaceMap(), intFld);
378 // Faces that were boundary faces but are not anymore.
379 // Use owner value (so lowest numbered cell, i.e. from 'old' not 'added'
381 forAll(fld.boundaryField(), patchI)
383 const fvsPatchField<Type>& pf = fld.boundaryField()[patchI];
385 label start = oldPatchStarts[patchI];
389 label newFaceI = meshMap.oldFaceMap()[start + i];
391 if (newFaceI >= 0 && newFaceI < mesh.nInternalFaces())
393 intFld[newFaceI] = pf[i];
400 // Patch fields from old mesh
401 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
404 const labelList& oldPatchMap = meshMap.oldPatchMap();
405 const labelList& oldPatchSizes = meshMap.oldPatchSizes();
407 // Reorder old patches in order of new ones. Put removed patches at end.
409 label unusedPatchI = 0;
411 forAll(oldPatchMap, patchI)
413 label newPatchI = oldPatchMap[patchI];
421 label nUsedPatches = unusedPatchI;
423 // Reorder list for patchFields
424 labelList oldToNew(oldPatchMap.size());
426 forAll(oldPatchMap, patchI)
428 label newPatchI = oldPatchMap[patchI];
432 oldToNew[patchI] = newPatchI;
436 oldToNew[patchI] = unusedPatchI++;
441 // Sort deleted ones last so is now in newPatch ordering
442 fld.boundaryField().reorder(oldToNew);
443 // Extend to covers all patches
444 fld.boundaryField().setSize(mesh.boundaryMesh().size());
445 // Delete unused patches
448 label newPatchI = nUsedPatches;
449 newPatchI < fld.boundaryField().size();
453 fld.boundaryField().set(newPatchI, NULL);
460 forAll(oldPatchMap, patchI)
462 label newPatchI = oldPatchMap[patchI];
470 oldPatchStarts[patchI],
471 oldPatchSizes[patchI],
472 meshMap.oldFaceMap(),
473 mesh.boundaryMesh()[newPatchI],
478 directFvPatchFieldMapper patchMapper(newToOld);
481 // Create new patchField with same type as existing one.
483 // - boundaryField already in new order so access with newPatchI
484 // - fld.boundaryField()[newPatchI] both used for type and old
486 // - hope that field mapping allows aliasing since old and new
488 fld.boundaryField().set
491 fvsPatchField<Type>::New
493 fld.boundaryField()[newPatchI], // old field
494 mesh.boundary()[newPatchI], // new fvPatch
495 fld.dimensionedInternalField(), // new internal field
496 patchMapper // mapper (new to old)
505 // Patch fields from added mesh
506 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
509 const labelList& addedPatchMap = meshMap.addedPatchMap();
511 // Add addedMesh patches
512 forAll(addedPatchMap, patchI)
514 label newPatchI = addedPatchMap[patchI];
518 const polyPatch& newPatch = mesh.boundaryMesh()[newPatchI];
519 const polyPatch& oldPatch =
520 fldToAdd.mesh().boundaryMesh()[patchI];
522 if (!fld.boundaryField()(newPatchI))
524 // First occurrence of newPatchI. Map from existing
527 // From new patch faces to patch faces on added mesh.
534 meshMap.addedFaceMap(),
540 directFvPatchFieldMapper patchMapper(newToAdded);
542 fld.boundaryField().set
545 fvsPatchField<Type>::New
547 fldToAdd.boundaryField()[patchI],// added field
548 mesh.boundary()[newPatchI], // new fvPatch
549 fld.dimensionedInternalField(), // new int. field
550 patchMapper // mapper
556 // PatchField will have correct size already. Just slot in
559 // From new patch faces to patch faces on added mesh. This
560 // time keep unmapped elements -1.
567 meshMap.addedFaceMap(),
569 -1 // unmapped values
573 const fvsPatchField<Type>& addedFld =
574 fldToAdd.boundaryField()[patchI];
576 fvsPatchField<Type>& newFld =
577 fld.boundaryField()[newPatchI];
581 label oldFaceI = newToAdded[i];
583 if (oldFaceI >= 0 && oldFaceI < addedFld.size())
585 newFld[i] = addedFld[oldFaceI];
596 void Foam::fvMeshAdder::MapSurfaceFields
598 const mapAddedPolyMesh& meshMap,
600 const fvMesh& meshToAdd
603 typedef GeometricField<Type, fvsPatchField, surfaceMesh> fldType;
605 HashTable<const fldType*> fields
607 mesh.objectRegistry::lookupClass<fldType>()
610 HashTable<const fldType*> fieldsToAdd
612 meshToAdd.objectRegistry::lookupClass<fldType>()
615 // It is necessary to enforce that all old-time fields are stored
616 // before the mapping is performed. Otherwise, if the
617 // old-time-level field is mapped before the field itself, sizes
622 typename HashTable<const fldType*>::
623 iterator fieldIter = fields.begin();
624 fieldIter != fields.end();
628 const_cast<fldType*>(fieldIter())
635 typename HashTable<const fldType*>::
636 iterator fieldIter = fields.begin();
637 fieldIter != fields.end();
641 fldType& fld = const_cast<fldType&>(*fieldIter());
643 if (fieldsToAdd.found(fld.name()))
645 Pout<< "Mapping field " << fld.name() << endl;
647 const fldType& fldToAdd = *fieldsToAdd[fld.name()];
649 MapSurfaceField<Type>(meshMap, fld, fldToAdd);
653 WarningIn("fvMeshAdder::MapSurfaceFields")
654 << "Not mapping field " << fld.name()
655 << " since not present on mesh to add"
662 // ************************************************************************* //