surfaceWriter.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2019 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "surfaceWriter.H"
29 #include "proxySurfaceWriter.H"
30 #include "MeshedSurfaceProxy.H"
31 
32 #include "Time.H"
33 #include "globalIndex.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(surfaceWriter, 0);
41  defineRunTimeSelectionTable(surfaceWriter, word);
42  defineRunTimeSelectionTable(surfaceWriter, wordDict);
43 }
44 
45 Foam::scalar Foam::surfaceWriter::defaultMergeDim = 1e-8;
46 
48 
49 
50 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
51 
53 {
54  return
55  (
56  wordConstructorTablePtr_->found(writeType)
57  || wordDictConstructorTablePtr_->found(writeType)
59  );
60 }
61 
62 
64 Foam::surfaceWriter::New(const word& writeType)
65 {
66  // Constructors without dictionary options
67  auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
68 
69  if (!cstrIter.found())
70  {
72  {
73  // Generally unknown, but handle via 'proxy' handler
75  (
76  new surfaceWriters::proxyWriter(writeType)
77  );
78  }
79 
81  << "Unknown write type \"" << writeType << "\"\n\n"
82  << "Valid write types : "
83  << flatOutput(wordConstructorTablePtr_->sortedToc()) << nl
84  << "Valid proxy types : "
86  << exit(FatalError);
87  }
88 
89  return autoPtr<surfaceWriter>(cstrIter()());
90 }
91 
92 
95 (
96  const word& writeType,
97  const dictionary& writeOpts
98 )
99 {
100  // Constructors with dictionary options
101  auto cstrIter2 = wordDictConstructorTablePtr_->cfind(writeType);
102 
103  if (cstrIter2.found())
104  {
105  return autoPtr<surfaceWriter>(cstrIter2()(writeOpts));
106  }
107 
108  // Constructors without dictionary options
109  auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
110 
111  if (!cstrIter.found())
112  {
114  {
115  // Generally unknown, but handle via 'proxy' handler
117  (
118  new surfaceWriters::proxyWriter(writeType, writeOpts)
119  );
120  }
121 
123  << "Unknown write type \"" << writeType << "\"\n\n"
124  << "Valid write types : "
125  << wordConstructorTablePtr_->sortedToc() << nl
126  << "Valid proxy types : "
128  << exit(FatalError);
129  }
130 
131  return autoPtr<surfaceWriter>(cstrIter()());
132 }
133 
134 
135 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
136 
138 :
139  surf_(std::cref<meshedSurf>(emptySurface_)),
140  surfComp_(),
141  useComponents_(false),
142  upToDate_(false),
143  wroteGeom_(false),
144  parallel_(true),
145  useTimeDir_(false),
146  isPointData_(false),
147  verbose_(false),
148  nFields_(0),
149  mergeDim_(defaultMergeDim),
150  merged_(),
151  currTime_(),
152  outputPath_()
153 {
155 }
156 
157 
159 :
160  surfaceWriter()
161 {
162  options.readIfPresent("verbose", verbose_);
163 }
164 
165 
167 (
168  const meshedSurf& surf,
169  bool parallel,
170  const dictionary& options
171 )
172 :
173  surfaceWriter(options)
174 {
175  setSurface(surf, parallel);
176 }
177 
178 
180 (
181  const pointField& points,
182  const faceList& faces,
183  bool parallel,
184  const dictionary& options
185 )
186 :
187  surfaceWriter(options)
188 {
189  setSurface(points, faces, parallel);
190 }
191 
192 
193 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
194 
196 {
197  close();
198 }
199 
200 
201 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
202 
204 {
205  currTime_ = inst;
206 }
207 
208 
209 void Foam::surfaceWriter::setTime(scalar timeValue)
210 {
211  currTime_ = instant(timeValue);
212 }
213 
214 
215 void Foam::surfaceWriter::setTime(scalar timeValue, const word& timeName)
216 {
217  currTime_.value() = timeValue;
218  currTime_.name() = timeName;
219 }
220 
221 
223 {
224  currTime_.value() = 0;
225  currTime_.name().clear();
226 }
227 
228 
230 {
231  setTime(t.value(), t.timeName());
232 }
233 
234 
236 {
237  setTime(inst);
238 }
239 
240 
242 {
243  unsetTime();
244 }
245 
246 
247 void Foam::surfaceWriter::open(const fileName& outputPath)
248 {
249  outputPath_ = outputPath;
250  wroteGeom_ = false;
251 }
252 
253 
255 (
256  const meshedSurf& surf,
257  const fileName& outputPath,
258  bool parallel
259 )
260 {
261  close();
262  setSurface(surf, parallel);
263  open(outputPath);
264 }
265 
266 
268 (
269  const pointField& points,
270  const faceList& faces,
271  const fileName& outputPath,
272  bool parallel
273 )
274 {
275  close();
276  setSurface(points, faces, parallel);
277  open(outputPath);
278 }
279 
280 
282 (
283  const meshedSurf& surf,
284  const fileName& outputPath
285 )
286 {
287  close();
288  setSurface(surf, parallel_);
289  open(outputPath);
290 }
291 
292 
294 (
295  const pointField& points,
296  const faceList& faces,
297  const fileName& outputPath
298 )
299 {
300  close();
301  setSurface(points, faces, parallel_);
302  open(outputPath);
303 }
304 
305 
307 {
308  outputPath_.clear();
309  wroteGeom_ = false;
310 }
311 
312 
314 {
315  close();
316  expire();
317  useComponents_ = false;
318  surf_ = std::cref<meshedSurf>(emptySurface_);
319  surfComp_.clear();
320 }
321 
322 
324 (
325  const meshedSurf& surf,
326  bool parallel
327 )
328 {
329  expire();
330  useComponents_ = false;
331  surf_ = std::cref<meshedSurf>(surf);
332  surfComp_.clear();
333  parallel_ = (parallel && Pstream::parRun());
334 }
335 
336 
338 (
339  const pointField& points,
340  const faceList& faces,
341  bool parallel
342 )
343 {
344  expire();
345  useComponents_ = true;
346  surf_ = std::cref<meshedSurf>(emptySurface_);
347  surfComp_.reset(points, faces);
348  parallel_ = (parallel && Pstream::parRun());
349 }
350 
351 
353 (
354  const meshedSurf& surf
355 )
356 {
357  setSurface(surf, parallel_);
358 }
359 
360 
362 (
363  const pointField& points,
364  const faceList& faces
365 )
366 {
367  setSurface(points, faces, parallel_);
368 }
369 
370 
372 {
373  return !upToDate_;
374 }
375 
376 
378 {
379  return wroteGeom_;
380 }
381 
382 
384 {
385  const bool changed = upToDate_;
386 
387  upToDate_ = false;
388  wroteGeom_ = false;
389  merged_.clear();
390 
391  // Field count (nFields_) is a different type of accounting
392  // and is unaffected by geometry changes
393 
394  return changed;
395 }
396 
397 
399 {
400  return (useComponents_ || (&emptySurface_ != &(surf_.get())));
401 }
402 
403 
405 {
406  const bool value =
407  (
408  useComponents_
409  ? surfComp_.faces().empty()
410  : surf_.get().faces().empty()
411  );
412 
413  return (parallel_ ? returnReduce(value, andOp<bool>()) : value);
414 }
415 
416 
417 Foam::label Foam::surfaceWriter::size() const
418 {
419  const bool value =
420  (
421  useComponents_
422  ? surfComp_.faces().empty()
423  : surf_.get().faces().empty()
424  );
425 
426  return (parallel_ ? returnReduce(value, sumOp<label>()) : value);
427 }
428 
429 
431 {
432  if (outputPath_.empty())
433  {
435  << type() << " : Attempted to write without a path" << nl
436  << exit(FatalIOError);
437  }
438 
439  return !outputPath_.empty();
440 }
441 
442 
444 {
445  bool changed = false;
446 
447  if (parallel_ && Pstream::parRun() && !upToDate_)
448  {
449  if (useComponents_)
450  {
451  changed = merged_.merge(surfComp_, mergeDim_);
452  }
453  else
454  {
455  changed = merged_.merge(surf_.get(), mergeDim_);
456  }
457  }
458  upToDate_ = true;
459 
460  if (changed)
461  {
462  wroteGeom_ = false;
463  }
464 
465  return changed;
466 }
467 
468 
470 {
471  merge();
472 
473  if (parallel_ && Pstream::parRun())
474  {
475  return merged_;
476  }
477 
478  if (useComponents_)
479  {
480  return surfComp_;
481  }
482  else
483  {
484  return surf_.get();
485  }
486 }
487 
488 
489 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
490 
491 template<class Type>
493 (
494  const Field<Type>& fld
495 ) const
496 {
497  if (parallel_ && Pstream::parRun())
498  {
499  // Ensure geometry is also merged
500  merge();
501 
502  // Gather all values
503  auto tfield = tmp<Field<Type>>::New();
504  auto& allFld = tfield.ref();
505 
506  globalIndex::gatherOp(fld, allFld);
507 
508  // Renumber (point data) to correspond to merged points
509  if
510  (
512  && this->isPointData()
513  && merged_.pointsMap().size()
514  )
515  {
516  inplaceReorder(merged_.pointsMap(), allFld);
517  allFld.resize(merged_.points().size());
518  }
519 
520  return tfield;
521  }
522 
523  // Mark that any geometry changes have been taken care of
524  upToDate_ = true;
525 
526  return fld;
527 }
528 
529 
530 #define defineSurfaceWriterMergeMethod(ThisClass, Type) \
531  Foam::tmp<Foam::Field<Type>> \
532  ThisClass::mergeField(const Field<Type>& fld) const \
533  { \
534  return mergeFieldTemplate(fld); \
535  }
536 
543 
544 #undef defineSurfaceWriterMergeMethod
545 
546 
547 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
548 
549 Foam::Ostream& Foam::operator<<
550 (
551  Ostream& os,
552  const InfoProxy<surfaceWriter>& ip
553 )
554 {
555  const surfaceWriter& w = ip.t_;
556 
557  os << "surfaceWriter:"
558  << " upToDate: " << w.upToDate_
559  << " PointData: " << w.isPointData_
560  << " nFields: " << w.nFields_
561  << " time: " << w.currTime_
562  << " path: " << w.outputPath_ << endl;
563 
564  return os;
565 }
566 
567 
568 // ************************************************************************* //
Foam::Tensor< scalar >
Foam::SymmTensor< scalar >
MeshedSurfaceProxy.H
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::InfoProxy
A helper class for outputting values to Ostream.
Definition: InfoProxy.H:47
Foam::surfaceWriter
Base class for surface writers.
Definition: surfaceWriter.H:111
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
proxySurfaceWriter.H
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::surfaceWriter::defaultMergeDim
static scalar defaultMergeDim
The default merge dimension (1e-8)
Definition: surfaceWriter.H:218
Foam::surfaceWriter::unsetTime
void unsetTime()
Clear the current time.
Definition: surfaceWriter.C:222
Foam::surfaceWriter::merge
virtual bool merge() const
Definition: surfaceWriter.C:443
globalIndex.H
Foam::surfaceWriter::setSurface
virtual void setSurface(const meshedSurf &surf, bool parallel)
Definition: surfaceWriter.C:324
Foam::UPstream::parRun
static bool & parRun()
Test if this a parallel run, or allow modify access.
Definition: UPstream.H:434
Foam::surfaceWriter::setTime
void setTime(const instant &inst)
Set the current time.
Definition: surfaceWriter.C:203
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::surfaceWriter::clear
virtual void clear()
Definition: surfaceWriter.C:313
Foam::surfaceWriter::surface
const meshedSurf & surface() const
Definition: surfaceWriter.C:469
Foam::meshedSurf
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:49
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:458
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::surfaceWriter::size
label size() const
The global number of faces for the associated surface.
Definition: surfaceWriter.C:417
Foam::dimensioned::value
const Type & value() const
Return const reference to value.
Definition: dimensionedType.C:434
surfaceWriter.H
setTime
runTimeSource setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex)
Foam::surfaceWriter::emptySurface_
static const meshedSurf::emptySurface emptySurface_
Placeholder.
Definition: surfaceWriter.H:118
Foam::MeshedSurfaceProxy
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
Definition: MeshedSurface.H:82
Foam::sumOp
Definition: ops.H:213
Foam::surfaceWriter::empty
bool empty() const
The surface to write is empty if the global number of faces is zero.
Definition: surfaceWriter.C:404
Foam::surfaceWriters::proxyWriter
A surfaceWriter that writes the geometry via the MeshedSurfaceProxy, but which does not support any f...
Definition: proxySurfaceWriter.H:92
Foam::surfaceWriter::endTime
virtual void endTime()
End a time-step.
Definition: surfaceWriter.C:241
Foam::surfaceWriter::upToDate_
bool upToDate_
The topology/surface is up-to-date?
Definition: surfaceWriter.H:133
Foam::surfaceWriter::beginTime
virtual void beginTime(const Time &t)
Begin a time-step.
Definition: surfaceWriter.C:229
Foam::Field< vector >
Foam::surfaceWriter::nFields_
label nFields_
The number of fields.
Definition: surfaceWriter.H:151
Foam::surfaceWriter::checkOpen
bool checkOpen() const
Verify that the outputPath_ has been set or FatalError.
Definition: surfaceWriter.C:430
Foam::surfaceWriter::surfaceWriter
surfaceWriter()
Construct null.
Definition: surfaceWriter.C:137
Foam::surfaceWriter::needsUpdate
virtual bool needsUpdate() const
Does the writer need an update (eg, lagging behind surface changes)
Definition: surfaceWriter.C:371
Foam::andOp
Definition: ops.H:233
Foam::globalIndex::gatherOp
static void gatherOp(const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Collect data in processor order on master.
Definition: globalIndexTemplates.C:208
fld
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Definition: gmvOutputLagrangian.H:23
Foam::surfaceWriter::outputPath_
fileName outputPath_
The full output directory and file (surface) name.
Definition: surfaceWriter.H:163
Foam::surfaceWriter::wroteData
virtual bool wroteData() const
Geometry or fields written since the last open?
Definition: surfaceWriter.C:377
timeName
word timeName
Definition: getTimeIndex.H:3
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::surfaceWriter::expire
virtual bool expire()
Definition: surfaceWriter.C:383
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::flatOutput
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:217
Foam::surfaceWriter::isPointData_
bool isPointData_
Is point vs cell data.
Definition: surfaceWriter.H:145
Foam::SphericalTensor< scalar >
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
Foam::meshedSurf::emptySurface
A concrete meshedSurf class without faces, points, etc.
Definition: meshedSurf.H:95
Time.H
Foam::autoPtr< Foam::surfaceWriter >
Foam::MeshedSurfaceProxy::writeTypes
static wordHashSet writeTypes()
The file format types that can be written via MeshedSurfaceProxy.
Definition: MeshedSurfaceProxy.C:39
Foam::surfaceWriter::currTime_
instant currTime_
The current time value/name.
Definition: surfaceWriter.H:160
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::surfaceWriter::New
static autoPtr< surfaceWriter > New(const word &writeType)
Return a reference to the selected surfaceWriter.
Definition: surfaceWriter.C:64
Foam::Vector< scalar >
Foam::List< face >
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::surfaceWriter::~surfaceWriter
virtual ~surfaceWriter()
Destructor. Calls close()
Definition: surfaceWriter.C:195
Foam::surfaceWriter::hasSurface
bool hasSurface() const
Writer is associated with a surface.
Definition: surfaceWriter.C:398
Foam::inplaceReorder
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Definition: ListOpsTemplates.C:124
defineSurfaceWriterMergeMethod
#define defineSurfaceWriterMergeMethod(ThisClass, Type)
Definition: surfaceWriter.C:530
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::surfaceWriter::mergeFieldTemplate
tmp< Field< Type > > mergeFieldTemplate(const Field< Type > &fld) const
Gather (merge) fields with renumbering and shrinking for point data.
Foam::surfaceWriter::verbose_
bool verbose_
Additional output verbosity.
Definition: surfaceWriter.H:148
Foam::surfaceWriter::close
virtual void close()
Finish output, performing any necessary cleanup.
Definition: surfaceWriter.C:306
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::surfaceWriter::supportedType
static bool supportedType(const word &writeType)
True if New is likely to succeed for this writeType.
Definition: surfaceWriter.C:52
Foam::surfaceWriter::open
virtual void open(const fileName &outputPath)
Open for output on specified path, using existing surface.
Definition: surfaceWriter.C:247
Foam::MeshedSurfaceProxy::canWriteType
static bool canWriteType(const word &fileType, bool verbose=false)
Can this file format type be written via MeshedSurfaceProxy?
Definition: MeshedSurfaceProxy.C:47
Foam::dictionary::readIfPresent
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:417