1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2010 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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "fvFieldReconstructor.H"
29 #include "fvPatchFields.H"
30 #include "emptyFvPatch.H"
31 #include "emptyFvPatchField.H"
32 #include "emptyFvsPatchField.H"
34 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
37 Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
38 Foam::fvFieldReconstructor::reconstructFvVolumeField
40 const IOobject& fieldIoObject
43 // Read the field for all the processors
44 PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
49 forAll (procMeshes_, procI)
54 new GeometricField<Type, fvPatchField, volMesh>
59 procMeshes_[procI].time().timeName(),
70 // Create the internalField
71 Field<Type> internalField(mesh_.nCells());
73 // Create the patch fields
74 PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
77 forAll (procMeshes_, procI)
79 const GeometricField<Type, fvPatchField, volMesh>& procField =
82 // Set the cell values in the reconstructed field
85 procField.internalField(),
86 cellProcAddressing_[procI]
89 // Set the boundary patch values in the reconstructed field
90 forAll(boundaryProcAddressing_[procI], patchI)
92 // Get patch index of the original patch
93 const label curBPatch = boundaryProcAddressing_[procI][patchI];
95 // Get addressing slice for this patch
96 const labelList::subList cp =
97 procMeshes_[procI].boundary()[patchI].patchSlice
99 faceProcAddressing_[procI]
102 // check if the boundary patch is not a processor patch
105 // Regular patch. Fast looping
107 if (!patchFields(curBPatch))
112 fvPatchField<Type>::New
114 procField.boundaryField()[patchI],
115 mesh_.boundary()[curBPatch],
116 DimensionedField<Type, volMesh>::null(),
117 fvPatchFieldReconstructor
119 mesh_.boundary()[curBPatch].size()
125 const label curPatchStart =
126 mesh_.boundaryMesh()[curBPatch].start();
128 labelList reverseAddressing(cp.size());
132 // Subtract one to take into account offsets for
134 reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
137 patchFields[curBPatch].rmap
139 procField.boundaryField()[patchI],
145 const Field<Type>& curProcPatch =
146 procField.boundaryField()[patchI];
148 // In processor patches, there's a mix of internal faces (some
149 // of them turned) and possible cyclics. Slow loop
152 // Subtract one to take into account offsets for
154 label curF = cp[faceI] - 1;
156 // Is the face on the boundary?
157 if (curF >= mesh_.nInternalFaces())
159 label curBPatch = mesh_.boundaryMesh().whichPatch(curF);
161 if (!patchFields(curBPatch))
166 fvPatchField<Type>::New
168 mesh_.boundary()[curBPatch].type(),
169 mesh_.boundary()[curBPatch],
170 DimensionedField<Type, volMesh>::null()
178 [curBPatch].whichFace(curF);
180 patchFields[curBPatch][curPatchFace] =
188 forAll(mesh_.boundary(), patchI)
193 isType<emptyFvPatch>(mesh_.boundary()[patchI])
194 && !patchFields(patchI)
200 fvPatchField<Type>::New
202 emptyFvPatchField<Type>::typeName,
203 mesh_.boundary()[patchI],
204 DimensionedField<Type, volMesh>::null()
211 // Now construct and write the field
212 // setting the internalField and patchFields
213 return tmp<GeometricField<Type, fvPatchField, volMesh> >
215 new GeometricField<Type, fvPatchField, volMesh>
219 fieldIoObject.name(),
220 mesh_.time().timeName(),
226 procFields[0].dimensions(),
235 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
236 Foam::fvFieldReconstructor::reconstructFvSurfaceField
238 const IOobject& fieldIoObject
241 // Read the field for all the processors
242 PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
247 forAll (procMeshes_, procI)
252 new GeometricField<Type, fvsPatchField, surfaceMesh>
256 fieldIoObject.name(),
257 procMeshes_[procI].time().timeName(),
268 // Create the internalField
269 Field<Type> internalField(mesh_.nInternalFaces());
271 // Create the patch fields
272 PtrList<fvsPatchField<Type> > patchFields(mesh_.boundary().size());
275 forAll (procMeshes_, procI)
277 const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
280 // Set the face values in the reconstructed field
282 // It is necessary to create a copy of the addressing array to
283 // take care of the face direction offset trick.
286 labelList curAddr(faceProcAddressing_[procI]);
288 forAll (curAddr, addrI)
295 procField.internalField(),
300 // Set the boundary patch values in the reconstructed field
301 forAll(boundaryProcAddressing_[procI], patchI)
303 // Get patch index of the original patch
304 const label curBPatch = boundaryProcAddressing_[procI][patchI];
306 // Get addressing slice for this patch
307 const labelList::subList cp =
308 procMeshes_[procI].boundary()[patchI].patchSlice
310 faceProcAddressing_[procI]
313 // check if the boundary patch is not a processor patch
316 // Regular patch. Fast looping
318 if (!patchFields(curBPatch))
323 fvsPatchField<Type>::New
325 procField.boundaryField()[patchI],
326 mesh_.boundary()[curBPatch],
327 DimensionedField<Type, surfaceMesh>::null(),
328 fvPatchFieldReconstructor
330 mesh_.boundary()[curBPatch].size()
336 const label curPatchStart =
337 mesh_.boundaryMesh()[curBPatch].start();
339 labelList reverseAddressing(cp.size());
343 // Subtract one to take into account offsets for
345 reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
348 patchFields[curBPatch].rmap
350 procField.boundaryField()[patchI],
356 const Field<Type>& curProcPatch =
357 procField.boundaryField()[patchI];
359 // In processor patches, there's a mix of internal faces (some
360 // of them turned) and possible cyclics. Slow loop
363 label curF = cp[faceI] - 1;
365 // Is the face turned the right side round
368 // Is the face on the boundary?
369 if (curF >= mesh_.nInternalFaces())
372 mesh_.boundaryMesh().whichPatch(curF);
374 if (!patchFields(curBPatch))
379 fvsPatchField<Type>::New
381 mesh_.boundary()[curBPatch].type(),
382 mesh_.boundary()[curBPatch],
383 DimensionedField<Type, surfaceMesh>
392 [curBPatch].whichFace(curF);
394 patchFields[curBPatch][curPatchFace] =
400 internalField[curF] = curProcPatch[faceI];
408 forAll(mesh_.boundary(), patchI)
413 isType<emptyFvPatch>(mesh_.boundary()[patchI])
414 && !patchFields(patchI)
420 fvsPatchField<Type>::New
422 emptyFvsPatchField<Type>::typeName,
423 mesh_.boundary()[patchI],
424 DimensionedField<Type, surfaceMesh>::null()
431 // Now construct and write the field
432 // setting the internalField and patchFields
433 return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
435 new GeometricField<Type, fvsPatchField, surfaceMesh>
439 fieldIoObject.name(),
440 mesh_.time().timeName(),
446 procFields[0].dimensions(),
454 // Reconstruct and write all/selected volume fields
456 void Foam::fvFieldReconstructor::reconstructFvVolumeFields
458 const IOobjectList& objects,
459 const HashSet<word>& selectedFields
462 const word& fieldClassName =
463 GeometricField<Type, fvPatchField, volMesh>::typeName;
465 IOobjectList fields = objects.lookupClass(fieldClassName);
469 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
471 forAllConstIter(IOobjectList, fields, fieldIter)
475 !selectedFields.size()
476 || selectedFields.found(fieldIter()->name())
479 Info<< " " << fieldIter()->name() << endl;
481 reconstructFvVolumeField<Type>(*fieldIter())().write();
488 // Reconstruct and write all/selected surface fields
490 void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
492 const IOobjectList& objects,
493 const HashSet<word>& selectedFields
496 const word& fieldClassName =
497 GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
499 IOobjectList fields = objects.lookupClass(fieldClassName);
503 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
505 forAllConstIter(IOobjectList, fields, fieldIter)
509 !selectedFields.size()
510 || selectedFields.found(fieldIter()->name())
513 Info<< " " << fieldIter()->name() << endl;
515 reconstructFvSurfaceField<Type>(*fieldIter())().write();
523 // ************************************************************************* //