Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
Dyad.hpp
Go to the documentation of this file.
1 // Copyright © 2020-2024 Alexandre Coderre-Chabot
2 //
3 // This file is part of Physical Quantities (PhQ), a C++ library of physical quantities, physical
4 // models, and units of measure for scientific computing.
5 //
6 // Physical Quantities is hosted at:
7 // https://github.com/acodcha/phq
8 //
9 // Physical Quantities is licensed under the MIT License:
10 // https://mit-license.org
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
13 // associated documentation files (the "Software"), to deal in the Software without restriction,
14 // including without limitation the rights to use, copy, modify, merge, publish, distribute,
15 // sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 // - The above copyright notice and this permission notice shall be included in all copies or
18 // substantial portions of the Software.
19 // - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
20 // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 #ifndef PHQ_DYAD_HPP
26 #define PHQ_DYAD_HPP
27 
28 #include <array>
29 #include <cstddef>
30 #include <functional>
31 #include <optional>
32 #include <ostream>
33 #include <string>
34 #include <type_traits>
35 
36 #include "Base.hpp"
37 #include "PlanarVector.hpp"
38 #include "SymmetricDyad.hpp"
39 #include "Vector.hpp"
40 
41 namespace PhQ {
42 
43 /// \brief Three-dimensional Euclidean dyadic tensor. Contains nine components in Cartesian
44 /// coordinates: xx, xy, xz, yx, yy, yz, zx, zy, and zz. May be symmetric or asymmetric. For a
45 /// symmetric three-dimensional Euclidean dyadic tensor, see PhQ::SymmetricDyad. For a
46 /// three-dimensional Euclidean vector, see PhQ::Vector. For a two-dimensional Euclidean vector in
47 /// the XY plane, see PhQ::PlanarVector.
48 /// \tparam NumericType Floating-point numeric type: float, double, or long double. Defaults to
49 /// double if unspecified.
50 template <typename NumericType = double>
51 class Dyad {
52  static_assert(std::is_floating_point<NumericType>::value,
53  "The NumericType template parameter of PhQ::Dyad<NumericType> must be a numeric "
54  "floating-point type: float, double, or long double.");
55 
56 public:
57  /// \brief Default constructor. Constructs a three-dimensional dyadic tensor with uninitialized
58  /// xx, xy, xz, yx, yy, yz, zx, zy, and zz Cartesian components.
59  Dyad() = default;
60 
61  /// \brief Constructor. Constructs a three-dimensional dyadic tensor from the given xx, xy, xz,
62  /// yx, yy, yz, zx, zy, and zz Cartesian components.
63  constexpr Dyad(const NumericType xx, const NumericType xy, const NumericType xz,
64  const NumericType yx, const NumericType yy, const NumericType yz,
65  const NumericType zx, const NumericType zy, const NumericType zz)
66  : xx_xy_xz_yx_yy_yz_zx_zy_zz_({xx, xy, xz, yx, yy, yz, zx, zy, zz}) {}
67 
68  /// \brief Constructor. Constructs a three-dimensional dyadic tensor from a given array
69  /// representing its xx, xy, xz, yx, yy, yz, zx, zy, and zz Cartesian components.
70  explicit constexpr Dyad(const std::array<NumericType, 9>& xx_xy_xz_yx_yy_yz_zx_zy_zz)
72 
73  /// \brief Constructor. Constructs a three-dimensional dyadic tensor from a given
74  /// three-dimensional symmetric dyadic tensor.
75  explicit constexpr Dyad(const SymmetricDyad<NumericType>& symmetric_dyad)
77  {symmetric_dyad.xx(), symmetric_dyad.xy(), symmetric_dyad.xz(), symmetric_dyad.yx(),
78  symmetric_dyad.yy(), symmetric_dyad.yz(), symmetric_dyad.zx(), symmetric_dyad.zy(),
79  symmetric_dyad.zz()}) {}
80 
81  /// \brief Destructor. Destroys this three-dimensional dyadic tensor.
82  ~Dyad() noexcept = default;
83 
84  /// \brief Copy constructor. Constructs a three-dimensional dyadic tensor by copying another one.
85  constexpr Dyad(const Dyad<NumericType>& other) = default;
86 
87  /// \brief Copy constructor. Constructs a three-dimensional dyadic tensor by copying another one.
88  template <typename OtherNumericType>
89  explicit constexpr Dyad(const Dyad<OtherNumericType>& other)
91  {static_cast<NumericType>(other.xx()), static_cast<NumericType>(other.xy()),
92  static_cast<NumericType>(other.xz()), static_cast<NumericType>(other.yx()),
93  static_cast<NumericType>(other.yy()), static_cast<NumericType>(other.yz()),
94  static_cast<NumericType>(other.zx()), static_cast<NumericType>(other.zy()),
95  static_cast<NumericType>(other.zz())}) {}
96 
97  /// \brief Move constructor. Constructs a three-dimensional dyadic tensor by moving another one.
98  constexpr Dyad(Dyad<NumericType>&& other) noexcept = default;
99 
100  /// \brief Copy assignment operator. Assigns this three-dimensional dyadic tensor by copying
101  /// another one.
102  constexpr Dyad<NumericType>& operator=(const Dyad<NumericType>& other) = default;
103 
104  /// \brief Copy assignment operator. Assigns this three-dimensional dyadic tensor by copying
105  /// another one.
106  template <typename OtherNumericType>
108  xx_xy_xz_yx_yy_yz_zx_zy_zz_[0] = static_cast<NumericType>(other.xx());
109  xx_xy_xz_yx_yy_yz_zx_zy_zz_[1] = static_cast<NumericType>(other.xy());
110  xx_xy_xz_yx_yy_yz_zx_zy_zz_[2] = static_cast<NumericType>(other.xz());
111  xx_xy_xz_yx_yy_yz_zx_zy_zz_[3] = static_cast<NumericType>(other.yx());
112  xx_xy_xz_yx_yy_yz_zx_zy_zz_[4] = static_cast<NumericType>(other.yy());
113  xx_xy_xz_yx_yy_yz_zx_zy_zz_[5] = static_cast<NumericType>(other.yz());
114  xx_xy_xz_yx_yy_yz_zx_zy_zz_[6] = static_cast<NumericType>(other.zx());
115  xx_xy_xz_yx_yy_yz_zx_zy_zz_[7] = static_cast<NumericType>(other.zy());
116  xx_xy_xz_yx_yy_yz_zx_zy_zz_[8] = static_cast<NumericType>(other.zz());
117  return *this;
118  }
119 
120  /// \brief Move assignment operator. Assigns this three-dimensional dyadic tensor by moving
121  /// another one.
122  constexpr Dyad<NumericType>& operator=(Dyad<NumericType>&& other) noexcept = default;
123 
124  /// \brief Assignment operator. Assigns this three-dimensional dyadic tensor by copying a
125  /// three-dimensional symmetric dyadic tensor.
127  xx_xy_xz_yx_yy_yz_zx_zy_zz_[0] = other.xx();
128  xx_xy_xz_yx_yy_yz_zx_zy_zz_[1] = other.xy();
129  xx_xy_xz_yx_yy_yz_zx_zy_zz_[2] = other.xz();
130  xx_xy_xz_yx_yy_yz_zx_zy_zz_[3] = other.yx();
131  xx_xy_xz_yx_yy_yz_zx_zy_zz_[4] = other.yy();
132  xx_xy_xz_yx_yy_yz_zx_zy_zz_[5] = other.yz();
133  xx_xy_xz_yx_yy_yz_zx_zy_zz_[6] = other.zx();
134  xx_xy_xz_yx_yy_yz_zx_zy_zz_[7] = other.zy();
135  xx_xy_xz_yx_yy_yz_zx_zy_zz_[8] = other.zz();
136  return *this;
137  }
138 
139  /// \brief Assignment operator. Assigns this three-dimensional dyadic tensor by copying a given
140  /// array representing its xx, xy, xz, yx, yy, yz, zx, zy, and zz Cartesian components.
142  const std::array<NumericType, 9>& xx_xy_xz_yx_yy_yz_zx_zy_zz) {
144  return *this;
145  }
146 
147  /// \brief Statically creates a three-dimensional dyadic tensor with its xx, xy, xz, yx, yy, yz,
148  /// zx, zy, and zz Cartesian components initialized to zero.
149  [[nodiscard]] static constexpr Dyad<NumericType> Zero() {
150  return Dyad<NumericType>{
151  std::array<NumericType, 9>{
152  static_cast<NumericType>(0), static_cast<NumericType>(0), static_cast<NumericType>(0),
153  static_cast<NumericType>(0), static_cast<NumericType>(0), static_cast<NumericType>(0),
154  static_cast<NumericType>(0), static_cast<NumericType>(0), static_cast<NumericType>(0)}
155  };
156  }
157 
158  /// \brief Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yx, yy, yz, zx,
159  /// zy, and zz Cartesian components as an array.
160  [[nodiscard]] constexpr const std::array<NumericType, 9>&
161  xx_xy_xz_yx_yy_yz_zx_zy_zz() const noexcept {
163  }
164 
165  /// \brief Returns this three-dimensional dyadic tensor's xx Cartesian component.
166  [[nodiscard]] constexpr NumericType xx() const noexcept {
167  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[0];
168  }
169 
170  /// \brief Returns this three-dimensional dyadic tensor's xy Cartesian component.
171  [[nodiscard]] constexpr NumericType xy() const noexcept {
172  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[1];
173  }
174 
175  /// \brief Returns this three-dimensional dyadic tensor's xz Cartesian component.
176  [[nodiscard]] constexpr NumericType xz() const noexcept {
177  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[2];
178  }
179 
180  /// \brief Returns this three-dimensional dyadic tensor's yx Cartesian component.
181  [[nodiscard]] constexpr NumericType yx() const noexcept {
182  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[3];
183  }
184 
185  /// \brief Returns this three-dimensional dyadic tensor's yy Cartesian component.
186  [[nodiscard]] constexpr NumericType yy() const noexcept {
187  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[4];
188  }
189 
190  /// \brief Returns this three-dimensional dyadic tensor's yz Cartesian component.
191  [[nodiscard]] constexpr NumericType yz() const noexcept {
192  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[5];
193  }
194 
195  /// \brief Returns this three-dimensional dyadic tensor's zx Cartesian component.
196  [[nodiscard]] constexpr NumericType zx() const noexcept {
197  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[6];
198  }
199 
200  /// \brief Returns this three-dimensional dyadic tensor's zy Cartesian component.
201  [[nodiscard]] constexpr NumericType zy() const noexcept {
202  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[7];
203  }
204 
205  /// \brief Returns this three-dimensional dyadic tensor's zz Cartesian component.
206  [[nodiscard]] constexpr NumericType zz() const noexcept {
207  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[8];
208  }
209 
210  /// \brief Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yx, yy, yz, zx,
211  /// zy, and zz Cartesian components as a mutable array.
212  [[nodiscard]] constexpr std::array<NumericType, 9>&
215  }
216 
217  /// \brief Returns this three-dimensional dyadic tensor's xx Cartesian component as a mutable
218  /// value.
219  [[nodiscard]] constexpr NumericType& Mutable_xx() noexcept {
220  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[0];
221  }
222 
223  /// \brief Returns this three-dimensional dyadic tensor's xy Cartesian component as a mutable
224  /// value.
225  [[nodiscard]] constexpr NumericType& Mutable_xy() noexcept {
227  }
228 
229  /// \brief Returns this three-dimensional dyadic tensor's xz Cartesian component as a mutable
230  /// value.
231  [[nodiscard]] constexpr NumericType& Mutable_xz() noexcept {
232  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[2];
233  }
234 
235  /// \brief Returns this three-dimensional dyadic tensor's yx Cartesian component as a mutable
236  /// value.
237  [[nodiscard]] constexpr NumericType& Mutable_yx() noexcept {
238  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[3];
239  }
240 
241  /// \brief Returns this three-dimensional dyadic tensor's yy Cartesian component as a mutable
242  /// value.
243  [[nodiscard]] constexpr NumericType& Mutable_yy() noexcept {
244  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[4];
245  }
246 
247  /// \brief Returns this three-dimensional dyadic tensor's yz Cartesian component as a mutable
248  /// value.
249  [[nodiscard]] constexpr NumericType& Mutable_yz() noexcept {
250  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[5];
251  }
252 
253  /// \brief Returns this three-dimensional dyadic tensor's zx Cartesian component as a mutable
254  /// value.
255  [[nodiscard]] constexpr NumericType& Mutable_zx() noexcept {
256  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[6];
257  }
258 
259  /// \brief Returns this three-dimensional dyadic tensor's zy Cartesian component as a mutable
260  /// value.
261  [[nodiscard]] constexpr NumericType& Mutable_zy() noexcept {
262  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[7];
263  }
264 
265  /// \brief Returns this three-dimensional dyadic tensor's zz Cartesian component as a mutable
266  /// value.
267  [[nodiscard]] constexpr NumericType& Mutable_zz() noexcept {
268  return xx_xy_xz_yx_yy_yz_zx_zy_zz_[8];
269  }
270 
271  /// \brief Sets this three-dimensional dyadic tensor's xx, xy, xz, yx, yy, yz, zx, zy, and zz
272  /// Cartesian components to the given values.
274  const std::array<NumericType, 9>& xx_xy_xz_yx_yy_yz_zx_zy_zz) noexcept {
276  }
277 
278  /// \brief Sets this three-dimensional dyadic tensor's xx, xy, xz, yx, yy, yz, zx, zy, and zz
279  /// Cartesian components to the given values.
281  const NumericType xx, const NumericType xy, const NumericType xz, const NumericType yx,
282  const NumericType yy, const NumericType yz, const NumericType zx, const NumericType zy,
283  const NumericType zz) noexcept {
293  }
294 
295  /// \brief Sets this three-dimensional dyadic tensor's xx Cartesian component to a given value.
296  constexpr void Set_xx(const NumericType xx) noexcept {
298  }
299 
300  /// \brief Sets this three-dimensional dyadic tensor's xy Cartesian component to a given value.
301  constexpr void Set_xy(const NumericType xy) noexcept {
303  }
304 
305  /// \brief Sets this three-dimensional dyadic tensor's xz Cartesian component to a given value.
306  constexpr void Set_xz(const NumericType xz) noexcept {
308  }
309 
310  /// \brief Sets this three-dimensional dyadic tensor's yx Cartesian component to a given value.
311  constexpr void Set_yx(const NumericType yx) noexcept {
313  }
314 
315  /// \brief Sets this three-dimensional dyadic tensor's yy Cartesian component to a given value.
316  constexpr void Set_yy(const NumericType yy) noexcept {
318  }
319 
320  /// \brief Sets this three-dimensional dyadic tensor's yz Cartesian component to a given value.
321  constexpr void Set_yz(const NumericType yz) noexcept {
323  }
324 
325  /// \brief Sets this three-dimensional dyadic tensor's zx Cartesian component to a given value.
326  constexpr void Set_zx(const NumericType zx) noexcept {
328  }
329 
330  /// \brief Sets this three-dimensional dyadic tensor's zy Cartesian component to a given value.
331  constexpr void Set_zy(const NumericType zy) noexcept {
333  }
334 
335  /// \brief Sets this three-dimensional dyadic tensor's zz Cartesian component to a given value.
336  constexpr void Set_zz(const NumericType zz) noexcept {
338  }
339 
340  /// \brief Returns whether this three-dimensional dyadic tensor is symmetric.
341  [[nodiscard]] constexpr bool IsSymmetric() const noexcept {
342  return xy() == yx() && xz() == zx() && yz() == zy();
343  }
344 
345  /// \brief Returns the trace of this three-dimensional dyadic tensor.
346  [[nodiscard]] constexpr NumericType Trace() const noexcept {
347  return xx() + yy() + zz();
348  }
349 
350  /// \brief Returns the determinant of this three-dimensional dyadic tensor.
351  [[nodiscard]] constexpr NumericType Determinant() const noexcept {
352  return (xx() * (yy() * zz() - yz() * zy()) + xy() * (yz() * zx() - yx() * zz())
353  + xz() * (yx() * zy() - yy() * zx()));
354  }
355 
356  /// \brief Returns the transpose of this three-dimensional dyadic tensor.
357  [[nodiscard]] constexpr Dyad<NumericType> Transpose() const {
358  return Dyad<NumericType>{xx(), yx(), zx(), xy(), yy(), zy(), xz(), yz(), zz()};
359  }
360 
361  /// \brief Returns the cofactors of this three-dimensional dyadic tensor.
362  [[nodiscard]] constexpr Dyad<NumericType> Cofactors() const {
363  const NumericType cofactor_xx{yy() * zz() - yz() * zy()};
364  const NumericType cofactor_xy{yz() * zx() - yx() * zz()};
365  const NumericType cofactor_xz{yx() * zy() - yy() * zx()};
366  const NumericType cofactor_yx{xz() * zy() - xy() * zz()};
367  const NumericType cofactor_yy{xx() * zz() - xz() * zx()};
368  const NumericType cofactor_yz{xy() * zx() - xx() * zy()};
369  const NumericType cofactor_zx{xy() * yz() - xz() * yy()};
370  const NumericType cofactor_zy{xz() * yx() - xx() * yz()};
371  const NumericType cofactor_zz{xx() * yy() - xy() * yx()};
372  return Dyad<NumericType>{cofactor_xx, cofactor_xy, cofactor_xz, cofactor_yx, cofactor_yy,
373  cofactor_yz, cofactor_zx, cofactor_zy, cofactor_zz};
374  }
375 
376  /// \brief Returns the adjugate of this three-dimensional dyadic tensor.
377  [[nodiscard]] constexpr Dyad<NumericType> Adjugate() const {
378  return Cofactors().Transpose();
379  }
380 
381  /// \brief Returns the inverse of this three-dimensional dyadic tensor if it exists, or
382  /// std::nullopt otherwise.
383  [[nodiscard]] constexpr std::optional<Dyad<NumericType>> Inverse() const;
384 
385  /// \brief Prints this three-dimensional dyadic tensor as a string.
386  [[nodiscard]] std::string Print() const {
387  return "(" + PhQ::Print(xx()) + ", " + PhQ::Print(xy()) + ", " + PhQ::Print(xz()) + "; "
388  + PhQ::Print(yx()) + ", " + PhQ::Print(yy()) + ", " + PhQ::Print(yz()) + "; "
389  + PhQ::Print(zx()) + ", " + PhQ::Print(zy()) + ", " + PhQ::Print(zz()) + ")";
390  }
391 
392  /// \brief Serializes this three-dimensional dyadic tensor as a JSON message.
393  [[nodiscard]] std::string JSON() const {
394  return "{\"xx\":" + PhQ::Print(xx()) + ",\"xy\":" + PhQ::Print(xy()) + ",\"xz\":"
395  + PhQ::Print(xz()) + ",\"yx\":" + PhQ::Print(yx()) + ",\"yy\":" + PhQ::Print(yy())
396  + ",\"yz\":" + PhQ::Print(yz()) + ",\"zx\":" + PhQ::Print(zx())
397  + ",\"zy\":" + PhQ::Print(zy()) + ",\"zz\":" + PhQ::Print(zz()) + "}";
398  }
399 
400  /// \brief Serializes this three-dimensional dyadic tensor as an XML message.
401  [[nodiscard]] std::string XML() const {
402  return "<xx>" + PhQ::Print(xx()) + "</xx><xy>" + PhQ::Print(xy()) + "</xy><xz>"
403  + PhQ::Print(xz()) + "</xz><yx>" + PhQ::Print(yx()) + "</yx><yy>" + PhQ::Print(yy())
404  + "</yy><yz>" + PhQ::Print(yz()) + "</yz><zx>" + PhQ::Print(zx()) + "</zx><zy>"
405  + PhQ::Print(zy()) + "</zy><zz>" + PhQ::Print(zz()) + "</zz>";
406  }
407 
408  /// \brief Serializes this three-dimensional dyadic tensor as a YAML message.
409  [[nodiscard]] std::string YAML() const {
410  return "{xx:" + PhQ::Print(xx()) + ",xy:" + PhQ::Print(xy()) + ",xz:" + PhQ::Print(xz())
411  + ",yx:" + PhQ::Print(yx()) + ",yy:" + PhQ::Print(yy()) + ",yz:" + PhQ::Print(yz())
412  + ",zx:" + PhQ::Print(zx()) + ",zy:" + PhQ::Print(zy()) + ",zz:" + PhQ::Print(zz())
413  + "}";
414  }
415 
416  /// \brief Adds another three-dimensional dyadic tensor to this one.
417  constexpr void operator+=(const Dyad<NumericType>& other) noexcept {
418  xx_xy_xz_yx_yy_yz_zx_zy_zz_[0] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[0];
419  xx_xy_xz_yx_yy_yz_zx_zy_zz_[1] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[1];
420  xx_xy_xz_yx_yy_yz_zx_zy_zz_[2] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[2];
421  xx_xy_xz_yx_yy_yz_zx_zy_zz_[3] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[3];
422  xx_xy_xz_yx_yy_yz_zx_zy_zz_[4] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[4];
423  xx_xy_xz_yx_yy_yz_zx_zy_zz_[5] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[5];
424  xx_xy_xz_yx_yy_yz_zx_zy_zz_[6] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[6];
425  xx_xy_xz_yx_yy_yz_zx_zy_zz_[7] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[7];
426  xx_xy_xz_yx_yy_yz_zx_zy_zz_[8] += other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[8];
427  }
428 
429  /// \brief Subtracts another three-dimensional dyadic tensor from this one.
430  constexpr void operator-=(const Dyad<NumericType>& other) noexcept {
431  xx_xy_xz_yx_yy_yz_zx_zy_zz_[0] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[0];
432  xx_xy_xz_yx_yy_yz_zx_zy_zz_[1] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[1];
433  xx_xy_xz_yx_yy_yz_zx_zy_zz_[2] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[2];
434  xx_xy_xz_yx_yy_yz_zx_zy_zz_[3] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[3];
435  xx_xy_xz_yx_yy_yz_zx_zy_zz_[4] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[4];
436  xx_xy_xz_yx_yy_yz_zx_zy_zz_[5] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[5];
437  xx_xy_xz_yx_yy_yz_zx_zy_zz_[6] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[6];
438  xx_xy_xz_yx_yy_yz_zx_zy_zz_[7] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[7];
439  xx_xy_xz_yx_yy_yz_zx_zy_zz_[8] -= other.xx_xy_xz_yx_yy_yz_zx_zy_zz_[8];
440  }
441 
442  /// \brief Multiplies this three-dimensional dyadic tensor by the given number.
443  /// \tparam OtherNumericType Floating-point numeric type of the given number. Deduced
444  /// automatically.
445  template <typename OtherNumericType>
446  constexpr void operator*=(const OtherNumericType number) noexcept {
447  xx_xy_xz_yx_yy_yz_zx_zy_zz_[0] *= static_cast<NumericType>(number);
448  xx_xy_xz_yx_yy_yz_zx_zy_zz_[1] *= static_cast<NumericType>(number);
449  xx_xy_xz_yx_yy_yz_zx_zy_zz_[2] *= static_cast<NumericType>(number);
450  xx_xy_xz_yx_yy_yz_zx_zy_zz_[3] *= static_cast<NumericType>(number);
451  xx_xy_xz_yx_yy_yz_zx_zy_zz_[4] *= static_cast<NumericType>(number);
452  xx_xy_xz_yx_yy_yz_zx_zy_zz_[5] *= static_cast<NumericType>(number);
453  xx_xy_xz_yx_yy_yz_zx_zy_zz_[6] *= static_cast<NumericType>(number);
454  xx_xy_xz_yx_yy_yz_zx_zy_zz_[7] *= static_cast<NumericType>(number);
455  xx_xy_xz_yx_yy_yz_zx_zy_zz_[8] *= static_cast<NumericType>(number);
456  }
457 
458  /// \brief Divides this three-dimensional dyadic tensor by the given number.
459  /// \tparam OtherNumericType Floating-point numeric type of the given number. Deduced
460  /// automatically.
461  template <typename OtherNumericType>
462  constexpr void operator/=(const OtherNumericType number) noexcept {
463  xx_xy_xz_yx_yy_yz_zx_zy_zz_[0] /= static_cast<NumericType>(number);
464  xx_xy_xz_yx_yy_yz_zx_zy_zz_[1] /= static_cast<NumericType>(number);
465  xx_xy_xz_yx_yy_yz_zx_zy_zz_[2] /= static_cast<NumericType>(number);
466  xx_xy_xz_yx_yy_yz_zx_zy_zz_[3] /= static_cast<NumericType>(number);
467  xx_xy_xz_yx_yy_yz_zx_zy_zz_[4] /= static_cast<NumericType>(number);
468  xx_xy_xz_yx_yy_yz_zx_zy_zz_[5] /= static_cast<NumericType>(number);
469  xx_xy_xz_yx_yy_yz_zx_zy_zz_[6] /= static_cast<NumericType>(number);
470  xx_xy_xz_yx_yy_yz_zx_zy_zz_[7] /= static_cast<NumericType>(number);
471  xx_xy_xz_yx_yy_yz_zx_zy_zz_[8] /= static_cast<NumericType>(number);
472  }
473 
474 private:
475  /// \brief Cartesian components of this three-dimensional dyadic tensor.
476  std::array<NumericType, 9> xx_xy_xz_yx_yy_yz_zx_zy_zz_;
477 };
478 
479 template <typename NumericType>
480 inline constexpr bool operator==(
481  const Dyad<NumericType>& left, const Dyad<NumericType>& right) noexcept {
482  return (left.xx() == right.xx() && left.xy() == right.xy() && left.xz() == right.xz()
483  && left.yx() == right.yx() && left.yy() == right.yy() && left.yz() == right.yz()
484  && left.zx() == right.zx() && left.zy() == right.zy() && left.zz() == right.zz());
485 }
486 
487 template <typename NumericType>
488 inline constexpr bool operator!=(
489  const Dyad<NumericType>& left, const Dyad<NumericType>& right) noexcept {
490  return (left.xx() != right.xx() || left.xy() != right.xy() || left.xz() != right.xz()
491  || left.yx() != right.yx() || left.yy() != right.yy() || left.yz() != right.yz()
492  || left.zx() != right.zx() || left.zy() != right.zy() || left.zz() != right.zz());
493 }
494 
495 template <typename NumericType>
496 inline constexpr bool operator<(
497  const Dyad<NumericType>& left, const Dyad<NumericType>& right) noexcept {
498  if (left.xx() != right.xx()) {
499  return left.xx() < right.xx();
500  }
501  if (left.xy() != right.xy()) {
502  return left.xy() < right.xy();
503  }
504  if (left.xz() != right.xz()) {
505  return left.xz() < right.xz();
506  }
507  if (left.yx() != right.yx()) {
508  return left.yx() < right.yx();
509  }
510  if (left.yy() != right.yy()) {
511  return left.yy() < right.yy();
512  }
513  if (left.yz() != right.yz()) {
514  return left.yz() < right.yz();
515  }
516  if (left.zx() != right.zx()) {
517  return left.zx() < right.zx();
518  }
519  if (left.zy() != right.zy()) {
520  return left.zy() < right.zy();
521  }
522  return left.zz() < right.zz();
523 }
524 
525 template <typename NumericType>
526 inline constexpr bool operator>(
527  const Dyad<NumericType>& left, const Dyad<NumericType>& right) noexcept {
528  if (left.xx() != right.xx()) {
529  return left.xx() > right.xx();
530  }
531  if (left.xy() != right.xy()) {
532  return left.xy() > right.xy();
533  }
534  if (left.xz() != right.xz()) {
535  return left.xz() > right.xz();
536  }
537  if (left.yx() != right.yx()) {
538  return left.yx() > right.yx();
539  }
540  if (left.yy() != right.yy()) {
541  return left.yy() > right.yy();
542  }
543  if (left.yz() != right.yz()) {
544  return left.yz() > right.yz();
545  }
546  if (left.zx() != right.zx()) {
547  return left.zx() > right.zx();
548  }
549  if (left.zy() != right.zy()) {
550  return left.zy() > right.zy();
551  }
552  return left.zz() > right.zz();
553 }
554 
555 template <typename NumericType>
556 inline constexpr bool operator<=(
557  const Dyad<NumericType>& left, const Dyad<NumericType>& right) noexcept {
558  return !(left > right);
559 }
560 
561 template <typename NumericType>
562 inline constexpr bool operator>=(
563  const Dyad<NumericType>& left, const Dyad<NumericType>& right) noexcept {
564  return !(left < right);
565 }
566 
567 template <typename NumericType>
568 inline constexpr Dyad<NumericType> operator+(
569  const Dyad<NumericType>& left, const Dyad<NumericType>& right) {
570  return Dyad<NumericType>{left.xx() + right.xx(), left.xy() + right.xy(), left.xz() + right.xz(),
571  left.yx() + right.yx(), left.yy() + right.yy(), left.yz() + right.yz(),
572  left.zx() + right.zx(), left.zy() + right.zy(), left.zz() + right.zz()};
573 }
574 
575 template <typename NumericType>
576 inline constexpr Dyad<NumericType> operator-(
577  const Dyad<NumericType>& left, const Dyad<NumericType>& right) {
578  return Dyad<NumericType>{left.xx() - right.xx(), left.xy() - right.xy(), left.xz() - right.xz(),
579  left.yx() - right.yx(), left.yy() - right.yy(), left.yz() - right.yz(),
580  left.zx() - right.zx(), left.zy() - right.zy(), left.zz() - right.zz()};
581 }
582 
583 template <typename NumericType, typename OtherNumericType>
584 inline constexpr Dyad<NumericType> operator*(
585  const Dyad<NumericType>& dyad, const OtherNumericType number) {
586  return Dyad<NumericType>{
587  dyad.xx() * static_cast<NumericType>(number), dyad.xy() * static_cast<NumericType>(number),
588  dyad.xz() * static_cast<NumericType>(number), dyad.yx() * static_cast<NumericType>(number),
589  dyad.yy() * static_cast<NumericType>(number), dyad.yz() * static_cast<NumericType>(number),
590  dyad.zx() * static_cast<NumericType>(number), dyad.zy() * static_cast<NumericType>(number),
591  dyad.zz() * static_cast<NumericType>(number)};
592 }
593 
594 template <typename NumericType, typename OtherNumericType>
595 inline constexpr Dyad<NumericType> operator*(
596  const OtherNumericType number, const Dyad<NumericType>& dyad) {
597  return Dyad<NumericType>{dyad * number};
598 }
599 
600 template <typename NumericType>
602  const Dyad<NumericType>& dyad, const PlanarVector<NumericType>& planar_vector) {
603  return Vector<NumericType>{dyad.xx() * planar_vector.x() + dyad.xy() * planar_vector.y(),
604  dyad.yx() * planar_vector.x() + dyad.yy() * planar_vector.y(),
605  dyad.zx() * planar_vector.x() + dyad.zy() * planar_vector.y()};
606 }
607 
608 template <typename NumericType>
610  const Dyad<NumericType>& dyad, const Vector<NumericType>& vector) {
611  return Vector<NumericType>{
612  dyad.xx() * vector.x() + dyad.xy() * vector.y() + dyad.xz() * vector.z(),
613  dyad.yx() * vector.x() + dyad.yy() * vector.y() + dyad.yz() * vector.z(),
614  dyad.zx() * vector.x() + dyad.zy() * vector.y() + dyad.zz() * vector.z()};
615 }
616 
617 template <typename NumericType>
618 inline constexpr Dyad<NumericType> operator*(
619  const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) {
620  return Dyad<NumericType>{
621  left.xx() * right.xx() + left.xy() * right.xy() + left.xz() * right.xz(),
622  left.xx() * right.xy() + left.xy() * right.yy() + left.xz() * right.yz(),
623  left.xx() * right.xz() + left.xy() * right.yz() + left.xz() * right.zz(),
624  left.xy() * right.xx() + left.yy() * right.xy() + left.yz() * right.xz(),
625  left.xy() * right.xy() + left.yy() * right.yy() + left.yz() * right.yz(),
626  left.xy() * right.xz() + left.yy() * right.yz() + left.yz() * right.zz(),
627  left.xz() * right.xx() + left.yz() * right.xy() + left.zz() * right.xz(),
628  left.xz() * right.xy() + left.yz() * right.yy() + left.zz() * right.yz(),
629  left.xz() * right.xz() + left.yz() * right.yz() + left.zz() * right.zz()};
630 }
631 
632 template <typename NumericType>
633 inline constexpr Dyad<NumericType> operator*(
634  const SymmetricDyad<NumericType>& symmetric_dyad, const Dyad<NumericType>& dyad) {
635  return Dyad<NumericType>{
636  symmetric_dyad.xx() * dyad.xx() + symmetric_dyad.xy() * dyad.yx()
637  + symmetric_dyad.xz() * dyad.zx(),
638  symmetric_dyad.xx() * dyad.xy() + symmetric_dyad.xy() * dyad.yy()
639  + symmetric_dyad.xz() * dyad.zy(),
640  symmetric_dyad.xx() * dyad.xz() + symmetric_dyad.xy() * dyad.yz()
641  + symmetric_dyad.xz() * dyad.zz(),
642  symmetric_dyad.xy() * dyad.xx() + symmetric_dyad.yy() * dyad.yx()
643  + symmetric_dyad.yz() * dyad.zx(),
644  symmetric_dyad.xy() * dyad.xy() + symmetric_dyad.yy() * dyad.yy()
645  + symmetric_dyad.yz() * dyad.zy(),
646  symmetric_dyad.xy() * dyad.xz() + symmetric_dyad.yy() * dyad.yz()
647  + symmetric_dyad.yz() * dyad.zz(),
648  symmetric_dyad.xz() * dyad.xx() + symmetric_dyad.yz() * dyad.yx()
649  + symmetric_dyad.zz() * dyad.zx(),
650  symmetric_dyad.xz() * dyad.xy() + symmetric_dyad.yz() * dyad.yy()
651  + symmetric_dyad.zz() * dyad.zy(),
652  symmetric_dyad.xz() * dyad.xz() + symmetric_dyad.yz() * dyad.yz()
653  + symmetric_dyad.zz() * dyad.zz()};
654 }
655 
656 template <typename NumericType>
657 inline constexpr Dyad<NumericType> operator*(
658  const Dyad<NumericType>& dyad, const SymmetricDyad<NumericType>& symmetric_dyad) {
659  return Dyad<NumericType>{
660  dyad.xx() * symmetric_dyad.xx() + dyad.xy() * symmetric_dyad.yx()
661  + dyad.xz() * symmetric_dyad.zx(),
662  dyad.xx() * symmetric_dyad.xy() + dyad.xy() * symmetric_dyad.yy()
663  + dyad.xz() * symmetric_dyad.zy(),
664  dyad.xx() * symmetric_dyad.xz() + dyad.xy() * symmetric_dyad.yz()
665  + dyad.xz() * symmetric_dyad.zz(),
666  dyad.yx() * symmetric_dyad.xx() + dyad.yy() * symmetric_dyad.yx()
667  + dyad.yz() * symmetric_dyad.zx(),
668  dyad.yx() * symmetric_dyad.xy() + dyad.yy() * symmetric_dyad.yy()
669  + dyad.yz() * symmetric_dyad.zy(),
670  dyad.yx() * symmetric_dyad.xz() + dyad.yy() * symmetric_dyad.yz()
671  + dyad.yz() * symmetric_dyad.zz(),
672  dyad.zx() * symmetric_dyad.xx() + dyad.zy() * symmetric_dyad.yx()
673  + dyad.zz() * symmetric_dyad.zx(),
674  dyad.zx() * symmetric_dyad.xy() + dyad.zy() * symmetric_dyad.yy()
675  + dyad.zz() * symmetric_dyad.zy(),
676  dyad.zx() * symmetric_dyad.xz() + dyad.zy() * symmetric_dyad.yz()
677  + dyad.zz() * symmetric_dyad.zz()};
678 }
679 
680 template <typename NumericType>
681 inline constexpr Dyad<NumericType> operator*(
682  const Dyad<NumericType>& left, const Dyad<NumericType>& right) {
683  return Dyad<NumericType>{
684  left.xx() * right.xx() + left.xy() * right.yx() + left.xz() * right.zx(),
685  left.xx() * right.xy() + left.xy() * right.yy() + left.xz() * right.zy(),
686  left.xx() * right.xz() + left.xy() * right.yz() + left.xz() * right.zz(),
687  left.yx() * right.xx() + left.yy() * right.yx() + left.yz() * right.zx(),
688  left.yx() * right.xy() + left.yy() * right.yy() + left.yz() * right.zy(),
689  left.yx() * right.xz() + left.yy() * right.yz() + left.yz() * right.zz(),
690  left.zx() * right.xx() + left.zy() * right.yx() + left.zz() * right.zx(),
691  left.zx() * right.xy() + left.zy() * right.yy() + left.zz() * right.zy(),
692  left.zx() * right.xz() + left.zy() * right.yz() + left.zz() * right.zz()};
693 }
694 
695 template <typename NumericType, typename OtherNumericType>
696 inline constexpr Dyad<NumericType> operator/(
697  const Dyad<NumericType>& dyad, const OtherNumericType number) {
698  return Dyad<NumericType>{
699  dyad.xx() / static_cast<NumericType>(number), dyad.xy() / static_cast<NumericType>(number),
700  dyad.xz() / static_cast<NumericType>(number), dyad.yx() / static_cast<NumericType>(number),
701  dyad.yy() / static_cast<NumericType>(number), dyad.yz() / static_cast<NumericType>(number),
702  dyad.zx() / static_cast<NumericType>(number), dyad.zy() / static_cast<NumericType>(number),
703  dyad.zz() / static_cast<NumericType>(number)};
704 }
705 
706 template <typename NumericType>
707 inline std::ostream& operator<<(std::ostream& stream, const Dyad<NumericType>& dyad) {
708  stream << dyad.Print();
709  return stream;
710 }
711 
712 template <typename NumericType>
713 inline constexpr std::optional<Dyad<NumericType>> Dyad<NumericType>::Inverse() const {
714  const NumericType determinant_{Determinant()};
715  if (determinant_ != static_cast<NumericType>(0)) {
716  return std::optional<Dyad<NumericType>>{Adjugate() / determinant_};
717  }
718  return std::nullopt;
719 }
720 
721 template <typename NumericType>
723  const PlanarVector<NumericType>& planar_vector) const {
724  return Dyad<NumericType>{
725  x_y_[0] * planar_vector.x_y_[0], x_y_[0] * planar_vector.x_y_[1],
726  static_cast<NumericType>(0), x_y_[1] * planar_vector.x_y_[0],
727  x_y_[1] * planar_vector.x_y_[1], static_cast<NumericType>(0),
728  static_cast<NumericType>(0), static_cast<NumericType>(0),
729  static_cast<NumericType>(0)};
730 }
731 
732 template <typename NumericType>
734  const Vector<NumericType>& other) const {
735  return Dyad<NumericType>{
736  x_y_z_[0] * other.x_y_z_[0], x_y_z_[0] * other.x_y_z_[1], x_y_z_[0] * other.x_y_z_[2],
737  x_y_z_[1] * other.x_y_z_[0], x_y_z_[1] * other.x_y_z_[1], x_y_z_[1] * other.x_y_z_[2],
738  x_y_z_[2] * other.x_y_z_[0], x_y_z_[2] * other.x_y_z_[1], x_y_z_[2] * other.x_y_z_[2]};
739 }
740 
741 } // namespace PhQ
742 
743 namespace std {
744 
745 template <typename NumericType>
746 struct hash<PhQ::Dyad<NumericType>> {
747  inline size_t operator()(const PhQ::Dyad<NumericType>& dyad) const {
748  size_t result{17};
749  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.xx());
750  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.xy());
751  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.xz());
752  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.yx());
753  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.yy());
754  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.yz());
755  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.zx());
756  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.zy());
757  result = static_cast<size_t>(31) * result + hash<NumericType>()(dyad.zz());
758  return result;
759  }
760 };
761 
762 } // namespace std
763 
764 #endif // PHQ_DYAD_HPP
Three-dimensional Euclidean dyadic tensor. Contains nine components in Cartesian coordinates: xx,...
Definition: Dyad.hpp:51
static constexpr Dyad< NumericType > Zero()
Statically creates a three-dimensional dyadic tensor with its xx, xy, xz, yx, yy, yz,...
Definition: Dyad.hpp:149
constexpr std::array< NumericType, 9 > & Mutable_xx_xy_xz_yx_yy_yz_zx_zy_zz() noexcept
Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yx, yy, yz, zx,...
Definition: Dyad.hpp:213
constexpr NumericType Determinant() const noexcept
Returns the determinant of this three-dimensional dyadic tensor.
Definition: Dyad.hpp:351
constexpr bool IsSymmetric() const noexcept
Returns whether this three-dimensional dyadic tensor is symmetric.
Definition: Dyad.hpp:341
constexpr std::optional< Dyad< NumericType > > Inverse() const
Returns the inverse of this three-dimensional dyadic tensor if it exists, or std::nullopt otherwise.
Definition: Dyad.hpp:713
constexpr Dyad< NumericType > Transpose() const
Returns the transpose of this three-dimensional dyadic tensor.
Definition: Dyad.hpp:357
constexpr Dyad(const SymmetricDyad< NumericType > &symmetric_dyad)
Constructor. Constructs a three-dimensional dyadic tensor from a given three-dimensional symmetric dy...
Definition: Dyad.hpp:75
constexpr NumericType Trace() const noexcept
Returns the trace of this three-dimensional dyadic tensor.
Definition: Dyad.hpp:346
constexpr const std::array< NumericType, 9 > & xx_xy_xz_yx_yy_yz_zx_zy_zz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yx, yy, yz, zx,...
Definition: Dyad.hpp:161
Dyad()=default
Default constructor. Constructs a three-dimensional dyadic tensor with uninitialized xx,...
std::string XML() const
Serializes this three-dimensional dyadic tensor as an XML message.
Definition: Dyad.hpp:401
constexpr Dyad(Dyad< NumericType > &&other) noexcept=default
Move constructor. Constructs a three-dimensional dyadic tensor by moving another one.
constexpr void Set_zx(const NumericType zx) noexcept
Sets this three-dimensional dyadic tensor's zx Cartesian component to a given value.
Definition: Dyad.hpp:326
constexpr NumericType & Mutable_zz() noexcept
Returns this three-dimensional dyadic tensor's zz Cartesian component as a mutable value.
Definition: Dyad.hpp:267
constexpr void Set_yx(const NumericType yx) noexcept
Sets this three-dimensional dyadic tensor's yx Cartesian component to a given value.
Definition: Dyad.hpp:311
constexpr Dyad< NumericType > & operator=(const Dyad< OtherNumericType > &other)
Copy assignment operator. Assigns this three-dimensional dyadic tensor by copying another one.
Definition: Dyad.hpp:107
constexpr void Set_yy(const NumericType yy) noexcept
Sets this three-dimensional dyadic tensor's yy Cartesian component to a given value.
Definition: Dyad.hpp:316
constexpr void operator*=(const OtherNumericType number) noexcept
Multiplies this three-dimensional dyadic tensor by the given number.
Definition: Dyad.hpp:446
std::array< NumericType, 9 > xx_xy_xz_yx_yy_yz_zx_zy_zz_
Cartesian components of this three-dimensional dyadic tensor.
Definition: Dyad.hpp:476
constexpr NumericType & Mutable_xz() noexcept
Returns this three-dimensional dyadic tensor's xz Cartesian component as a mutable value.
Definition: Dyad.hpp:231
constexpr void Set_xx(const NumericType xx) noexcept
Sets this three-dimensional dyadic tensor's xx Cartesian component to a given value.
Definition: Dyad.hpp:296
constexpr NumericType & Mutable_yx() noexcept
Returns this three-dimensional dyadic tensor's yx Cartesian component as a mutable value.
Definition: Dyad.hpp:237
constexpr NumericType & Mutable_xy() noexcept
Returns this three-dimensional dyadic tensor's xy Cartesian component as a mutable value.
Definition: Dyad.hpp:225
constexpr NumericType yz() const noexcept
Returns this three-dimensional dyadic tensor's yz Cartesian component.
Definition: Dyad.hpp:191
constexpr NumericType & Mutable_xx() noexcept
Returns this three-dimensional dyadic tensor's xx Cartesian component as a mutable value.
Definition: Dyad.hpp:219
constexpr void Set_xx_xy_xz_yx_yy_yz_zx_zy_zz(const NumericType xx, const NumericType xy, const NumericType xz, const NumericType yx, const NumericType yy, const NumericType yz, const NumericType zx, const NumericType zy, const NumericType zz) noexcept
Sets this three-dimensional dyadic tensor's xx, xy, xz, yx, yy, yz, zx, zy, and zz Cartesian componen...
Definition: Dyad.hpp:280
constexpr NumericType zx() const noexcept
Returns this three-dimensional dyadic tensor's zx Cartesian component.
Definition: Dyad.hpp:196
constexpr NumericType zy() const noexcept
Returns this three-dimensional dyadic tensor's zy Cartesian component.
Definition: Dyad.hpp:201
constexpr void operator-=(const Dyad< NumericType > &other) noexcept
Subtracts another three-dimensional dyadic tensor from this one.
Definition: Dyad.hpp:430
constexpr NumericType yy() const noexcept
Returns this three-dimensional dyadic tensor's yy Cartesian component.
Definition: Dyad.hpp:186
constexpr void Set_xx_xy_xz_yx_yy_yz_zx_zy_zz(const std::array< NumericType, 9 > &xx_xy_xz_yx_yy_yz_zx_zy_zz) noexcept
Sets this three-dimensional dyadic tensor's xx, xy, xz, yx, yy, yz, zx, zy, and zz Cartesian componen...
Definition: Dyad.hpp:273
constexpr NumericType zz() const noexcept
Returns this three-dimensional dyadic tensor's zz Cartesian component.
Definition: Dyad.hpp:206
constexpr void operator/=(const OtherNumericType number) noexcept
Divides this three-dimensional dyadic tensor by the given number.
Definition: Dyad.hpp:462
std::string Print() const
Prints this three-dimensional dyadic tensor as a string.
Definition: Dyad.hpp:386
constexpr void Set_xy(const NumericType xy) noexcept
Sets this three-dimensional dyadic tensor's xy Cartesian component to a given value.
Definition: Dyad.hpp:301
constexpr Dyad< NumericType > & operator=(const std::array< NumericType, 9 > &xx_xy_xz_yx_yy_yz_zx_zy_zz)
Assignment operator. Assigns this three-dimensional dyadic tensor by copying a given array representi...
Definition: Dyad.hpp:141
constexpr NumericType xz() const noexcept
Returns this three-dimensional dyadic tensor's xz Cartesian component.
Definition: Dyad.hpp:176
constexpr Dyad(const NumericType xx, const NumericType xy, const NumericType xz, const NumericType yx, const NumericType yy, const NumericType yz, const NumericType zx, const NumericType zy, const NumericType zz)
Constructor. Constructs a three-dimensional dyadic tensor from the given xx, xy, xz,...
Definition: Dyad.hpp:63
constexpr Dyad< NumericType > & operator=(Dyad< NumericType > &&other) noexcept=default
Move assignment operator. Assigns this three-dimensional dyadic tensor by moving another one.
constexpr NumericType & Mutable_yy() noexcept
Returns this three-dimensional dyadic tensor's yy Cartesian component as a mutable value.
Definition: Dyad.hpp:243
constexpr Dyad< NumericType > & operator=(const Dyad< NumericType > &other)=default
Copy assignment operator. Assigns this three-dimensional dyadic tensor by copying another one.
constexpr void operator+=(const Dyad< NumericType > &other) noexcept
Adds another three-dimensional dyadic tensor to this one.
Definition: Dyad.hpp:417
constexpr void Set_zz(const NumericType zz) noexcept
Sets this three-dimensional dyadic tensor's zz Cartesian component to a given value.
Definition: Dyad.hpp:336
constexpr NumericType & Mutable_yz() noexcept
Returns this three-dimensional dyadic tensor's yz Cartesian component as a mutable value.
Definition: Dyad.hpp:249
constexpr NumericType xy() const noexcept
Returns this three-dimensional dyadic tensor's xy Cartesian component.
Definition: Dyad.hpp:171
constexpr void Set_xz(const NumericType xz) noexcept
Sets this three-dimensional dyadic tensor's xz Cartesian component to a given value.
Definition: Dyad.hpp:306
~Dyad() noexcept=default
Destructor. Destroys this three-dimensional dyadic tensor.
constexpr Dyad< NumericType > Cofactors() const
Returns the cofactors of this three-dimensional dyadic tensor.
Definition: Dyad.hpp:362
constexpr Dyad< NumericType > Adjugate() const
Returns the adjugate of this three-dimensional dyadic tensor.
Definition: Dyad.hpp:377
constexpr NumericType & Mutable_zx() noexcept
Returns this three-dimensional dyadic tensor's zx Cartesian component as a mutable value.
Definition: Dyad.hpp:255
constexpr NumericType & Mutable_zy() noexcept
Returns this three-dimensional dyadic tensor's zy Cartesian component as a mutable value.
Definition: Dyad.hpp:261
std::string JSON() const
Serializes this three-dimensional dyadic tensor as a JSON message.
Definition: Dyad.hpp:393
constexpr void Set_yz(const NumericType yz) noexcept
Sets this three-dimensional dyadic tensor's yz Cartesian component to a given value.
Definition: Dyad.hpp:321
constexpr void Set_zy(const NumericType zy) noexcept
Sets this three-dimensional dyadic tensor's zy Cartesian component to a given value.
Definition: Dyad.hpp:331
std::string YAML() const
Serializes this three-dimensional dyadic tensor as a YAML message.
Definition: Dyad.hpp:409
constexpr Dyad< NumericType > & operator=(const SymmetricDyad< NumericType > &other)
Assignment operator. Assigns this three-dimensional dyadic tensor by copying a three-dimensional symm...
Definition: Dyad.hpp:126
constexpr Dyad(const std::array< NumericType, 9 > &xx_xy_xz_yx_yy_yz_zx_zy_zz)
Constructor. Constructs a three-dimensional dyadic tensor from a given array representing its xx,...
Definition: Dyad.hpp:70
constexpr NumericType yx() const noexcept
Returns this three-dimensional dyadic tensor's yx Cartesian component.
Definition: Dyad.hpp:181
constexpr NumericType xx() const noexcept
Returns this three-dimensional dyadic tensor's xx Cartesian component.
Definition: Dyad.hpp:166
Two-dimensional Euclidean vector in the XY plane. Contains two components in Cartesian coordinates: x...
constexpr NumericType x() const noexcept
Returns this two-dimensional planar vector's x Cartesian component.
std::array< NumericType, 2 > x_y_
Cartesian components of this two-dimensional planar vector.
constexpr Dyad< NumericType > Dyadic(const PlanarVector< NumericType > &other) const
Returns the dyadic tensor product (also known as the outer product) of this two-dimensional planar ve...
Definition: Dyad.hpp:722
constexpr NumericType y() const noexcept
Returns this two-dimensional planar vector's y Cartesian component.
Symmetric three-dimensional Euclidean dyadic tensor. Contains six components in Cartesian coordinates...
constexpr NumericType xy() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component.
constexpr NumericType xx() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xx Cartesian component.
constexpr NumericType zx() const noexcept
Returns this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component.
constexpr NumericType zz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's zz Cartesian component.
constexpr NumericType yx() const noexcept
Returns this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component.
constexpr NumericType yy() const noexcept
Returns this three-dimensional symmetric dyadic tensor's yy Cartesian component.
constexpr NumericType xz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component.
constexpr NumericType yz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component.
constexpr NumericType zy() const noexcept
Returns this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component.
Three-dimensional Euclidean vector. Contains three components in Cartesian coordinates: x,...
Definition: Vector.hpp:60
constexpr NumericType x() const noexcept
Returns this three-dimensional vector's x Cartesian component.
Definition: Vector.hpp:139
std::array< NumericType, 3 > x_y_z_
Cartesian components of this three-dimensional vector.
Definition: Vector.hpp:315
constexpr Dyad< NumericType > Dyadic(const Vector< NumericType > &other) const
Returns the dyadic tensor product (also known as the outer product) of this three-dimensional vector ...
Definition: Dyad.hpp:733
constexpr NumericType y() const noexcept
Returns this three-dimensional vector's y Cartesian component.
Definition: Vector.hpp:144
constexpr NumericType z() const noexcept
Returns this three-dimensional vector's z Cartesian component.
Definition: Vector.hpp:149
Namespace that encompasses all of the Physical Quantities library's content.
constexpr bool operator<(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr bool operator<=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr Acceleration< NumericType > operator*(const NumericType number, const Acceleration< NumericType > &acceleration)
constexpr bool operator>(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr bool operator==(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr Dyad< NumericType > operator+(const Dyad< NumericType > &left, const Dyad< NumericType > &right)
Definition: Dyad.hpp:568
constexpr Dyad< NumericType > operator-(const Dyad< NumericType > &left, const Dyad< NumericType > &right)
Definition: Dyad.hpp:576
constexpr bool operator>=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr Dyad< NumericType > operator/(const Dyad< NumericType > &dyad, const OtherNumericType number)
Definition: Dyad.hpp:696
constexpr bool operator!=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)
std::string Print(const NumericType value)
Prints a given floating-point number as a string. Prints enough digits to represent the number exactl...
Definition: Base.hpp:170