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 \*---------------------------------------------------------------------------*/
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(),
121 procField.boundaryField()[patchI].size()
127 const label curPatchStart =
128 mesh_.boundaryMesh()[curBPatch].start();
130 labelList reverseAddressing(cp.size());
134 // Subtract one to take into account offsets for
136 reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
139 patchFields[curBPatch].rmap
141 procField.boundaryField()[patchI],
147 const Field<Type>& curProcPatch =
148 procField.boundaryField()[patchI];
150 // In processor patches, there's a mix of internal faces (some
151 // of them turned) and possible cyclics. Slow loop
154 // Subtract one to take into account offsets for
156 label curF = cp[faceI] - 1;
158 // Is the face on the boundary?
159 if (curF >= mesh_.nInternalFaces())
162 mesh_.boundaryMesh().whichPatch(curF);
164 if (!patchFields(curBPatch))
169 fvPatchField<Type>::New
171 mesh_.boundary()[curBPatch].type(),
172 mesh_.boundary()[curBPatch],
173 DimensionedField<Type, volMesh>::null()
181 [curBPatch].whichFace(curF);
183 patchFields[curBPatch][curPatchFace] =
191 forAll (mesh_.boundary(), patchI)
196 isType<emptyFvPatch>(mesh_.boundary()[patchI])
197 && !patchFields(patchI)
203 fvPatchField<Type>::New
205 emptyFvPatchField<Type>::typeName,
206 mesh_.boundary()[patchI],
207 DimensionedField<Type, volMesh>::null()
214 // Now construct and write the field
215 // setting the internalField and patchFields
216 return tmp<GeometricField<Type, fvPatchField, volMesh> >
218 new GeometricField<Type, fvPatchField, volMesh>
222 fieldIoObject.name(),
223 mesh_.time().timeName(),
229 procFields[0].dimensions(),
238 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
239 Foam::fvFieldReconstructor::reconstructFvSurfaceField
241 const IOobject& fieldIoObject
244 // Read the field for all the processors
245 PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
250 forAll (procMeshes_, procI)
255 new GeometricField<Type, fvsPatchField, surfaceMesh>
259 fieldIoObject.name(),
260 procMeshes_[procI].time().timeName(),
271 // Create the internalField
272 Field<Type> internalField(mesh_.nInternalFaces());
274 // Create the patch fields
275 PtrList<fvsPatchField<Type> > patchFields(mesh_.boundary().size());
277 forAll (procMeshes_, procI)
279 const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
282 // Set the face values in the reconstructed field
284 // It is necessary to create a copy of the addressing array to
285 // take care of the face direction offset trick.
288 labelList curAddr(faceProcAddressing_[procI]);
290 forAll (curAddr, addrI)
297 procField.internalField(),
302 // Set the boundary patch values in the reconstructed field
303 forAll (boundaryProcAddressing_[procI], patchI)
305 // Get patch index of the original patch
306 const label curBPatch = boundaryProcAddressing_[procI][patchI];
308 // Get addressing slice for this patch
309 const labelList::subList cp =
310 procMeshes_[procI].boundary()[patchI].patchSlice
312 faceProcAddressing_[procI]
315 // Check if the boundary patch is not a processor patch
318 // 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(),
332 procField.boundaryField()[patchI].size()
338 const label curPatchStart =
339 mesh_.boundaryMesh()[curBPatch].start();
341 labelList reverseAddressing(cp.size());
345 // Subtract one to take into account offsets for
347 reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
350 patchFields[curBPatch].rmap
352 procField.boundaryField()[patchI],
358 const Field<Type>& curProcPatch =
359 procField.boundaryField()[patchI];
361 // In processor patches, there's a mix of internal faces (some
362 // of them turned) and possible cyclics. Slow loop
365 label curF = cp[faceI] - 1;
367 // Is the face turned the right side round
370 // Is the face on the boundary?
371 if (curF >= mesh_.nInternalFaces())
374 mesh_.boundaryMesh().whichPatch(curF);
376 if (!patchFields(curBPatch))
381 fvsPatchField<Type>::New
383 mesh_.boundary()[curBPatch].type(),
384 mesh_.boundary()[curBPatch],
385 DimensionedField<Type, surfaceMesh>
394 [curBPatch].whichFace(curF);
396 patchFields[curBPatch][curPatchFace] =
402 internalField[curF] = curProcPatch[faceI];
410 forAll (mesh_.boundary(), patchI)
415 isType<emptyFvPatch>(mesh_.boundary()[patchI])
416 && !patchFields(patchI)
422 fvsPatchField<Type>::New
424 emptyFvsPatchField<Type>::typeName,
425 mesh_.boundary()[patchI],
426 DimensionedField<Type, surfaceMesh>::null()
433 // Now construct and write the field
434 // setting the internalField and patchFields
435 return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
437 new GeometricField<Type, fvsPatchField, surfaceMesh>
441 fieldIoObject.name(),
442 mesh_.time().timeName(),
448 procFields[0].dimensions(),
456 // Reconstruct and write all/selected volume fields
458 void Foam::fvFieldReconstructor::reconstructFvVolumeFields
460 const IOobjectList& objects,
461 const HashSet<word>& selectedFields
464 const word& fieldClassName =
465 GeometricField<Type, fvPatchField, volMesh>::typeName;
467 IOobjectList fields = objects.lookupClass(fieldClassName);
471 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
473 forAllConstIter(IOobjectList, fields, fieldIter)
477 !selectedFields.size()
478 || selectedFields.found(fieldIter()->name())
481 Info<< " " << fieldIter()->name() << endl;
483 reconstructFvVolumeField<Type>(*fieldIter())().write();
491 // Reconstruct and write all/selected surface fields
493 void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
495 const IOobjectList& objects,
496 const HashSet<word>& selectedFields
499 const word& fieldClassName =
500 GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
502 IOobjectList fields = objects.lookupClass(fieldClassName);
506 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
508 forAllConstIter(IOobjectList, fields, fieldIter)
512 !selectedFields.size()
513 || selectedFields.found(fieldIter()->name())
516 Info<< " " << fieldIter()->name() << endl;
518 reconstructFvSurfaceField<Type>(*fieldIter())().write();
527 // ************************************************************************* //