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
29 Reconstructs a mesh and fields of a case that is decomposed for parallel
30 execution of OpenFOAM.
32 \*---------------------------------------------------------------------------*/
35 #include "timeSelector.H"
38 #include "IOobjectList.H"
39 #include "processorMeshes.H"
40 #include "fvFieldReconstructor.H"
41 #include "pointFieldReconstructor.H"
42 #include "reconstructLagrangian.H"
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 int main(int argc, char *argv[])
48 argList::noParallel();
49 timeSelector::addOptions();
50 # include "addRegionOption.H"
51 # include "setRootCase.H"
52 # include "createTime.H"
54 // determine the processor count directly
56 while (dir(args.path()/(word("processor") + name(nProcs))))
63 FatalErrorIn(args.executable())
64 << "No processor* directories found"
68 // Create the processor databases
69 PtrList<Time> databases(nProcs);
71 forAll (databases, procI)
78 Time::controlDictName,
80 args.caseName()/fileName(word("processor") + name(procI))
85 // use the times list from the master processor
86 // and select a subset based on the command-line options
87 instantList timeDirs = timeSelector::select
95 FatalErrorIn(args.executable())
96 << "No times selected"
100 # include "createNamedMesh.H"
101 fileName regionPrefix = "";
102 if (regionName != fvMesh::defaultRegion)
104 regionPrefix = regionName;
108 // Set all times (on reconstructed mesh and on processor meshes)
109 runTime.setTime(timeDirs[0], 0);
112 forAll (databases, procI)
114 databases[procI].setTime(timeDirs[0], 0);
117 // Read all meshes and addressing to reconstructed mesh
118 processorMeshes procMeshes(databases, regionName);
120 // check face addressing for meshes that have been decomposed
121 // with a very old foam version
122 # include "checkFaceAddressingComp.H"
124 // Loop over all times
125 forAll (timeDirs, timeI)
127 // Set time for global database
128 runTime.setTime(timeDirs[timeI], timeI);
130 Info << "Time = " << runTime.timeName() << endl << endl;
132 // Set time for all databases
133 forAll (databases, procI)
135 databases[procI].setTime(timeDirs[timeI], timeI);
138 // Check if any new meshes need to be read.
139 fvMesh::readUpdateState meshStat = mesh.readUpdate();
141 fvMesh::readUpdateState procStat = procMeshes.readUpdate();
143 if (procStat == fvMesh::POINTS_MOVED)
145 // Reconstruct the points for moving mesh cases and write them out
146 procMeshes.reconstructPoints(mesh);
148 else if (meshStat != procStat)
150 WarningIn(args.executable())
151 << "readUpdate for the reconstructed mesh:" << meshStat << nl
152 << "readUpdate for the processor meshes :" << procStat << nl
153 << "These should be equal or your addressing"
154 << " might be incorrect."
155 << " Please check your time directories for any "
156 << "mesh directories." << endl;
160 // Get list of objects from processor0 database
161 IOobjectList objects(procMeshes.meshes()[0], databases[0].timeName());
164 // If there are any FV fields, reconstruct them
168 objects.lookupClass(volScalarField::typeName).size()
169 || objects.lookupClass(volVectorField::typeName).size()
170 || objects.lookupClass(volSphericalTensorField::typeName).size()
171 || objects.lookupClass(volSymmTensorField::typeName).size()
172 || objects.lookupClass(volTensorField::typeName).size()
173 || objects.lookupClass(surfaceScalarField::typeName).size()
176 Info << "Reconstructing FV fields" << nl << endl;
178 fvFieldReconstructor fvReconstructor
182 procMeshes.faceProcAddressing(),
183 procMeshes.cellProcAddressing(),
184 procMeshes.boundaryProcAddressing()
187 fvReconstructor.reconstructFvVolumeFields<scalar>(objects);
188 fvReconstructor.reconstructFvVolumeFields<vector>(objects);
189 fvReconstructor.reconstructFvVolumeFields<sphericalTensor>(objects);
190 fvReconstructor.reconstructFvVolumeFields<symmTensor>(objects);
191 fvReconstructor.reconstructFvVolumeFields<tensor>(objects);
193 fvReconstructor.reconstructFvSurfaceFields<scalar>(objects);
197 Info << "No FV fields" << nl << endl;
201 // If there are any point fields, reconstruct them
204 objects.lookupClass(pointScalarField::typeName).size()
205 || objects.lookupClass(pointVectorField::typeName).size()
206 || objects.lookupClass(pointSphericalTensorField::typeName).size()
207 || objects.lookupClass(pointSymmTensorField::typeName).size()
208 || objects.lookupClass(pointTensorField::typeName).size()
211 Info << "Reconstructing point fields" << nl << endl;
213 pointMesh pMesh(mesh);
214 PtrList<pointMesh> pMeshes(procMeshes.meshes().size());
216 forAll (pMeshes, procI)
218 pMeshes.set(procI, new pointMesh(procMeshes.meshes()[procI]));
221 pointFieldReconstructor pointReconstructor
225 procMeshes.pointProcAddressing(),
226 procMeshes.boundaryProcAddressing()
229 pointReconstructor.reconstructFields<scalar>(objects);
230 pointReconstructor.reconstructFields<vector>(objects);
231 pointReconstructor.reconstructFields<sphericalTensor>(objects);
232 pointReconstructor.reconstructFields<symmTensor>(objects);
233 pointReconstructor.reconstructFields<tensor>(objects);
237 Info << "No point fields" << nl << endl;
241 // If there are any clouds, reconstruct them.
242 // The problem is that a cloud of size zero will not get written so
243 // in pass 1 we determine the cloud names and per cloud name the
244 // fields. Note that the fields are stored as IOobjectList from
245 // the first processor that has them. They are in pass2 only used
246 // for name and type (scalar, vector etc).
248 HashTable<IOobjectList> cloudObjects;
250 forAll (databases, procI)
252 fileNameList cloudDirs
256 databases[procI].timePath()/regionPrefix/"lagrangian",
261 forAll (cloudDirs, i)
263 // Check if we already have cloud objects for this cloudname.
264 HashTable<IOobjectList>::const_iterator iter =
265 cloudObjects.find(cloudDirs[i]);
267 if (iter == cloudObjects.end())
269 // Do local scan for valid cloud objects.
270 IOobjectList sprayObjs
272 procMeshes.meshes()[procI],
273 databases[procI].timeName(),
274 "lagrangian"/cloudDirs[i]
277 IOobject* positionsPtr = sprayObjs.lookup("positions");
281 cloudObjects.insert(cloudDirs[i], sprayObjs);
288 if (cloudObjects.size() > 0)
290 // Pass2: reconstruct the cloud
291 forAllConstIter(HashTable<IOobjectList>, cloudObjects, iter)
293 const word cloudName = string::validate<word>(iter.key());
295 // Objects (on arbitrary processor)
296 const IOobjectList& sprayObjs = iter();
298 Info<< "Reconstructing lagrangian fields for cloud "
299 << cloudName << nl << endl;
301 reconstructLagrangianPositions
306 procMeshes.faceProcAddressing(),
307 procMeshes.cellProcAddressing()
309 reconstructLagrangianFields<label>
316 reconstructLagrangianFields<scalar>
323 reconstructLagrangianFields<vector>
330 reconstructLagrangianFields<sphericalTensor>
337 reconstructLagrangianFields<symmTensor>
344 reconstructLagrangianFields<tensor>
355 Info << "No lagrangian fields" << nl << endl;
358 // If there are any "uniform" directories copy them from
359 // the master processor.
361 fileName uniformDir0 = databases[0].timePath()/"uniform";
362 if (dir(uniformDir0))
364 cp(uniformDir0, runTime.timePath());
368 Info<< "End.\n" << endl;
374 // ************************************************************************* //