subsetMesh.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 Application
25  subsetMesh
26 
27 Description
28  Selects a section of mesh based on a cellSet.
29 
30  The utility sub-sets the mesh to choose only a part of interest. Check
31  the setSet/cellSet/topoSet utilities to see how to select cells based on
32  various shapes.
33 
34  The mesh will subset all points, faces and cells needed to make a sub-mesh
35  but will not preserve attached boundary types.
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #include "fvMeshSubset.H"
40 #include "argList.H"
41 #include "cellSet.H"
42 #include "IOobjectList.H"
43 #include "volFields.H"
44 
45 using namespace Foam;
46 
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 
49 
50 template<class Type>
51 void subsetVolFields
52 (
53  const fvMeshSubset& subsetter,
54  const wordList& fieldNames,
56 )
57 {
58  const fvMesh& baseMesh = subsetter.baseMesh();
59 
60  forAll(fieldNames, i)
61  {
62  const word& fieldName = fieldNames[i];
63 
64  Info<< "Subsetting field " << fieldName << endl;
65 
67  (
68  IOobject
69  (
70  fieldName,
71  baseMesh.time().timeName(),
72  baseMesh,
75  ),
76  baseMesh
77  );
78 
79  subFields.set(i, subsetter.interpolate(fld));
80  }
81 }
82 
83 
84 template<class Type>
85 void subsetSurfaceFields
86 (
87  const fvMeshSubset& subsetter,
88  const wordList& fieldNames,
90 )
91 {
92  const fvMesh& baseMesh = subsetter.baseMesh();
93 
94  forAll(fieldNames, i)
95  {
96  const word& fieldName = fieldNames[i];
97 
98  Info<< "Subsetting field " << fieldName << endl;
99 
101  (
102  IOobject
103  (
104  fieldName,
105  baseMesh.time().timeName(),
106  baseMesh,
109  ),
110  baseMesh
111  );
112 
113  subFields.set(i, subsetter.interpolate(fld));
114  }
115 }
116 
117 
118 template<class Type>
119 void subsetPointFields
120 (
121  const fvMeshSubset& subsetter,
122  const pointMesh& pMesh,
123  const wordList& fieldNames,
125 )
126 {
127  const fvMesh& baseMesh = subsetter.baseMesh();
128 
129  forAll(fieldNames, i)
130  {
131  const word& fieldName = fieldNames[i];
132 
133  Info<< "Subsetting field " << fieldName << endl;
134 
136  (
137  IOobject
138  (
139  fieldName,
140  baseMesh.time().timeName(),
141  baseMesh,
144  ),
145  pMesh
146  );
147 
148  subFields.set(i, subsetter.interpolate(fld));
149  }
150 }
151 
152 
153 template<class Type>
154 void subsetDimensionedFields
155 (
156  const fvMeshSubset& subsetter,
157  const wordList& fieldNames,
159 )
160 {
161  const fvMesh& baseMesh = subsetter.baseMesh();
162 
163  forAll(fieldNames, i)
164  {
165  const word& fieldName = fieldNames[i];
166 
167  Info<< "Subsetting field " << fieldName << endl;
168 
170  (
171  IOobject
172  (
173  fieldName,
174  baseMesh.time().timeName(),
175  baseMesh,
178  ),
179  baseMesh
180  );
181 
182  subFields.set(i, subsetter.interpolate(fld));
183  }
184 }
185 
186 
187 
188 int main(int argc, char *argv[])
189 {
191  (
192  "select a mesh subset based on a cellSet"
193  );
194 
195  #include "addOverwriteOption.H"
196  #include "addRegionOption.H"
197  argList::validArgs.append("cellSet");
199  (
200  "patch",
201  "name",
202  "add exposed internal faces to specified patch instead of to "
203  "'oldInternalFaces'"
204  );
206  (
207  "resultTime",
208  "time",
209  "specify a time for the resulting mesh"
210  );
212  (
213  "noFields",
214  "do not update fields"
215  );
216 
217  #include "setRootCase.H"
218  #include "createTime.H"
220 
221  Foam::word meshRegionName = polyMesh::defaultRegion;
222  args.optionReadIfPresent("region", meshRegionName);
223 
224  #include "createNamedMesh.H"
225 
226 
227  const word setName = args[1];
228 
229  word meshInstance = mesh.pointsInstance();
230  word fieldsInstance = runTime.timeName();
231 
232  const bool overwrite = args.optionFound("overwrite");
233  const bool specifiedInstance = args.optionReadIfPresent
234  (
235  "resultTime",
236  fieldsInstance
237  );
238  if (specifiedInstance)
239  {
240  // Set both mesh and field to this time
241  meshInstance = fieldsInstance;
242  }
243  const bool fields = !args.optionFound("noFields");
244 
245 
246  Info<< "Reading cell set from " << setName << endl << endl;
247 
248  // Create mesh subsetting engine
249  fvMeshSubset subsetter(mesh);
250 
251  label patchi = -1;
252 
253  if (args.optionFound("patch"))
254  {
255  const word patchName = args["patch"];
256 
257  patchi = mesh.boundaryMesh().findPatchID(patchName);
258 
259  if (patchi == -1)
260  {
262  << nl << "Valid patches are " << mesh.boundaryMesh().names()
263  << exit(FatalError);
264  }
265 
266  Info<< "Adding exposed internal faces to patch " << patchName << endl
267  << endl;
268  }
269  else
270  {
271  Info<< "Adding exposed internal faces to a patch called"
272  << " \"oldInternalFaces\" (created if necessary)" << endl
273  << endl;
274  }
275 
276 
277  cellSet currentSet(mesh, setName);
278  subsetter.setLargeCellSubset(currentSet, patchi, true);
279 
280 
281  if (fields)
282  {
284 
285  // Read vol fields and subset
286  // ~~~~~~~~~~~~~~~~~~~~~~~~~~
287 
288  wordList scalarNames(objects.names(volScalarField::typeName));
289  PtrList<volScalarField> scalarFlds(scalarNames.size());
290  subsetVolFields(subsetter, scalarNames, scalarFlds);
291 
292  wordList vectorNames(objects.names(volVectorField::typeName));
293  PtrList<volVectorField> vectorFlds(vectorNames.size());
294  subsetVolFields(subsetter, vectorNames, vectorFlds);
295 
296  wordList sphericalTensorNames
297  (
299  );
300  PtrList<volSphericalTensorField> sphericalTensorFlds
301  (
302  sphericalTensorNames.size()
303  );
304  subsetVolFields(subsetter, sphericalTensorNames, sphericalTensorFlds);
305 
306  wordList symmTensorNames(objects.names(volSymmTensorField::typeName));
307  PtrList<volSymmTensorField> symmTensorFlds(symmTensorNames.size());
308  subsetVolFields(subsetter, symmTensorNames, symmTensorFlds);
309 
310  wordList tensorNames(objects.names(volTensorField::typeName));
311  PtrList<volTensorField> tensorFlds(tensorNames.size());
312  subsetVolFields(subsetter, tensorNames, tensorFlds);
313 
314 
315  // Read surface fields and subset
316  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
317 
318  wordList surfScalarNames(objects.names(surfaceScalarField::typeName));
319  PtrList<surfaceScalarField> surfScalarFlds(surfScalarNames.size());
320  subsetSurfaceFields(subsetter, surfScalarNames, surfScalarFlds);
321 
322  wordList surfVectorNames(objects.names(surfaceVectorField::typeName));
323  PtrList<surfaceVectorField> surfVectorFlds(surfVectorNames.size());
324  subsetSurfaceFields(subsetter, surfVectorNames, surfVectorFlds);
325 
326  wordList surfSphericalTensorNames
327  (
329  );
330  PtrList<surfaceSphericalTensorField> surfSphericalTensorFlds
331  (
332  surfSphericalTensorNames.size()
333  );
334  subsetSurfaceFields
335  (
336  subsetter,
337  surfSphericalTensorNames,
338  surfSphericalTensorFlds
339  );
340 
341  wordList surfSymmTensorNames
342  (
344  );
345  PtrList<surfaceSymmTensorField> surfSymmTensorFlds
346  (
347  surfSymmTensorNames.size()
348  );
349  subsetSurfaceFields(subsetter, surfSymmTensorNames, surfSymmTensorFlds);
350 
351  wordList surfTensorNames(objects.names(surfaceTensorField::typeName));
352  PtrList<surfaceTensorField> surfTensorFlds(surfTensorNames.size());
353  subsetSurfaceFields(subsetter, surfTensorNames, surfTensorFlds);
354 
355 
356  // Read point fields and subset
357  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
358 
359  const pointMesh& pMesh = pointMesh::New(mesh);
360 
361  wordList pointScalarNames(objects.names(pointScalarField::typeName));
362  PtrList<pointScalarField> pointScalarFlds(pointScalarNames.size());
363  subsetPointFields(subsetter, pMesh, pointScalarNames, pointScalarFlds);
364 
365  wordList pointVectorNames(objects.names(pointVectorField::typeName));
366  PtrList<pointVectorField> pointVectorFlds(pointVectorNames.size());
367  subsetPointFields(subsetter, pMesh, pointVectorNames, pointVectorFlds);
368 
369  wordList pointSphericalTensorNames
370  (
372  );
373  PtrList<pointSphericalTensorField> pointSphericalTensorFlds
374  (
375  pointSphericalTensorNames.size()
376  );
377  subsetPointFields
378  (
379  subsetter,
380  pMesh,
381  pointSphericalTensorNames,
382  pointSphericalTensorFlds
383  );
384 
385  wordList pointSymmTensorNames
386  (
388  );
389  PtrList<pointSymmTensorField> pointSymmTensorFlds
390  (
391  pointSymmTensorNames.size()
392  );
393  subsetPointFields
394  (
395  subsetter,
396  pMesh,
397  pointSymmTensorNames,
398  pointSymmTensorFlds
399  );
400 
401  wordList pointTensorNames(objects.names(pointTensorField::typeName));
402  PtrList<pointTensorField> pointTensorFlds(pointTensorNames.size());
403  subsetPointFields(subsetter, pMesh, pointTensorNames, pointTensorFlds);
404 
405 
406  // Read dimensioned fields and subset
407  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
408 
409  typedef volScalarField::Internal dimScalType;
410  wordList scalarDimNames(objects.names(dimScalType::typeName));
411  PtrList<dimScalType> scalarDimFlds(scalarDimNames.size());
412  subsetDimensionedFields(subsetter, scalarDimNames, scalarDimFlds);
413 
414  typedef volVectorField::Internal dimVecType;
415  wordList vectorDimNames(objects.names(dimVecType::typeName));
416  PtrList<dimVecType> vectorDimFlds(vectorDimNames.size());
417  subsetDimensionedFields(subsetter, vectorDimNames, vectorDimFlds);
418 
419  typedef volSphericalTensorField::Internal dimSphereType;
420  wordList sphericalTensorDimNames
421  (
422  objects.names(dimSphereType::typeName)
423  );
424  PtrList<dimSphereType> sphericalTensorDimFlds
425  (
426  sphericalTensorDimNames.size()
427  );
428  subsetDimensionedFields
429  (
430  subsetter,
431  sphericalTensorDimNames,
432  sphericalTensorDimFlds
433  );
434 
435  typedef volSymmTensorField::Internal dimSymmTensorType;
436  wordList symmTensorDimNames(objects.names(dimSymmTensorType::typeName));
437  PtrList<dimSymmTensorType> symmTensorDimFlds(symmTensorDimNames.size());
438  subsetDimensionedFields
439  (
440  subsetter,
441  symmTensorDimNames,
442  symmTensorDimFlds
443  );
444 
445  typedef volTensorField::Internal dimTensorType;
446  wordList tensorDimNames(objects.names(dimTensorType::typeName));
447  PtrList<dimTensorType> tensorDimFlds(tensorDimNames.size());
448  subsetDimensionedFields(subsetter, tensorDimNames, tensorDimFlds);
449 
450 
451  // Write mesh and fields to new time
452  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
453 
454  if (overwrite || specifiedInstance)
455  {
456  runTime.setTime(instant(fieldsInstance), 0);
457  subsetter.subMesh().setInstance(meshInstance);
458  }
459  else
460  {
461  runTime++;
462  }
463 
464  Info<< "Writing subsetted mesh and fields to time "
465  << runTime.timeName() << endl;
466 
467  subsetter.subMesh().write();
468 
469  // Subsetting adds 'subset' prefix. Rename field to be like original.
470  forAll(scalarFlds, i)
471  {
472  scalarFlds[i].rename(scalarNames[i]);
473  scalarFlds[i].write();
474  }
475  forAll(vectorFlds, i)
476  {
477  vectorFlds[i].rename(vectorNames[i]);
478  vectorFlds[i].write();
479  }
480  forAll(sphericalTensorFlds, i)
481  {
482  sphericalTensorFlds[i].rename(sphericalTensorNames[i]);
483  sphericalTensorFlds[i].write();
484  }
485  forAll(symmTensorFlds, i)
486  {
487  symmTensorFlds[i].rename(symmTensorNames[i]);
488  symmTensorFlds[i].write();
489  }
490  forAll(tensorFlds, i)
491  {
492  tensorFlds[i].rename(tensorNames[i]);
493  tensorFlds[i].write();
494  }
495 
496  // Surface ones.
497  forAll(surfScalarFlds, i)
498  {
499  surfScalarFlds[i].rename(surfScalarNames[i]);
500  surfScalarFlds[i].write();
501  }
502  forAll(surfVectorFlds, i)
503  {
504  surfVectorFlds[i].rename(surfVectorNames[i]);
505  surfVectorFlds[i].write();
506  }
507  forAll(surfSphericalTensorFlds, i)
508  {
509  surfSphericalTensorFlds[i].rename(surfSphericalTensorNames[i]);
510  surfSphericalTensorFlds[i].write();
511  }
512  forAll(surfSymmTensorFlds, i)
513  {
514  surfSymmTensorFlds[i].rename(surfSymmTensorNames[i]);
515  surfSymmTensorFlds[i].write();
516  }
517  forAll(surfTensorNames, i)
518  {
519  surfTensorFlds[i].rename(surfTensorNames[i]);
520  surfTensorFlds[i].write();
521  }
522 
523  // Point ones
524  forAll(pointScalarFlds, i)
525  {
526  pointScalarFlds[i].rename(pointScalarNames[i]);
527  pointScalarFlds[i].write();
528  }
529  forAll(pointVectorFlds, i)
530  {
531  pointVectorFlds[i].rename(pointVectorNames[i]);
532  pointVectorFlds[i].write();
533  }
534  forAll(pointSphericalTensorFlds, i)
535  {
536  pointSphericalTensorFlds[i].rename(pointSphericalTensorNames[i]);
537  pointSphericalTensorFlds[i].write();
538  }
539  forAll(pointSymmTensorFlds, i)
540  {
541  pointSymmTensorFlds[i].rename(pointSymmTensorNames[i]);
542  pointSymmTensorFlds[i].write();
543  }
544  forAll(pointTensorNames, i)
545  {
546  pointTensorFlds[i].rename(pointTensorNames[i]);
547  pointTensorFlds[i].write();
548  }
549 
550  // DimensionedFields
551  forAll(scalarDimFlds, i)
552  {
553  scalarDimFlds[i].rename(scalarDimNames[i]);
554  scalarDimFlds[i].write();
555  }
556  forAll(vectorDimFlds, i)
557  {
558  vectorDimFlds[i].rename(vectorDimNames[i]);
559  vectorDimFlds[i].write();
560  }
561  forAll(sphericalTensorDimFlds, i)
562  {
563  sphericalTensorDimFlds[i].rename(sphericalTensorDimNames[i]);
564  sphericalTensorDimFlds[i].write();
565  }
566  forAll(symmTensorDimFlds, i)
567  {
568  symmTensorDimFlds[i].rename(symmTensorDimNames[i]);
569  symmTensorDimFlds[i].write();
570  }
571  forAll(tensorDimFlds, i)
572  {
573  tensorDimFlds[i].rename(tensorDimNames[i]);
574  tensorDimFlds[i].write();
575  }
576  }
577  else
578  {
579  // Write mesh to new time
580  // ~~~~~~~~~~~~~~~~~~~~~~
581 
582  if (overwrite || specifiedInstance)
583  {
584  runTime.setTime(instant(fieldsInstance), 0);
585  subsetter.subMesh().setInstance(meshInstance);
586  }
587  else
588  {
589  runTime++;
590  }
591 
592  Info<< "Writing subsetted mesh to time "
593  << runTime.timeName() << endl;
594 
595  subsetter.subMesh().write();
596  }
597 
598  Info<< "End\n" << endl;
599 
600  return 0;
601 }
602 
603 
604 // ************************************************************************* //
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:434
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:50
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
void off()
Switch the function objects off.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
static const char *const typeName
Definition: Field.H:105
engineTime & runTime
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:309
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
bool optionFound(const word &opt) const
Return true if the named option is found.
Definition: argListI.H:108
label findPatchID(const word &patchName) const
Find patch index given a name.
static SLList< string > validArgs
A list of valid (mandatory) arguments.
Definition: argList.H:153
Generic GeometricField class.
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Definition: Time.C:626
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:239
virtual bool write(const bool write=true) const
Write mesh using IO settings from time.
Definition: fvMesh.C:1035
bool optionReadIfPresent(const word &opt, T &) const
Read a value from the named option if present.
Definition: argListI.H:198
static const pointMesh & New(const polyMesh &mesh)
Definition: MeshObject.C:44
Mesh representing a set of points created from polyMesh.
Definition: pointMesh.H:48
const fileName & pointsInstance() const
Return the current instance directory for points.
Definition: polyMesh.C:802
dynamicFvMesh & mesh
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
A class for handling words, derived from string.
Definition: word.H:59
wordList names() const
Return a list of patch names.
static void addOption(const word &opt, const string &param="", const string &usage="")
Add to an option to validOptions with usage information.
Definition: argList.C:127
virtual void setTime(const Time &)
Reset the time and time-index to those of the given time.
Definition: Time.C:873
static const char nl
Definition: Ostream.H:265
objects
Post-processing mesh subset tool. Given the original mesh and the list of selected cells...
Definition: fvMeshSubset.H:73
void setInstance(const fileName &)
Set the instance for mesh files.
Definition: polyMeshIO.C:32
An instant of time. Contains the time value and name.
Definition: instant.H:66
const fvMesh & subMesh() const
Return reference to subset mesh.
const functionObjectList & functionObjects() const
Return the list of function objects.
Definition: Time.H:410
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:70
A collection of cell labels.
Definition: cellSet.H:48
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
messageStream Info
static void addBoolOption(const word &opt, const string &usage="")
Add to a bool option to validOptions with usage information.
Definition: argList.C:117
static void addNote(const string &)
Add extra notes for the usage information.
Definition: argList.C:158
Foam::argList args(argc, argv)
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
static tmp< GeometricField< Type, fvPatchField, volMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &, const fvMesh &sMesh, const labelList &patchMap, const labelList &cellMap, const labelList &faceMap)
Map volume field.
void setLargeCellSubset(const labelList &region, const label currentRegion, const label patchID=-1, const bool syncCouples=true)
Set the subset from all cells with region == currentRegion.
Definition: fvMeshSubset.C:885
const fvMesh & baseMesh() const
Original mesh.
Definition: fvMeshSubset.H:214
Namespace for OpenFOAM.