polySurface.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-2024 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 "polySurface.H"
29 #include "Time.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(polySurface, 0);
37 }
38 
40 
41 
42 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
43 
44 void Foam::polySurface::calculateZoneIds(const UList<surfZone>& zones)
45 {
46  if (returnReduceAnd(zones.empty()))
47  {
48  zoneIds_.clear();
49  return;
50  }
51 
52  // Extra safety, ensure we have at some zones
53  // and they cover all the faces - fix start silently
54 
55  zoneIds_.resize_nocopy(size());
56 
57  label off = 0;
58  for (const surfZone& zn : zones)
59  {
60  SubList<label>(zoneIds_, zn.size(), off) = zn.index();
61  off += zn.size();
62  }
63 
64  if (off < size())
65  {
67  << "More faces " << size() << " than zones " << off << endl;
68 
69  zoneIds_.slice(off) = (zones.empty() ? 0 : zones.back().index());
70  }
71  else if (size() < off)
72  {
74  << "More zones " << off << " than faces " << size()
76  }
77 }
78 
79 
80 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
81 
82 Foam::polySurface::polySurface(const IOobject& io, bool doCheckIn)
83 :
84  objectRegistry
85  (
86  IOobject
87  (
88  io.name(),
89  io.db().time().constant(),
90  io.db(),
91  IOobjectOption::NO_READ,
92  IOobjectOption::NO_WRITE,
93  IOobjectOption::REGISTER
94  )
95  ),
96  MeshReference(faceList(), pointField())
97 {
98  // Created without a point field sub-registry
99 
100  if (doCheckIn)
101  {
102  this->store();
103  }
104 }
105 
106 
108 (
109  const word& surfName,
110  const objectRegistry& obr,
111  bool doCheckIn
112 )
113 :
114  polySurface
115  (
116  IOobject
117  (
118  surfName,
119  obr.time().constant(),
120  obr,
121  IOobjectOption::NO_READ,
122  IOobjectOption::NO_WRITE,
123  IOobjectOption::REGISTER
124  ),
125  doCheckIn
126  )
127 {}
128 
129 
131 (
132  const IOobject& io,
133  const MeshedSurface<face>& surf,
134  bool doCheckIn
135 )
136 :
137  polySurface(io, doCheckIn)
138 {
139  copySurface(surf);
140 }
141 
142 
144 (
145  const IOobject& io,
146  MeshedSurface<face>&& surf,
147  bool doCheckIn
148 )
149 :
150  polySurface(io, doCheckIn)
151 {
152  transfer(surf);
153 }
154 
155 
156 // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
157 
159 (
160  const word& surfName,
161  const objectRegistry& obr
162 )
163 {
164  auto* ptr = obr.getObjectPtr<polySurface>(surfName);
165 
166  if (!ptr)
167  {
168  ptr = new polySurface(surfName, obr);
169  regIOobject::store(ptr);
170  }
171 
172  return *ptr;
173 }
174 
175 
177 (
178  const word& surfName,
179  const objectRegistry& obr
180 )
181 {
182  return obr.checkOut(obr.getObjectPtr<polySurface>(surfName));
183 }
184 
185 
186 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
187 
189 {
191 }
192 
193 
194 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
195 
196 Foam::label Foam::polySurface::nFaceData() const
197 {
198  // Do not include sub-registry in the count
199  if (objectRegistry::foundObject<objectRegistry>(pointDataName))
200  {
201  return (objectRegistry::size() - 1);
202  }
203 
204  return objectRegistry::size();
205 }
206 
207 
208 Foam::label Foam::polySurface::nPointData() const
209 {
210  const auto* subreg =
211  objectRegistry::cfindObject<objectRegistry>(pointDataName);
212 
213  if (subreg)
214  {
215  return subreg->size();
216  }
217 
218  return 0;
219 }
220 
223 {
224  return static_cast<const objectRegistry&>(*this);
225 }
226 
227 
229 {
230  // Force create on access
231  return objectRegistry::subRegistry(pointDataName, true);
232 }
233 
234 
236 Foam::polySurface::queryFieldAssociation(const word& fieldName) const
237 {
238  unsigned where(FieldAssociation::NO_DATA);
239 
240  const objectRegistry* subreg = nullptr;
241 
242  // Face Data
243  {
244  subreg = this;
245 
246  if (subreg && subreg->contains(fieldName))
247  {
249  }
250  }
251 
252  // Point Data
253  {
254  subreg = cfindObject<objectRegistry>(pointDataName);
255 
256  if (subreg && subreg->contains(fieldName))
257  {
259  }
260  }
261 
262  return FieldAssociation(where);
263 }
264 
265 
267 (
268  const word& fieldName,
269  enum FieldAssociation association
270 ) const
271 {
272  const unsigned where(association);
273 
274 
275  const regIOobject* ioptr = nullptr;
276  const objectRegistry* subreg = nullptr;
277 
278  // Face Data
279  if (where & FieldAssociation::FACE_DATA)
280  {
281  subreg = this;
282 
283  if (subreg && (ioptr = subreg->cfindObject<regIOobject>(fieldName)))
284  {
285  return ioptr;
286  }
287  }
288 
289  // Point Data
290  if (where & FieldAssociation::POINT_DATA)
291  {
292  subreg = cfindObject<objectRegistry>(pointDataName);
293 
294  if (subreg && (ioptr = subreg->cfindObject<regIOobject>(fieldName)))
295  {
296  return ioptr;
297  }
298  }
299 
300  return ioptr;
301 }
302 
303 
305 (
306  const pointField& points,
307  const faceList& faces,
308  bool unused
309 )
310 {
311  clearOut(); // Clear addressing
312 
313  if
314  (
315  this->nPoints() != points.size()
316  || this->nFaces() != faces.size()
317  )
318  {
319  // Geometry changed
320  clearFields();
321  }
322 
323  this->storedPoints() = points;
324  this->storedFaces() = faces;
325 
326  zoneIds_.clear();
327 
328  // if (validate)
329  // {
330  // checkZones();
331  // }
332 }
333 
334 
336 (
337  const meshedSurf& surf,
338  bool unused
339 )
340 {
341  clearOut(); // Clear addressing
342 
343  if
344  (
345  this->nPoints() != surf.points().size()
346  || this->nFaces() != surf.faces().size()
347  )
348  {
349  // Geometry changed
350  clearFields();
351  }
352 
353  this->storedPoints() = surf.points();
354  this->storedFaces() = surf.faces();
355 
356  zoneIds_ = surf.zoneIds();
357 
358  // if (validate)
359  // {
360  // checkZones();
361  // }
362 }
363 
364 
366 (
367  const MeshedSurface<face>& surf,
368  bool unused
369 )
370 {
371  clearOut(); // Clear addressing
372 
373  if
374  (
375  this->nPoints() != surf.points().size()
376  || this->nFaces() != surf.surfFaces().size()
377  )
378  {
379  // Geometry changed
380  clearFields();
381  }
382 
383  this->storedPoints() = surf.points();
384  this->storedFaces() = surf.surfFaces();
385 
386  calculateZoneIds(surf.surfZones());
387 
388  // if (validate)
389  // {
390  // checkZones();
391  // }
392 }
393 
394 
396 (
397  pointField&& points,
398  faceList&& faces,
399  labelList&& zoneIds
400 )
401 {
402  clearOut(); // Clear addressing
403  clearFields();
404 
405  this->storedPoints().transfer(points);
406  this->storedFaces().transfer(faces);
407  zoneIds_.transfer(zoneIds);
408 }
409 
410 
412 (
413  MeshedSurface<face>& surf,
414  bool unused
415 )
416 {
417  clearOut(); // Clear addressing
418  clearFields();
419 
420  ModifiableMeshedSurface<face> tsurf(std::move(surf));
421 
422  this->storedPoints().transfer(tsurf.storedPoints());
423  this->storedFaces().transfer(tsurf.storedFaces());
424 
425  calculateZoneIds(tsurf.surfZones());
426 
427  // if (validate)
428  // {
429  // checkZones();
430  // }
431 }
432 
433 
434 // void Foam::polySurface::checkZones()
435 // {
436 // // Extra safety, ensure we have at some zones
437 // // and they cover all the faces - fix start silently
438 //
439 // if (surfZones_.size() <= 1)
440 // {
441 // removeZones();
442 // return;
443 // }
444 //
445 // label count = 0;
446 // for (surfZone& zn : surfZones_)
447 // {
448 // zn.start() = count;
449 // count += zn.size();
450 // }
451 //
452 // if (count < nFaces())
453 // {
454 // WarningInFunction
455 // << "More faces " << nFaces() << " than zones " << count
456 // << " ... extending final zone"
457 // << endl;
458 //
459 // surfZones_.back().size() += count - nFaces();
460 // }
461 // else if (size() < count)
462 // {
463 // FatalErrorInFunction
464 // << "More zones " << count << " than faces " << nFaces()
465 // << exit(FatalError);
466 // }
467 // }
468 
469 
470 // * * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * //
471 
472 namespace Foam
473 {
474 
475 template<>
476 const regIOobject* polySurface::findFieldObject<polySurfaceGeoMesh>
477 (
478  const word& fieldName
479 ) const
480 {
481  // Face Data (main registry)
482  return cfindObject<regIOobject>(fieldName);
483 }
484 
485 
486 template<>
487 const regIOobject* polySurface::findFieldObject<polySurfacePointGeoMesh>
488 (
489  const word& fieldName
490 ) const
491 {
492  // Point Data (sub-registry)
493 
494  const auto* subreg =
495  objectRegistry::cfindObject<objectRegistry>(pointDataName);
496 
497  if (subreg)
498  {
499  return subreg->cfindObject<regIOobject>(fieldName);
500  }
501 
502  return nullptr;
503 }
504 
505 
506 
507 template<>
508 const objectRegistry* polySurface::whichRegistry<polySurfaceGeoMesh>
509 (
510  const word& fieldName
511 ) const
512 {
513  // Face Data (main registry)
514  const objectRegistry* subreg = this;
515 
516  if (subreg->contains(fieldName))
517  {
518  return subreg;
519  }
521  return nullptr;
522 }
523 
524 
525 template<>
526 const objectRegistry* polySurface::whichRegistry<polySurfacePointGeoMesh>
527 (
528  const word& fieldName
529 ) const
530 {
531  // Point Data (sub registry)
532 
533  const auto* subreg =
534  objectRegistry::cfindObject<objectRegistry>(pointDataName);
535 
536  if (subreg && subreg->contains(fieldName))
537  {
538  return subreg;
539  }
540 
541  return nullptr;
542 }
543 
544 } // End of namespace
545 
546 // ************************************************************************* //
A surface mesh consisting of general polygon faces and capable of holding fields. ...
Definition: polySurface.H:62
bool contains(const word &name, const bool recursive=false) const
Does the registry contain the regIOobject object (by name).
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
static bool Delete(const word &surfName, const objectRegistry &)
Remove named surface from specified registry.
Definition: polySurface.C:170
virtual const labelList & zoneIds() const
Per-face zone/region information.
Definition: meshedSurf.H:82
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
static polySurface & New(const word &surfName, const objectRegistry &)
Get or create (NO_READ, NO_WRITE) named surface on registry.
Definition: polySurface.C:152
const objectRegistry & subRegistry(const word &name, const bool forceCreate=false, const bool recursive=false) const
Lookup and return a const sub-objectRegistry.
A special purpose MeshedSurface that exposes the stored values for direct modification.
Abstract definition of a meshed surface defined by faces and points.
Definition: meshedSurf.H:43
FieldAssociation queryFieldAssociation(const word &fieldName) const
Query the field association (FACE or POINT)
Definition: polySurface.C:229
const objectRegistry & pointData() const
Point data are stored in a sub-registry.
Definition: polySurface.C:221
List< face > faceList
List of faces.
Definition: faceListFwd.H:39
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
virtual label size() const
Return number of faces.
Definition: polySurface.H:288
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
label nPointData() const
Number of entries on PointData sub-registry (if it exists)
Definition: polySurface.C:201
const pointField & points
List< Face > & storedFaces()
Non-const access to the faces.
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:130
A class for handling words, derived from Foam::string.
Definition: word.H:63
label nPoints
Type * getObjectPtr(const word &name, const bool recursive=false) const
Return non-const pointer to the object of the given Type, using a const-cast to have it behave like a...
FieldAssociation
Enumeration for the field association.
Definition: polySurface.H:73
pointField & storedPoints()
Non-const access to global points.
label nFaceData() const
Number of main entries, without PointData sub-registry.
Definition: polySurface.C:189
const Field< point_type > & points() const noexcept
Return reference to global points.
polySurface(const polySurface &)=delete
No copy construct.
virtual const faceList & faces() const =0
The faces used for the surface.
const objectRegistry & faceData() const
Face data are stored directly on the registry.
Definition: polySurface.C:215
const List< Face > & surfFaces() const
Return const access to the faces.
defineTypeNameAndDebug(combustionModel, 0)
const regIOobject * findFieldObject(const word &fieldName, const FieldAssociation association) const
Find the field object with the given name and required FieldAssociation (FACE or POINT).
Definition: polySurface.C:260
virtual ~polySurface()
Destructor.
Definition: polySurface.C:181
void transfer(pointField &&points, faceList &&faces, labelList &&zoneIds=labelList())
Transfer the contents (and annul the parameters). Removes existing fields.
Definition: polySurface.C:389
#define WarningInFunction
Report a warning using Foam::Warning.
void copySurface(const pointField &points, const faceList &faces, bool unused=false)
Update with new contents. Removes existing fields if sizes have changed.
Definition: polySurface.C:298
static const word pointDataName
Name for point fields sub-registry.
Definition: polySurface.H:164
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:68
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, IOobject::NO_REGISTER)
Registry of regIOobjects.
const surfZoneList & surfZones() const
Const access to the surface zones.
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:180
virtual const pointField & points() const =0
The points used for the surface.
Namespace for OpenFOAM.