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-2021 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* ctorPtr = wordConstructorTable(writeType);
68 
69  if (!ctorPtr)
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>(ctorPtr());
90 }
91 
92 
95 (
96  const word& writeType,
97  const dictionary& writeOpts
98 )
99 {
100  // Constructors with dictionary options
101  {
102  auto* ctorPtr = wordDictConstructorTable(writeType);
103 
104  if (ctorPtr)
105  {
106  return autoPtr<surfaceWriter>(ctorPtr(writeOpts));
107  }
108  }
109 
110 
111  // Constructors without dictionary options
112  auto* ctorPtr = wordConstructorTable(writeType);
113 
114  if (!ctorPtr)
115  {
117  {
118  // Generally unknown, but handle via 'proxy' handler
120  (
121  new surfaceWriters::proxyWriter(writeType, writeOpts)
122  );
123  }
124 
126  << "Unknown write type \"" << writeType << "\"\n\n"
127  << "Valid write types : "
128  << wordConstructorTablePtr_->sortedToc() << nl
129  << "Valid proxy types : "
131  << exit(FatalError);
132  }
133 
134  return autoPtr<surfaceWriter>(ctorPtr());
135 }
136 
137 
138 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
139 
141 :
142  surf_(std::cref<meshedSurf>(emptySurface_)),
143  surfComp_(),
144  useComponents_(false),
145  upToDate_(false),
146  wroteGeom_(false),
147  parallel_(true),
148  useTimeDir_(false),
149  isPointData_(false),
150  verbose_(false),
151  nFields_(0),
152  mergeDim_(defaultMergeDim),
153  merged_(),
154  currTime_(),
155  outputPath_()
156 {
158 }
159 
160 
162 :
163  surfaceWriter()
164 {
165  options.readIfPresent("verbose", verbose_);
166 }
167 
168 
170 (
171  const meshedSurf& surf,
172  bool parallel,
173  const dictionary& options
174 )
175 :
176  surfaceWriter(options)
177 {
178  setSurface(surf, parallel);
179 }
180 
181 
183 (
184  const pointField& points,
185  const faceList& faces,
186  bool parallel,
187  const dictionary& options
188 )
189 :
190  surfaceWriter(options)
191 {
192  setSurface(points, faces, parallel);
193 }
194 
195 
196 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
197 
199 {
200  close();
201 }
202 
203 
204 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
205 
207 {
208  currTime_ = inst;
209 }
210 
211 
212 void Foam::surfaceWriter::setTime(scalar timeValue)
213 {
214  currTime_ = instant(timeValue);
215 }
216 
217 
218 void Foam::surfaceWriter::setTime(scalar timeValue, const word& timeName)
219 {
220  currTime_.value() = timeValue;
221  currTime_.name() = timeName;
222 }
223 
224 
226 {
227  currTime_.value() = 0;
228  currTime_.name().clear();
229 }
230 
231 
233 {
234  setTime(t.value(), t.timeName());
235 }
236 
237 
239 {
240  setTime(inst);
241 }
242 
243 
245 {
246  unsetTime();
247 }
248 
249 
250 void Foam::surfaceWriter::open(const fileName& outputPath)
251 {
252  outputPath_ = outputPath;
253  wroteGeom_ = false;
254 }
255 
256 
258 (
259  const meshedSurf& surf,
260  const fileName& outputPath,
261  bool parallel
262 )
263 {
264  close();
265  setSurface(surf, parallel);
266  open(outputPath);
267 }
268 
269 
271 (
272  const pointField& points,
273  const faceList& faces,
274  const fileName& outputPath,
275  bool parallel
276 )
277 {
278  close();
279  setSurface(points, faces, parallel);
280  open(outputPath);
281 }
282 
283 
285 (
286  const meshedSurf& surf,
287  const fileName& outputPath
288 )
289 {
290  close();
291  setSurface(surf, parallel_);
292  open(outputPath);
293 }
294 
295 
297 (
298  const pointField& points,
299  const faceList& faces,
300  const fileName& outputPath
301 )
302 {
303  close();
304  setSurface(points, faces, parallel_);
305  open(outputPath);
306 }
307 
308 
310 {
311  outputPath_.clear();
312  wroteGeom_ = false;
313 }
314 
315 
317 {
318  close();
319  expire();
320  useComponents_ = false;
321  surf_ = std::cref<meshedSurf>(emptySurface_);
322  surfComp_.clear();
323 }
324 
325 
327 (
328  const meshedSurf& surf,
329  bool parallel
330 )
331 {
332  expire();
333  useComponents_ = false;
334  surf_ = std::cref<meshedSurf>(surf);
335  surfComp_.clear();
336  parallel_ = (parallel && Pstream::parRun());
337 }
338 
339 
341 (
342  const pointField& points,
343  const faceList& faces,
344  bool parallel
345 )
346 {
347  expire();
348  useComponents_ = true;
349  surf_ = std::cref<meshedSurf>(emptySurface_);
350  surfComp_.reset(points, faces);
351  parallel_ = (parallel && Pstream::parRun());
352 }
353 
354 
356 (
357  const meshedSurf& surf
358 )
359 {
360  setSurface(surf, parallel_);
361 }
362 
363 
365 (
366  const pointField& points,
367  const faceList& faces
368 )
369 {
370  setSurface(points, faces, parallel_);
371 }
372 
373 
375 {
376  return !upToDate_;
377 }
378 
379 
381 {
382  return wroteGeom_;
383 }
384 
385 
387 {
388  const bool changed = upToDate_;
389 
390  upToDate_ = false;
391  wroteGeom_ = false;
392  merged_.clear();
393 
394  // Field count (nFields_) is a different type of accounting
395  // and is unaffected by geometry changes
396 
397  return changed;
398 }
399 
400 
402 {
403  return (useComponents_ || (&emptySurface_ != &(surf_.get())));
404 }
405 
406 
408 {
409  const bool value =
410  (
411  useComponents_
412  ? surfComp_.faces().empty()
413  : surf_.get().faces().empty()
414  );
415 
416  return (parallel_ ? returnReduce(value, andOp<bool>()) : value);
417 }
418 
419 
420 Foam::label Foam::surfaceWriter::size() const
421 {
422  const label value =
423  (
424  useComponents_
425  ? surfComp_.faces().size()
426  : surf_.get().faces().size()
427  );
428 
429  return (parallel_ ? returnReduce(value, sumOp<label>()) : value);
430 }
431 
432 
434 {
435  if (outputPath_.empty())
436  {
438  << type() << " : Attempted to write without a path" << nl
439  << exit(FatalError);
440  }
441 
442  return !outputPath_.empty();
443 }
444 
445 
447 {
448  bool changed = false;
449 
450  if (parallel_ && Pstream::parRun() && !upToDate_)
451  {
452  if (useComponents_)
453  {
454  changed = merged_.merge(surfComp_, mergeDim_);
455  }
456  else
457  {
458  changed = merged_.merge(surf_.get(), mergeDim_);
459  }
460  }
461  upToDate_ = true;
462 
463  if (changed)
464  {
465  wroteGeom_ = false;
466  }
467 
468  return changed;
469 }
470 
471 
473 {
474  merge();
475 
476  if (parallel_ && Pstream::parRun())
477  {
478  return merged_;
479  }
480 
481  if (useComponents_)
482  {
483  return surfComp_;
484  }
485  else
486  {
487  return surf_.get();
488  }
489 }
490 
491 
492 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
493 
494 template<class Type>
496 (
497  const Field<Type>& fld
498 ) const
499 {
500  if (parallel_ && Pstream::parRun())
501  {
502  // Ensure geometry is also merged
503  merge();
504 
505  // Gather all values
506  auto tfield = tmp<Field<Type>>::New();
507  auto& allFld = tfield.ref();
508 
509  globalIndex::gatherOp(fld, allFld);
510 
511  // Renumber (point data) to correspond to merged points
512  if
513  (
515  && this->isPointData()
516  && merged_.pointsMap().size()
517  )
518  {
519  inplaceReorder(merged_.pointsMap(), allFld);
520  allFld.resize(merged_.points().size());
521  }
522 
523  return tfield;
524  }
525 
526  // Mark that any geometry changes have been taken care of
527  upToDate_ = true;
528 
529  return fld;
530 }
531 
532 
533 #define defineSurfaceWriterMergeMethod(ThisClass, Type) \
534  Foam::tmp<Foam::Field<Type>> \
535  ThisClass::mergeField(const Field<Type>& fld) const \
536  { \
537  return mergeFieldTemplate(fld); \
538  }
539 
546 
547 #undef defineSurfaceWriterMergeMethod
548 
549 
550 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
551 
552 Foam::Ostream& Foam::operator<<
553 (
554  Ostream& os,
555  const InfoProxy<surfaceWriter>& ip
556 )
557 {
558  const surfaceWriter& w = ip.t_;
559 
560  os << "surfaceWriter:"
561  << " upToDate: " << w.upToDate_
562  << " PointData: " << w.isPointData_
563  << " nFields: " << w.nFields_
564  << " time: " << w.currTime_
565  << " path: " << w.outputPath_ << endl;
566 
567  return os;
568 }
569 
570 
571 // ************************************************************************* //
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:65
Foam::InfoProxy
A helper class for outputting values to Ostream.
Definition: InfoProxy.H:47
Foam::surfaceWriter
Base class for surface writers.
Definition: surfaceWriter.H:114
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
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:221
Foam::surfaceWriter::unsetTime
void unsetTime()
Clear the current time.
Definition: surfaceWriter.C:225
Foam::surfaceWriter::merge
virtual bool merge() const
Definition: surfaceWriter.C:446
globalIndex.H
Foam::surfaceWriter::setSurface
virtual void setSurface(const meshedSurf &surf, bool parallel)
Definition: surfaceWriter.C:327
Foam::surfaceWriter::setTime
void setTime(const instant &inst)
Set the current time.
Definition: surfaceWriter.C:206
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:316
Foam::surfaceWriter::surface
const meshedSurf & surface() const
Definition: surfaceWriter.C:472
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:457
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::surfaceWriter::size
label size() const
The global number of faces for the associated surface.
Definition: surfaceWriter.C:420
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:121
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:407
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:244
Foam::surfaceWriter::upToDate_
bool upToDate_
The topology/surface is up-to-date?
Definition: surfaceWriter.H:136
Foam::surfaceWriter::beginTime
virtual void beginTime(const Time &t)
Begin a time-step.
Definition: surfaceWriter.C:232
Foam::Field< vector >
Foam::surfaceWriter::nFields_
label nFields_
The number of fields.
Definition: surfaceWriter.H:154
Foam::surfaceWriter::checkOpen
bool checkOpen() const
Verify that the outputPath_ has been set or FatalError.
Definition: surfaceWriter.C:433
Foam::surfaceWriter::surfaceWriter
surfaceWriter()
Default construct.
Definition: surfaceWriter.C:140
Foam::surfaceWriter::needsUpdate
virtual bool needsUpdate() const
Does the writer need an update (eg, lagging behind surface changes)
Definition: surfaceWriter.C:374
Foam::andOp
Definition: ops.H:233
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:166
Foam::surfaceWriter::wroteData
virtual bool wroteData() const
Geometry or fields written since the last open?
Definition: surfaceWriter.C:380
Foam::globalIndex::gatherOp
static void gatherOp(const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const Pstream::commsTypes=Pstream::commsTypes::nonBlocking)
Collect data in processor order on master.
Definition: globalIndexTemplates.C:472
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:123
os
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::surfaceWriter::expire
virtual bool expire()
Definition: surfaceWriter.C:386
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:216
Foam::surfaceWriter::isPointData_
bool isPointData_
Is point vs cell data.
Definition: surfaceWriter.H:148
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:163
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
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::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
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:198
Foam::surfaceWriter::hasSurface
bool hasSurface() const
Writer is associated with a surface.
Definition: surfaceWriter.C:401
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:533
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:151
Foam::surfaceWriter::close
virtual void close()
Finish output, performing any necessary cleanup.
Definition: surfaceWriter.C:309
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:250
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:405