1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. 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(),
120 procField.boundaryField()[patchI].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())
161 mesh_.boundaryMesh().whichPatch(curF);
163 if (!patchFields(curBPatch))
168 fvPatchField<Type>::New
170 mesh_.boundary()[curBPatch].type(),
171 mesh_.boundary()[curBPatch],
172 DimensionedField<Type, volMesh>::null()
180 [curBPatch].whichFace(curF);
182 patchFields[curBPatch][curPatchFace] =
190 forAll (mesh_.boundary(), patchI)
195 isType<emptyFvPatch>(mesh_.boundary()[patchI])
196 && !patchFields(patchI)
202 fvPatchField<Type>::New
204 emptyFvPatchField<Type>::typeName,
205 mesh_.boundary()[patchI],
206 DimensionedField<Type, volMesh>::null()
213 // Now construct and write the field
214 // setting the internalField and patchFields
215 return tmp<GeometricField<Type, fvPatchField, volMesh> >
217 new GeometricField<Type, fvPatchField, volMesh>
221 fieldIoObject.name(),
222 mesh_.time().timeName(),
228 procFields[0].dimensions(),
237 Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
238 Foam::fvFieldReconstructor::reconstructFvSurfaceField
240 const IOobject& fieldIoObject
243 // Read the field for all the processors
244 PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
249 forAll (procMeshes_, procI)
254 new GeometricField<Type, fvsPatchField, surfaceMesh>
258 fieldIoObject.name(),
259 procMeshes_[procI].time().timeName(),
270 // Create the internalField
271 Field<Type> internalField(mesh_.nInternalFaces());
273 // Create the patch fields
274 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
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(),
331 procField.boundaryField()[patchI].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 isType<emptyFvPatch>(mesh_.boundary()[patchI])
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();
490 // Reconstruct and write all/selected surface fields
492 void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
494 const IOobjectList& objects,
495 const HashSet<word>& selectedFields
498 const word& fieldClassName =
499 GeometricField<Type, fvsPatchField, surfaceMesh>::typeName;
501 IOobjectList fields = objects.lookupClass(fieldClassName);
505 Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
507 forAllConstIter(IOobjectList, fields, fieldIter)
511 !selectedFields.size()
512 || selectedFields.found(fieldIter()->name())
515 Info<< " " << fieldIter()->name() << endl;
517 reconstructFvSurfaceField<Type>(*fieldIter())().write();
526 // ************************************************************************* //