complex.H
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) 2011-2014 OpenFOAM Foundation
9  Copyright (C) 2019-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Class
28  Foam::complex
29 
30 Description
31  A complex number, similar to the C++ complex type.
32 
33 SourceFiles
34  complexI.H
35  complex.C
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #ifndef Foam_primitives_complex_H
40 #define Foam_primitives_complex_H
41 
42 #include "scalar.H"
43 #include "word.H"
44 #include "zero.H"
45 #include "contiguous.H"
46 #include <complex>
47 
48 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
49 
50 namespace Foam
51 {
52 
53 // Forward Declarations
54 class complex;
55 
56 inline complex operator-(const complex&);
57 inline complex operator+(const complex&, const complex&);
58 inline complex operator+(const complex&, const scalar);
59 inline complex operator+(const scalar, const complex&);
60 inline complex operator-(const complex&, const complex&);
61 inline complex operator-(const complex&, const scalar);
62 inline complex operator-(const scalar, const complex&);
63 inline complex operator*(const complex&, const complex&);
64 inline complex operator*(const complex&, const scalar);
65 inline complex operator*(const scalar, const complex&);
66 inline complex operator/(const complex&, const complex&);
67 inline complex operator/(const complex&, const scalar);
68 inline complex operator/(const scalar, const complex&);
69 
70 
71 /*---------------------------------------------------------------------------*\
72  Class complex Declaration
73 \*---------------------------------------------------------------------------*/
74 
75 class complex
76 {
77  // Private Data
78 
79  //- Real and imaginary parts
80  scalar re, im;
81 
82 
83 public:
84 
85  // Generated Methods
86 
87  //- Copy construct
88  complex(const complex&) noexcept = default;
89 
90  //- Copy assignment
91  complex& operator=(const complex&) noexcept = default;
92 
93  //- Move construct
94  complex(complex&&) noexcept = default;
95 
96  //- Move assignment
97  complex& operator=(complex&&) noexcept = default;
98 
99 
100  // Constructors
101 
102  //- Default construct, as zero-initialized
103  inline constexpr complex() noexcept;
104 
105  //- Construct zero-initialized from zero class
106  inline constexpr complex(const Foam::zero) noexcept;
107 
108  //- Construct from real component
109  inline explicit constexpr complex(const scalar r) noexcept;
110 
111  //- Construct from real and imaginary parts
112  inline constexpr complex(const scalar r, const scalar i) noexcept;
113 
114  //- Implicit construct from std::complex
115  inline complex(const std::complex<float>& c);
116 
117  //- Implicit construct from std::complex
118  inline complex(const std::complex<double>& c);
119 
120  //- Construct from Istream
121  explicit complex(Istream& is);
122 
123 
124  // Member Functions
125 
126  // STL getter/setter
127 
128  //- Real part of complex number - STL naming
129  constexpr scalar real() const noexcept { return re; }
130 
131  //- Imaginary part of complex number - STL naming
132  constexpr scalar imag() const noexcept { return im; }
133 
134  //- Set real part of complex number - STL naming
135  void real(scalar val) noexcept { re = val; }
136 
137  //- Set imaginary part of complex number - STL naming
138  void imag(scalar val) noexcept { im = val; }
139 
140 
141  // Methods
142 
143  //- Complex conjugate
144  inline complex conjugate() const;
145 
146  //- The magnitude (L2-norm) of complex.
147  //- Called magnitude() instead mag(), which looks too much like imag()
148  inline scalar magnitude() const;
149 
150  //- The L2-norm squared of complex
151  inline scalar magSqr() const;
152 
153  //- The sum of real/imag components
154  inline scalar cmptSum() const noexcept;
156 
157  // Member Operators
158 
159  //- Implicit conversion to std::complex
160  operator std::complex<scalar>() const
161  {
162  return std::complex<scalar>(re, im);
163  }
164 
166  //- Assign zero
167  inline void operator=(const Foam::zero);
168 
169  //- Assign scalar (imag = zero)
170  inline void operator=(const scalar s);
171 
172  inline void operator+=(const complex& c);
173  inline void operator+=(const scalar s);
174 
175  inline void operator-=(const complex& c);
176  inline void operator-=(const scalar s);
177 
178  inline void operator*=(const complex& c);
179  inline void operator*=(const scalar s);
180 
181  inline void operator/=(const complex& c);
182  inline void operator/=(const scalar s);
183 
184  inline bool operator==(const complex& c) const;
185  inline bool operator!=(const complex& c) const;
186 
187 
188  // Friend Operators
189 
190  friend complex operator-(const complex& c);
191 
192  friend complex operator+(const complex& c1, const complex& c2);
193  friend complex operator+(const complex& c, const scalar s);
194  friend complex operator+(const scalar s, const complex& c);
195 
196  friend complex operator-(const complex& c1, const complex& c2);
197  friend complex operator-(const complex& c, const scalar s);
198  friend complex operator-(const scalar s, const complex& c);
199 
200  friend complex operator*(const complex& c1, const complex& c2);
201  friend complex operator*(const complex& c, const scalar s);
202  friend complex operator*(const scalar s, const complex& c);
203 
204  friend complex operator/(const complex& c1, const complex& c2);
205  friend complex operator/(const complex& c, const scalar s);
206  friend complex operator/(const scalar s, const complex& c);
207 
208 
209  // Housekeeping
210 
211  //- Get real part of complex number. Same as real()
212  scalar Re() const noexcept { return re; }
213 
214  //- Get imaginary part of complex number. Same as imag()
215  scalar Im() const noexcept { return im; }
216 
217  //- Non-const access to real part. Prefer real() setter method
218  scalar& Re() noexcept { return re; }
219 
220  //- Non-const access to imaginary part. Prefer imag() setter method
221  scalar& Im() noexcept { return im; }
222 };
223 
224 
225 /*---------------------------------------------------------------------------*\
226  Specialization pTraits<complex>
227 \*---------------------------------------------------------------------------*/
228 
229 //- The underlying component data type for complex is scalar.
230 // The regular pTraits<T>:cmptType as complex is currently (2023-11)
231 // likely not quite correct (issue #3018)
232 template<>
233 struct pTraits_cmptType<complex> { typedef scalar type; };
234 
235 //- A complex has two scalar components
236 template<>
237 struct pTraits_nComponents<complex>
238 :
239  std::integral_constant<Foam::direction, 2>
240 {};
241 
242 
243 //- Template specialisation for pTraits<complex>
244 template<>
245 class pTraits<complex>
246 {
247  complex p_;
248 
249 public:
250 
251  // Typedefs
252 
253  //- Component type
254  typedef complex cmptType;
256  //- Magnitude type
257  typedef scalar magType;
258 
259  //- Equivalent type of labels used for valid component indexing
260  typedef label labelType;
261 
262 
263  // Member Constants
264 
265  //- Dimensionality of space
266  static constexpr direction dim = 3;
267 
268  //- Rank of complex is 0
269  static constexpr direction rank = 0;
271  //- Number of components in complex is 2
272  static constexpr direction nComponents = 2;
273 
274 
275  // Static Data Members
276 
277  static const char* const typeName;
278  static const char* const componentNames[];
279 
280  static const complex zero;
281  static const complex one;
282  static const complex min;
283  static const complex max;
284  static const complex rootMin;
285  static const complex rootMax;
286 
287 
288  // Constructors
289 
290  //- Copy construct from primitive
291  explicit pTraits(const complex& val) noexcept
292  :
293  p_(val)
294  {}
295 
296 
297  //- Read construct from Istream
298  explicit pTraits(Istream& is);
299 
300 
301  // Member Functions
302 
303  //- Return the value
304  operator complex() const noexcept { return p_; }
305 
306  //- Access the value
307  operator complex&() noexcept { return p_; }
308 };
309 
310 
311 /*---------------------------------------------------------------------------*\
312  Namespace Detail
313 \*---------------------------------------------------------------------------*/
314 
315 namespace Detail
316 {
317  // Helper functions for complex, in Detail namespace to avoid possible
318  // name collisions (could change in the future)
319 
320  //- The 'conjugate' of non-complex returns itself (pass-through)
321  //- it does not return a complex!
322  template<class T>
323  typename std::enable_if
324  <
325  !std::is_same<complex, T>::value,
326  const T&
327  >::type conj(const T& val)
328  {
329  return val;
330  }
331 
332  //- The conjugate of a complex number
333  template<class T>
334  typename std::enable_if
335  <
336  std::is_same<complex, T>::value,
337  complex
338  >::type conj(const T& val)
339  {
340  return val.conjugate();
341  }
342 
343 } // End namespace Detail
344 
346 // * * * * * * * * * * * * * * * * * Traits * * * * * * * * * * * * * * * * //
347 
348 //- Contiguous data for complex
349 template<> struct is_contiguous<complex> : std::true_type {};
351 //- Contiguous scalar data for complex
352 template<> struct is_contiguous_scalar<complex> : std::true_type {};
354 
355 // * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * //
356 
358 Ostream& operator<<(Ostream& os, const complex& c);
359 
360 //- Complex conjugate
361 inline complex operator~(const complex& c);
362 
363 
364 // * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * * //
365 
366 //- Return string representation of complex
367 word name(const complex& c);
368 
369 
370 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
371 
372 } // End namespace Foam
373 
374 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
375 
376 #include "complexI.H"
377 
378 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
379 
380 #endif
381 
382 // ************************************************************************* //
std::enable_if< !std::is_same< complex, T >::value, const T &>::type conj(const T &val)
The &#39;conjugate&#39; of non-complex returns itself (pass-through) it does not return a complex! ...
Definition: complex.H:405
uint8_t direction
Definition: direction.H:46
void operator/=(const complex &c)
Definition: complexI.H:147
bitSet operator~(const bitSet &bitset)
Bitset complement, returns a copy of the bitset with all its bits flipped.
Definition: bitSetI.H:676
bool operator!=(const complex &c) const
Definition: complexI.H:166
friend complex operator/(const complex &c1, const complex &c2)
Definition: complexI.H:351
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
const dimensionedScalar c2
Second radiation constant: default SI units: [m.K].
void operator+=(const complex &c)
Definition: complexI.H:108
constexpr scalar imag() const noexcept
Imaginary part of complex number - STL naming.
Definition: complex.H:155
dimensionedScalar operator/(const scalar s1, const dimensionedScalar &ds2)
::Foam::direction nComponents(const expressions::valueTypeCode) noexcept
The number of components associated with given valueTypeCode.
Definition: exprTraits.C:40
tmp< faMatrix< Type > > operator+(const faMatrix< Type > &, const faMatrix< Type > &)
friend complex operator+(const complex &c1, const complex &c2)
Definition: complexI.H:285
pTraits(const Base &obj)
Copy construct from base class.
Definition: pTraits.H:86
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
friend complex operator*(const complex &c1, const complex &c2)
Definition: complexI.H:329
complex & operator=(const complex &) noexcept=default
Copy assignment.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
A class for handling words, derived from Foam::string.
Definition: word.H:63
Istream & operator>>(Istream &, directionInfo &)
void operator*=(const complex &c)
Definition: complexI.H:134
scalar Im() const noexcept
Get imaginary part of complex number. Same as imag()
Definition: complex.H:260
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
void operator-=(const complex &c)
Definition: complexI.H:121
tmp< faMatrix< Type > > operator-(const faMatrix< Type > &)
Unary negation.
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
scalar Re() const noexcept
Get real part of complex number. Same as real()
Definition: complex.H:255
OBJstream os(runTime.globalPath()/outputName)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
complex conjugate() const
Complex conjugate.
Definition: complexI.H:68
scalar magSqr() const
The L2-norm squared of complex.
Definition: complexI.H:80
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
constexpr complex() noexcept
Default construct, as zero-initialized.
Definition: complexI.H:24
scalar cmptSum() const noexcept
The sum of real/imag components.
Definition: complexI.H:86
A template class to specify if a data type is composed solely of Foam::scalar elements.
Definition: contiguous.H:80
scalar magnitude() const
The magnitude (L2-norm) of complex. Called magnitude() instead mag(), which looks too much like imag(...
Definition: complexI.H:74
friend complex operator-(const complex &c)
Definition: complexI.H:279
A template class to specify that a data type can be considered as being contiguous in memory...
Definition: contiguous.H:70
const dimensionedScalar c
Speed of light in a vacuum.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
::Foam::direction rank(const expressions::valueTypeCode) noexcept
The vector-space rank associated with given valueTypeCode.
Definition: exprTraits.C:70
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
A complex number, similar to the C++ complex type.
Definition: complex.H:70
constexpr scalar real() const noexcept
Real part of complex number - STL naming.
Definition: complex.H:150
bool operator==(const complex &c) const
Definition: complexI.H:160
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;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Namespace for OpenFOAM.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:56