exprValueFieldTag.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) 2023-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 "exprValueFieldTag.H"
29 #include "PstreamReduceOps.H"
30 
31 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
32 
34 {
35  return
36  (
38  );
39 }
40 
41 
43 {
44  return
45  (
47  );
48 }
49 
50 
52 {
53  return
54  (
56  // Extra safety for direct reductions?
57  // || uniformity_ == Foam::Detail::ListPolicy::uniformity::MIXED
58  );
59 }
60 
61 
64 {
65  return value_;
66 }
67 
68 
70 {
72  value_ = Foam::zero{};
73 }
74 
75 
77 {
79  value_ = Foam::zero{};
80 }
81 
82 
84 (
85  const exprValueFieldTag& rhs
86 ) const
87 {
88  if (uniformity_ != rhs.uniformity_)
89  {
90  // First compare by uniformity
91  return (int(uniformity_) - int(rhs.uniformity_));
92  }
93  if (this == &rhs)
94  {
95  // Identical objects
96  return 0;
97  }
98 
99  return value_.compare(rhs.value_);
100 }
101 
102 
104 (
105  const exprValueFieldTag& rhs
106 ) const
107 {
108  return (value_ == rhs.value_);
109 }
110 
111 
113 {
114  if (!UPstream::is_parallel())
115  {
116  // Nothing to do
117  return;
118  }
119 
120  // Two-stage reduction
121  // ~~~~~~~~~~~~~~~~~~~
122  //
123  // Fields will usually be non-uniform somewhere, so first check with
124  // the cheapest option (bit-wise Allreduce).
125  // Only if they are uniform (with/without empty) do we actually
126  // need to compare values.
127 
128  typedef unsigned char bitmask_type;
129 
130  bitmask_type shape = static_cast<bitmask_type>(uniformity_);
131 
132  // Step 1
133  // ~~~~~~
135  (
136  shape,
138  UPstream::msgType(), // ignored
140  );
141 
142  // Step 2
143  // ~~~~~~
144  if
145  (
146  shape == static_cast<bitmask_type>
147  (
149  )
150  )
151  {
152  // no-op (empty everywhere)
153  value_ = Foam::zero{};
154  }
155  else if
156  (
157  shape == static_cast<bitmask_type>
158  (
160  )
161  )
162  {
163  // Ranks are locally uniform (or empty), need to check values too
165  (
166  *this,
167  exprValueFieldTag::combineOp{},
170  );
171  }
172  else
173  {
174  // Field is global non-empty and not uniform
175  set_nouniform();
176  }
177 }
178 
179 
182 (
183  const exprValueFieldTag& tag
184 )
185 {
186  exprValueFieldTag work(tag);
187  work.reduce();
188  return work;
189 }
190 
191 
193 (
194  const exprValueFieldTag& b
195 )
196 {
197  exprValueFieldTag& a = *this;
198 
199  if (b.empty())
200  {
201  // no-op
202  return;
203  }
204  else if (a.empty())
205  {
206  a = b;
207  }
208  else if (a.is_uniform() && (!b.is_uniform() || !a.equal(b)))
209  {
210  // Handle two cases:
211  // 1. uniform / non-uniform
212  // 2. uniform / uniform, but with different values
213  a.set_nouniform();
214  }
215 
216  // No meaningful value if it is not uniform.
217  // So use zero, but keep the type
218  if (!a.is_uniform())
219  {
220  a.value_ = Foam::zero{};
221  }
222 }
223 
224 
225 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
226 
228 operator==(const exprValueFieldTag& rhs) const
229 {
230  if (uniformity_ != rhs.uniformity_)
231  {
232  // Uniformity must match
233  return false;
234  }
235  else if (this == &rhs)
236  {
237  return true;
238  }
239 
240  return (value_ == rhs.value_);
241 }
242 
243 
245 operator<(const exprValueFieldTag& rhs) const
246 {
247  return (this->compare(rhs) < 0);
248 }
249 
250 
251 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
252 
254 {
255  label uniformTag;
256 
257  is.readBegin("fieldTag");
258 
259  is >> uniformTag;
260  uniformity_ = int(uniformTag);
261  value_.read(is);
262 
263  is.readEnd("fieldTag");
264 }
265 
266 
268 {
270  << label(uniformity_) << token::SPACE;
271  value_.write(os, false); // No pruning
272  os << token::END_LIST;
273 }
274 
275 
277 {
278  os << "{ uniform:"
279  << label(uniformity_)
280  << " type:" << label(value_.typeCode())
281  << " value: " << value_ << " }";
282 }
283 
284 
285 Foam::Istream& Foam::operator>>
286 (
287  Istream& is,
288  expressions::exprValueFieldTag& tag
289 )
290 {
291  tag.read(is);
292  return is;
293 }
294 
295 
296 Foam::Ostream& Foam::operator<<
297 (
298  Ostream& os,
299  const expressions::exprValueFieldTag& tag
300 )
301 {
302  tag.write(os);
303  return os;
304 }
305 
306 
307 // ************************************************************************* //
Inter-processor communication reduction functions.
void set_empty()
Set as empty with zero value, leave type unchanged.
void write(Ostream &os) const
Write uniformity label and the value as pair.
bool readBegin(const char *funcName)
Begin read of data chunk, starts with &#39;(&#39;.
Definition: Istream.C:134
A polymorphic typed union of simple primitive and VectorSpace types. It uses a &#39;fatter&#39; representatio...
Definition: exprValue.H:157
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
int compare(const exprValueFieldTag &rhs) const
Compare (uniformity, type, value)
Begin list [isseparator].
Definition: token.H:161
void set_nouniform()
Set as non-uniform with zero value, leave type unchanged.
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1252
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition: UPstream.H:421
void read(Istream &is)
Read uniformity label and the value as pair.
Container (non-empty) with different values.
Definition: ListPolicy.H:107
An empty container.
Definition: ListPolicy.H:105
void combine(const exprValueFieldTag &b)
Inplace combine - eg, for global uniformity.
static exprValueFieldTag returnReduce(const exprValueFieldTag &tag)
Perform a reduction on a copy and return the result.
const expressions::exprValue & value() const noexcept
Representative (uniform) value for the field.
virtual Istream & read(token &)=0
Return next token from stream.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Space [isspace].
Definition: token.H:131
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
End list [isseparator].
Definition: token.H:162
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
Definition: UPstream.H:1123
bool is_uniform() const noexcept
True if the uniformity is "uniform".
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
bool empty() const noexcept
True if the uniformity is "empty".
void reduce()
Inplace parallel reduction, uses worldComm.
bool readEnd(const char *funcName)
End read of data chunk, ends with &#39;)&#39;.
Definition: Istream.C:152
OBJstream os(runTime.globalPath()/outputName)
bool operator==(const exprValueFieldTag &) const
Compare (uniformity,value) for equality.
bool is_nonuniform() const noexcept
True if the uniformity is "non-uniform".
An expressions::exprValue (polymorphic typed union) with an additional flag for tracking Field conten...
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
Container (non-empty) with identical values.
Definition: ListPolicy.H:106
bool operator<(const exprValueFieldTag &) const
Compare (uniformity,value)
void print(Ostream &os) const
Print description to Ostream.
bool equal(const exprValueFieldTag &rhs) const
Test for equality of the values.
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.