1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 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 \*---------------------------------------------------------------------------*/
27 #include "fvFieldReconstructor.H"
30 #include "fvPatchFields.H"
31 #include "emptyFvPatch.H"
32 #include "emptyFvPatchField.H"
33 #include "emptyFvsPatchField.H"
35 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
38 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
39 Foam::fvFieldReconstructor::reconstructFvVolumeField
41 const IOobject& fieldIoObject
44 // Read the field for all the processors
45 PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
50 forAll (procMeshes_, procI)
55 new GeometricField<Type, fvPatchField, volMesh>
60 procMeshes_[procI].time().timeName(),
71 // Create the internalField
72 Field<Type> internalField(mesh_.nCells());
74 // Create the patch fields
75 PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
78 forAll (procMeshes_, procI)
80 const GeometricField<Type, fvPatchField, volMesh>& procField =
83 // Set the cell values in the reconstructed field
86 procField.internalField(),
87 cellProcAddressing_[procI]
90 // Set the boundary patch values in the reconstructed field
91 forAll(boundaryProcAddressing_[procI], patchI)
93 // Get patch index of the original patch
94 const label curBPatch = boundaryProcAddressing_[procI][patchI];
96 // Get addressing slice for this patch
97 const labelList::subList cp =
98 procMeshes_[procI].boundary()[patchI].patchSlice
100 faceProcAddressing_[procI]
103 // check if the boundary patch is not a processor patch
106 // Regular patch. Fast looping
108 if (!patchFields(curBPatch))
113 fvPatchField<Type>::New
115 procField.boundaryField()[patchI],
116 mesh_.boundary()[curBPatch],
117 DimensionedField<Type, volMesh>::null(),
118 fvPatchFieldReconstructor
120 mesh_.boundary()[curBPatch].size()
126 const label curPatchStart =
127 mesh_.boundaryMesh()[curBPatch].start();
129 labelList reverseAddressing(cp.size());
133 // Subtract one to take into account offsets for
135 reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
138 patchFields[curBPatch].rmap
140 procField.boundaryField()[patchI],
146 const Field<Type>& curProcPatch =
147 procField.boundaryField()[patchI];
149 // In processor patches, there's a mix of internal faces (some
150 // of them turned) and possible cyclics. Slow loop
153 // Subtract one to take into account offsets for
155 label curF = cp[faceI] - 1;
157 // Is the face on the boundary?
158 if (curF >= mesh_.nInternalFaces())
160 label curBPatch = mesh_.boundaryMesh().whichPatch(curF);
162 if (!patchFields(curBPatch))
167 fvPatchField<Type>::New
169 mesh_.boundary()[curBPatch].type(),
170 mesh_.boundary()[curBPatch],
171 DimensionedField<Type, volMesh>::null()
179 [curBPatch].whichFace(curF);
181 patchFields[curBPatch][curPatchFace] =
189 forAll(mesh_.boundary(), patchI)
194 typeid(mesh_.boundary()[patchI]) == typeid(emptyFvPatch)
195 && !patchFields(patchI)
201 fvPatchField<Type>::New
203 emptyFvPatchField<Type>::typeName,
204 mesh_.boundary()[patchI],
205 DimensionedField<Type, volMesh>::null()
212 // Now construct and write the field
213 // setting the internalField and patchFields
214 return tmp<GeometricField<Type, fvPatchField, volMesh> >
216 new GeometricField<Type, fvPatchField, volMesh>
220 fieldIoObject.name(),
221 mesh_.time().timeName(),
227 procFields[0].dimensions(),
236 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
237 Foam::fvFieldReconstructor::reconstructFvSurfaceField
239 const IOobject& fieldIoObject
242 // Read the field for all the processors
243 PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
248 forAll (procMeshes_, procI)
253 new GeometricField<Type, fvsPatchField, surfaceMesh>
257 fieldIoObject.name(),
258 procMeshes_[procI].time().timeName(),
269 // Create the internalField
270 Field<Type> internalField(mesh_.nInternalFaces());
272 // Create the patch fields
273 PtrList<fvsPatchField<Type> > patchFields(mesh_.boundary().size());
276 forAll (procMeshes_, procI)
278 const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
281 // Set the face values in the reconstructed field
283 // It is necessary to create a copy of the addressing array to
284 // take care of the face direction offset trick.
287 labelList curAddr(faceProcAddressing_[procI]);
289 forAll (curAddr, addrI)
296 procField.internalField(),
301 // Set the boundary patch values in the reconstructed field
302 forAll(boundaryProcAddressing_[procI], patchI)
304 // Get patch index of the original patch
305 const label curBPatch = boundaryProcAddressing_[procI][patchI];
307 // Get addressing slice for this patch
308 const labelList::subList cp =
309 procMeshes_[procI].boundary()[patchI].patchSlice
311 faceProcAddressing_[procI]
314 // check if the boundary patch is not a processor patch
317 // Regular patch. Fast looping
319 if (!patchFields(curBPatch))
324 fvsPatchField<Type>::New
326 procField.boundaryField()[patchI],
327 mesh_.boundary()[curBPatch],
328 DimensionedField<Type, surfaceMesh>::null(),
329 fvPatchFieldReconstructor
331 mesh_.boundary()[curBPatch].size()
337 const label curPatchStart =
338 mesh_.boundaryMesh()[curBPatch].start();
340 labelList reverseAddressing(cp.size());
344 // Subtract one to take into account offsets for
346 reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
349 patchFields[curBPatch].rmap
351 procField.boundaryField()[patchI],
357 const Field<Type>& curProcPatch =
358 procField.boundaryField()[patchI];
360 // In processor patches, there's a mix of internal faces (some
361 // of them turned) and possible cyclics. Slow loop
364 label curF = cp[faceI] - 1;
366 // Is the face turned the right side round
369 // Is the face on the boundary?
370 if (curF >= mesh_.nInternalFaces())
373 mesh_.boundaryMesh().whichPatch(curF);
375 if (!patchFields(curBPatch))
380 fvsPatchField<Type>::New
382 mesh_.boundary()[curBPatch].type(),
383 mesh_.boundary()[curBPatch],
384 DimensionedField<Type, surfaceMesh>
393 [curBPatch].whichFace(curF);
395 patchFields[curBPatch][curPatchFace] =
401 internalField[curF] = curProcPatch[faceI];
409 forAll(mesh_.boundary(), patchI)
414 typeid(mesh_.boundary()[patchI]) == typeid(emptyFvPatch)
415 && !patchFields(patchI)
421 fvsPatchField<Type>::New
423 emptyFvsPatchField<Type>::typeName,
424 mesh_.boundary()[patchI],
425 DimensionedField<Type, surfaceMesh>::null()
432 // Now construct and write the field
433 // setting the internalField and patchFields
434 return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
436 new GeometricField<Type, fvsPatchField, surfaceMesh>
440 fieldIoObject.name(),
441 mesh_.time().timeName(),
447 procFields[0].dimensions(),
455 // Reconstruct and write all/selected volume fields
457 void Foam::fvFieldReconstructor::reconstructFvVolumeFields
459 const IOobjectList& objects,
460 const HashSet<word>& selectedFields
463 const word& fieldClassName =
464 GeometricField<Type, fvPatchField, volMesh>::typeName;
466 IOobjectList fields = objects.lookupClass(fieldClassName);
470 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
472 forAllConstIter(IOobjectList, fields, fieldIter)
476 !selectedFields.size()
477 || selectedFields.found(fieldIter()->name())
480 Info<< " " << fieldIter()->name() << endl;
482 reconstructFvVolumeField<Type>(*fieldIter())().write();
489 // Reconstruct and write all/selected surface fields
491 void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
493 const IOobjectList& objects,
494 const HashSet<word>& selectedFields
497 const word& fieldClassName =
498 GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
500 IOobjectList fields = objects.lookupClass(fieldClassName);
504 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
506 forAllConstIter(IOobjectList, fields, fieldIter)
510 !selectedFields.size()
511 || selectedFields.found(fieldIter()->name())
514 Info<< " " << fieldIter()->name() << endl;
516 reconstructFvSurfaceField<Type>(*fieldIter())().write();
524 // ************************************************************************* //