ensightOutputCloud.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) 2016-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 "ensightOutputCloud.H"
29 #include "fvMesh.H"
30 #include "Cloud.H"
31 #include "passiveParticle.H"
32 #include "globalIndex.H"
33 
34 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 //- Binary output
40 static inline void writeMeasured_binary
41 (
42  ensightFile& os,
44 )
45 {
46  for (const auto& p : points)
47  {
48  os.write(p.x());
49  os.write(p.y());
50  os.write(p.z());
51  }
52 }
53 
54 //- ASCII output. Id + position together
55 static inline label writeMeasured_ascii
56 (
57  ensightFile& os,
58  label pointId,
60 )
61 {
62  for (const auto& p : points)
63  {
64  os.writeInt(++pointId, 8); // 1-index and an unusual width
65  os.write(p.x());
66  os.write(p.y());
67  os.write(p.z());
68  os.newline();
69  }
70 
71  return pointId;
72 }
73 
74 } // End namespace Foam
75 
76 
77 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
78 
80 (
81  ensightFile& os,
82  DynamicList<floatVector>& positions,
83  const globalIndex& procAddr
84 )
85 {
86  // Total number of parcels across all ranks
87  const label nTotParcels = procAddr.totalSize();
88 
89  bool noCloud(!procAddr.totalSize());
90  Pstream::broadcast(noCloud);
91 
92  if (UPstream::master())
93  {
94  os.beginParticleCoordinates(nTotParcels);
95  }
96 
97  if (noCloud)
98  {
99  return false; // All empty
100  }
101 
102  if (UPstream::master())
103  {
104  const bool isBinaryOutput = (os.format() == IOstreamOption::BINARY);
105 
106  label parcelId = 0;
107 
108  if (isBinaryOutput)
109  {
110  // NB: binary write is Ensight6 - first ids, then positions
111 
112  // 1-index
113  for (label id = 1; id <= nTotParcels; ++id)
114  {
115  os.write(id);
116  }
117 
118  // Write master data
119  writeMeasured_binary(os, positions);
120  }
121  else
122  {
123  // NB: ascii write is (id + position) together
124 
125  // Write master data
126  parcelId = writeMeasured_ascii(os, parcelId, positions);
127  }
128 
129 
130  positions.clear();
131  positions.reserve_nocopy(procAddr.maxNonLocalSize());
132 
133  // Receive and write
134  for (const label proci : procAddr.subProcs())
135  {
136  const label procSize = procAddr.localSize(proci);
137 
138  if (procSize)
139  {
140  positions.resize_nocopy(procSize);
141 
143  (
144  UPstream::commsTypes::scheduled,
145  proci,
146  positions.data_bytes(),
147  positions.size_bytes()
148  );
149 
150  if (isBinaryOutput)
151  {
152  writeMeasured_binary(os, positions);
153  }
154  else
155  {
156  parcelId = writeMeasured_ascii(os, parcelId, positions);
157  }
158  }
159  }
160  }
161  else if (UPstream::is_subrank())
162  {
163  if (positions.size())
164  {
166  (
167  UPstream::commsTypes::scheduled,
168  UPstream::masterNo(),
169  positions.cdata_bytes(),
170  positions.size_bytes()
171  );
172  }
173  }
174 
175  return true;
176 }
178 
180 (
181  ensightFile& os,
182  DynamicList<floatVector>& positions
183 )
184 {
186  (
187  os,
188  positions,
189  // Gather sizes (offsets irrelevant)
191  );
192 }
194 
196 (
197  ensightFile& os,
198  const fvMesh& mesh,
199  const word& cloudName,
200  bool exists
201 )
202 {
203  autoPtr<Cloud<passiveParticle>> parcelsPtr;
204 
205  if (exists)
206  {
207  parcelsPtr.reset(new Cloud<passiveParticle>(mesh, cloudName, false));
208  }
209 
210  const label nLocalParcels
211  (
212  parcelsPtr ? parcelsPtr->size() : 0
213  );
214 
215  // Gather sizes (offsets irrelevant)
216  // and total number of parcels (all processes)
217  const globalIndex procAddr(globalIndex::gatherOnly{}, nLocalParcels);
218 
219  // Extract positions from parcel.
220  // Store as floatVector, since that is what Ensight will write anyhow
221 
222  DynamicList<floatVector> positions;
223  positions.reserve(UPstream::master() ? procAddr.maxSize() : nLocalParcels);
224 
225  if (parcelsPtr)
226  {
227  const auto& parcels = *parcelsPtr;
228 
229  positions.resize_nocopy(parcels.size()); // same as nLocalParcels
230 
231  auto iter = positions.begin();
232 
233  if (std::is_same<float, vector::cmptType>::value)
234  {
235  for (const auto& p : parcels)
236  {
237  *iter = p.position();
238  ++iter;
239  }
240  }
241  else
242  {
243  for (const auto& p : parcels)
244  {
245  const vector pos(p.position());
246 
247  (*iter).x() = narrowFloat(pos.x());
248  (*iter).y() = narrowFloat(pos.y());
249  (*iter).z() = narrowFloat(pos.z());
250  ++iter;
251  }
252  }
253 
254  parcelsPtr.reset(nullptr);
255  }
256 
257  return ensightOutput::writeCloudPositions(os, positions, procAddr);
258 }
259 
260 
261 // ************************************************************************* //
A variant of OFstream with specialised handling for Ensight writing of strings, integers and floats (...
Definition: ensightFile.H:47
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
bool writeCloudPositions(ensightFile &os, DynamicList< floatVector > &positions, const globalIndex &procAddr)
Write cloud positions.
float narrowFloat(const double val)
Type narrowing from double to float.
Definition: scalar.H:240
virtual Ostream & write(const char c) override
Write character.
Definition: OBJstream.C:69
static void writeMeasured_binary(ensightFile &os, const UList< floatVector > &points)
Binary output.
void reserve_nocopy(const label len)
Reserve allocation space for at least this size, allocating new space if required without retaining o...
Definition: DynamicListI.H:343
Dispatch tag: Construct &#39;one-sided&#39; from local sizes, using gather but no broadcast.
Definition: globalIndex.H:118
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:279
A collection of functions for writing clouds as ensight file content.
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:272
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition: autoPtrI.H:37
dimensionedScalar pos(const dimensionedScalar &ds)
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:61
dynamicFvMesh & mesh
const pointField & points
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
const word cloudName(propsDict.get< word >("cloud"))
A class for handling words, derived from Foam::string.
Definition: word.H:63
bool exists(const fileName &name, const bool checkGzip=true, const bool followLink=true)
Does the name exist (as DIRECTORY or FILE) in the file system?
Definition: POSIX.C:835
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
void reserve(const label len)
Reserve allocation space for at least this size, allocating new space if required and retaining old c...
Definition: DynamicListI.H:333
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
OBJstream os(runTime.globalPath()/outputName)
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
static label writeMeasured_ascii(ensightFile &os, label pointId, const UList< floatVector > &points)
ASCII output. Id + position together.
globalIndex procAddr(aMesh.nFaces())
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
void resize_nocopy(const label len)
Alter addressable list size, allocating new space if required without necessarily recovering old cont...
Definition: DynamicListI.H:375
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
volScalarField & p
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:286
Namespace for OpenFOAM.