sampledSurfaces.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2016 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 \*---------------------------------------------------------------------------*/
25 
26 #include "sampledSurfaces.H"
27 #include "volFields.H"
28 #include "dictionary.H"
29 #include "Time.H"
30 #include "IOmanip.H"
31 #include "volPointInterpolation.H"
32 #include "PatchTools.H"
33 #include "mapPolyMesh.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(sampledSurfaces, 0);
41 
43  (
44  functionObject,
45  sampledSurfaces,
46  dictionary
47  );
48 }
49 
50 bool Foam::sampledSurfaces::verbose_ = false;
51 Foam::scalar Foam::sampledSurfaces::mergeTol_ = 1e-10;
52 
53 
54 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
55 
56 void Foam::sampledSurfaces::writeGeometry() const
57 {
58  // Write to time directory under outputPath_
59  // Skip surface without faces (eg, a failed cut-plane)
60 
61  const fileName outputDir = outputPath_/mesh_.time().timeName();
62 
63  forAll(*this, surfI)
64  {
65  const sampledSurface& s = operator[](surfI);
66 
67  if (Pstream::parRun())
68  {
69  if (Pstream::master() && mergeList_[surfI].faces.size())
70  {
71  formatter_->write
72  (
73  outputDir,
74  s.name(),
75  mergeList_[surfI].points,
76  mergeList_[surfI].faces
77  );
78  }
79  }
80  else if (s.faces().size())
81  {
82  formatter_->write
83  (
84  outputDir,
85  s.name(),
86  s.points(),
87  s.faces()
88  );
89  }
90  }
91 }
92 
93 
94 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
95 
96 Foam::sampledSurfaces::sampledSurfaces
97 (
98  const word& name,
99  const Time& t,
100  const dictionary& dict
101 )
102 :
103  functionObject(name),
105  mesh_
106  (
107  refCast<const fvMesh>
108  (
110  (
112  )
113  )
114  ),
115  loadFromFiles_(false),
116  outputPath_(fileName::null),
117  fieldSelection_(),
118  interpolationScheme_(word::null),
119  mergeList_(),
120  formatter_(NULL)
121 {
122  if (Pstream::parRun())
123  {
124  outputPath_ = mesh_.time().path()/".."/"postProcessing"/name;
125  }
126  else
127  {
128  outputPath_ = mesh_.time().path()/"postProcessing"/name;
129  }
130 
131  read(dict);
132 }
133 
134 
135 Foam::sampledSurfaces::sampledSurfaces
136 (
137  const word& name,
138  const objectRegistry& obr,
139  const dictionary& dict,
140  const bool loadFromFiles
141 )
142 :
143  functionObject(name),
145  mesh_(refCast<const fvMesh>(obr)),
146  loadFromFiles_(loadFromFiles),
147  outputPath_(fileName::null),
148  fieldSelection_(),
149  interpolationScheme_(word::null),
150  mergeList_(),
151  formatter_(NULL)
152 {
153  if (Pstream::parRun())
154  {
155  outputPath_ = mesh_.time().path()/".."/"postProcessing"/name;
156  }
157  else
158  {
159  outputPath_ = mesh_.time().path()/"postProcessing"/name;
160  }
161 
162  read(dict);
163 }
164 
165 
166 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
167 
169 {}
170 
171 
172 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
173 
174 void Foam::sampledSurfaces::verbose(const bool verbosity)
175 {
176  verbose_ = verbosity;
177 }
178 
179 
181 {
182  return true;
183 }
184 
185 
187 {
188  if (size())
189  {
190  // Finalize surfaces, merge points etc.
191  update();
192 
193  const label nFields = classifyFields();
194 
195  if (Pstream::master())
196  {
197  if (debug)
198  {
199  Pout<< "Creating directory "
200  << outputPath_/mesh_.time().timeName() << nl << endl;
201 
202  }
203 
204  mkDir(outputPath_/mesh_.time().timeName());
205  }
206 
207  // Write geometry first if required,
208  // or when no fields would otherwise be written
209  if (nFields == 0 || formatter_->separateGeometry())
210  {
211  writeGeometry();
212  }
213 
214  const IOobjectList objects(mesh_, mesh_.time().timeName());
215 
216  sampleAndWrite<volScalarField>(objects);
217  sampleAndWrite<volVectorField>(objects);
218  sampleAndWrite<volSphericalTensorField>(objects);
219  sampleAndWrite<volSymmTensorField>(objects);
220  sampleAndWrite<volTensorField>(objects);
221 
222  sampleAndWrite<surfaceScalarField>(objects);
223  sampleAndWrite<surfaceVectorField>(objects);
224  sampleAndWrite<surfaceSphericalTensorField>(objects);
225  sampleAndWrite<surfaceSymmTensorField>(objects);
226  sampleAndWrite<surfaceTensorField>(objects);
227  }
228 
229  return true;
230 }
231 
232 
234 {
235  bool surfacesFound = dict.found("surfaces");
236 
237  if (surfacesFound)
238  {
239  dict.lookup("fields") >> fieldSelection_;
240 
241  dict.lookup("interpolationScheme") >> interpolationScheme_;
242  const word writeType(dict.lookup("surfaceFormat"));
243 
244  // Define the surface formatter
245  // Optionally defined extra controls for the output formats
246  formatter_ = surfaceWriter::New
247  (
248  writeType,
249  dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType)
250  );
251 
253  (
254  dict.lookup("surfaces"),
255  sampledSurface::iNew(mesh_)
256  );
257  transfer(newList);
258 
259  if (Pstream::parRun())
260  {
261  mergeList_.setSize(size());
262  }
263 
264  // Ensure all surfaces and merge information are expired
265  expire();
266 
267  if (this->size())
268  {
269  Info<< "Reading surface description:" << nl;
270  forAll(*this, surfI)
271  {
272  Info<< " " << operator[](surfI).name() << nl;
273  }
274  Info<< endl;
275  }
276  }
277 
278  if (Pstream::master() && debug)
279  {
280  Pout<< "sample fields:" << fieldSelection_ << nl
281  << "sample surfaces:" << nl << "(" << nl;
282 
283  forAll(*this, surfI)
284  {
285  Pout<< " " << operator[](surfI) << endl;
286  }
287  Pout<< ")" << endl;
288  }
289 
290  return true;
291 }
292 
293 
295 {
296  if (&mpm.mesh() == &mesh_)
297  {
298  expire();
299  }
300 
301  // pointMesh and interpolation will have been reset in mesh.update
302 }
303 
304 
306 {
307  if (&mesh == &mesh_)
308  {
309  expire();
310  }
311 }
312 
313 
315 {
316  if (state != polyMesh::UNCHANGED)
317  {
318  expire();
319  }
320 }
321 
322 
324 {
325  forAll(*this, surfI)
326  {
327  if (operator[](surfI).needsUpdate())
328  {
329  return true;
330  }
331  }
332 
333  return false;
334 }
335 
336 
338 {
339  bool justExpired = false;
340 
341  forAll(*this, surfI)
342  {
343  if (operator[](surfI).expire())
344  {
345  justExpired = true;
346  }
347 
348  // Clear merge information
349  if (Pstream::parRun())
350  {
351  mergeList_[surfI].clear();
352  }
353  }
354 
355  // true if any surfaces just expired
356  return justExpired;
357 }
358 
359 
361 {
362  bool updated = false;
363 
364  if (!needsUpdate())
365  {
366  return updated;
367  }
368 
369  // Serial: quick and easy, no merging required
370  if (!Pstream::parRun())
371  {
372  forAll(*this, surfI)
373  {
374  if (operator[](surfI).update())
375  {
376  updated = true;
377  }
378  }
379 
380  return updated;
381  }
382 
383  // Dimension as fraction of mesh bounding box
384  scalar mergeDim = mergeTol_ * mesh_.bounds().mag();
385 
386  if (Pstream::master() && debug)
387  {
388  Pout<< nl << "Merging all points within "
389  << mergeDim << " metre" << endl;
390  }
391 
392  forAll(*this, surfI)
393  {
394  sampledSurface& s = operator[](surfI);
395 
396  if (s.update())
397  {
398  updated = true;
399  }
400  else
401  {
402  continue;
403  }
404 
406  (
407  mergeDim,
409  (
410  SubList<face>(s.faces(), s.faces().size()),
411  s.points()
412  ),
413  mergeList_[surfI].points,
414  mergeList_[surfI].faces,
415  mergeList_[surfI].pointsMap
416  );
417  }
418 
419  return updated;
420 }
421 
422 
423 // ************************************************************************* //
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< Face, FaceList, PointField, PointType > &p, Field< PointType > &mergedPoints, List< Face > &mergedFaces, labelList &pointMergeMap)
Gather points and faces onto master and merge into single patch.
virtual bool write()
Sample and write.
virtual bool read(const dictionary &)
Read the sampledSurfaces dictionary.
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
virtual bool update()
Update the surfaces as required and merge surface points (parallel).
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:50
const double e
Elementary charge.
Definition: doubleFloat.H:78
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
An abstract class for surfaces with sampling.
dictionary subOrEmptyDict(const word &, const bool mustRead=false) const
Find and return a sub-dictionary as a copy, or.
Definition: dictionary.C:668
virtual void updateMesh(const mapPolyMesh &)
Update for changes of mesh - expires the surfaces.
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
static const fileName null
An empty fileName.
Definition: fileName.H:97
static word defaultRegion
Return the default region name.
Definition: polyMesh.H:306
void verbose(const bool verbosity=true)
Set verbosity level.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:411
virtual void readUpdate(const polyMesh::readUpdateState state)
Update for changes of mesh due to readUpdate - expires the surfaces.
virtual ~sampledSurfaces()
Destructor.
Abstract base-class for Time/database function objects.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:158
Macros for easy insertion into run-time selection tables.
virtual const faceList & faces() const =0
Faces of surface.
const Type & lookupObject(const word &name) const
Lookup and return the object of the given Type.
A list of faces which address into the list of points.
A List obtained as a section of another List.
Definition: SubList.H:53
bool read(const char *, int32_t &)
Definition: int32IO.C:85
dynamicFvMesh & mesh
const pointField & points
A class for handling words, derived from string.
Definition: word.H:59
static const word null
An empty word.
Definition: word.H:77
virtual bool needsUpdate() const
Does any of the surfaces need an update?
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:306
virtual bool update()=0
Update the surface as required.
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
Istream and Ostream manipulators taking arguments.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
virtual void movePoints(const polyMesh &)
Update for mesh point-motion - expires the surfaces.
static const char nl
Definition: Ostream.H:262
defineTypeNameAndDebug(combustionModel, 0)
virtual bool execute()
Execute, currently does nothing.
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
Definition: POSIX.C:295
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:393
virtual const pointField & points() const =0
Points of surface.
virtual bool expire()
Mark the surfaces as needing an update.
messageStream Info
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
readUpdateState
Enumeration defining the state of the mesh after a read update.
Definition: polyMesh.H:88
Registry of regIOobjects.
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
static autoPtr< surfaceWriter > New(const word &writeType)
Return a reference to the selected surfaceWriter.
Definition: surfaceWriter.C:55
Class used for the PtrLists read-construction.
const polyMesh & mesh() const
Return polyMesh.
Definition: mapPolyMesh.H:357
Namespace for OpenFOAM.
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:451