Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
Loading...
Searching...
No Matches
SymmetricDyad.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_SYMMETRIC_DYAD_HPP
26#define PHQ_SYMMETRIC_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 "Vector.hpp"
39
40namespace PhQ {
41
42/// \brief Symmetric three-dimensional Euclidean dyadic tensor. Contains six components in Cartesian
43/// coordinates: xx, xy = yx, xz = zx, yy, yz = zy, and zz. For the general case of a
44/// three-dimensional Euclidean dyadic tensor which may be symmetric or asymmetric, see PhQ::Dyad.
45/// For a three-dimensional Euclidean vector, see PhQ::Vector. For a two-dimensional Euclidean
46/// vector in the XY plane, see PhQ::PlanarVector.
47/// \tparam NumericType Floating-point numeric type: float, double, or long double. Defaults to
48/// double if unspecified.
49template <typename NumericType = double>
51 static_assert(std::is_floating_point<NumericType>::value,
52 "The NumericType template parameter of PhQ::SymmetricDyad<NumericType> must be a "
53 "numeric floating-point type: float, double, or long double.");
54
55public:
56 /// \brief Default constructor. Constructs a three-dimensional symmetric dyadic tensor with
57 /// uninitialized xx, xy, xz, yy, yz, and zz Cartesian components.
58 SymmetricDyad() = default;
59
60 /// \brief Constructor. Constructs a three-dimensional symmetric dyadic tensor from the given xx,
61 /// xy, xz, yy, yz, and zz Cartesian components.
62 constexpr SymmetricDyad(const NumericType xx, const NumericType xy, const NumericType xz,
63 const NumericType yy, const NumericType yz, const NumericType zz)
64 : xx_xy_xz_yy_yz_zz_({xx, xy, xz, yy, yz, zz}) {}
65
66 /// \brief Constructor. Constructs a three-dimensional symmetric dyadic tensor from a given array
67 /// representing its xx, xy, xz, yy, yz, and zz Cartesian components.
68 explicit constexpr SymmetricDyad(const std::array<NumericType, 6>& xx_xy_xz_yy_yz_zz)
70
71 /// \brief Destructor. Destroys this three-dimensional symmetric dyadic tensor.
72 ~SymmetricDyad() noexcept = default;
73
74 /// \brief Copy constructor. Constructs a three-dimensional symmetric dyadic tensor by copying
75 /// another one.
76 constexpr SymmetricDyad(const SymmetricDyad<NumericType>& other) = default;
77
78 /// \brief Copy constructor. Constructs a three-dimensional symmetric dyadic tensor by copying
79 /// another one.
80 template <typename OtherNumericType>
81 explicit constexpr SymmetricDyad<NumericType>(const SymmetricDyad<OtherNumericType>& other)
83 {static_cast<NumericType>(other.xx()), static_cast<NumericType>(other.xy()),
84 static_cast<NumericType>(other.xz()), static_cast<NumericType>(other.yy()),
85 static_cast<NumericType>(other.yz()), static_cast<NumericType>(other.zz())}) {}
86
87 /// \brief Move constructor. Constructs a three-dimensional symmetric dyadic tensor by moving
88 /// another one.
89 constexpr SymmetricDyad<NumericType>(SymmetricDyad<NumericType>&& other) noexcept = default;
90
91 /// \brief Copy assignment operator. Assigns this three-dimensional symmetric dyadic tensor by
92 /// copying another one.
94 const SymmetricDyad<NumericType>& other) = default;
95
96 /// \brief Copy assignment operator. Assigns this three-dimensional symmetric dyadic tensor by
97 /// copying another one.
98 template <typename OtherNumericType>
100 xx_xy_xz_yy_yz_zz_[0] = static_cast<NumericType>(other.xx());
101 xx_xy_xz_yy_yz_zz_[1] = static_cast<NumericType>(other.xy());
102 xx_xy_xz_yy_yz_zz_[2] = static_cast<NumericType>(other.xz());
103 xx_xy_xz_yy_yz_zz_[3] = static_cast<NumericType>(other.yy());
104 xx_xy_xz_yy_yz_zz_[4] = static_cast<NumericType>(other.yz());
105 xx_xy_xz_yy_yz_zz_[5] = static_cast<NumericType>(other.zz());
106 return *this;
107 }
108
109 /// \brief Move assignment operator. Assigns this three-dimensional symmetric dyadic tensor by
110 /// moving another one.
112 SymmetricDyad<NumericType>&& other) noexcept = default;
113
114 /// \brief Assignment operator. Assigns this three-dimensional symmetric dyadic tensor by copying
115 /// a given array representing its xx, xy, xz, yy, yz, and zz Cartesian components.
117 const std::array<NumericType, 6>& xx_xy_xz_yy_yz_zz) {
119 return *this;
120 }
121
122 /// \brief Statically creates a three-dimensional symmetric dyadic tensor with its xx, xy, xz, yy,
123 /// yz, and zz Cartesian components initialized to zero.
124 [[nodiscard]] static constexpr SymmetricDyad<NumericType> Zero() {
126 std::array<NumericType, 6>{
127 static_cast<NumericType>(0), static_cast<NumericType>(0), static_cast<NumericType>(0),
128 static_cast<NumericType>(0), static_cast<NumericType>(0), static_cast<NumericType>(0)}
129 };
130 }
131
132 /// \brief Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz
133 /// Cartesian components as an array.
134 [[nodiscard]] constexpr const std::array<NumericType, 6>& xx_xy_xz_yy_yz_zz() const noexcept {
135 return xx_xy_xz_yy_yz_zz_;
136 }
137
138 /// \brief Returns this three-dimensional symmetric dyadic tensor's xx Cartesian component.
139 [[nodiscard]] constexpr NumericType xx() const noexcept {
140 return xx_xy_xz_yy_yz_zz_[0];
141 }
142
143 /// \brief Returns this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component.
144 [[nodiscard]] constexpr NumericType xy() const noexcept {
145 return xx_xy_xz_yy_yz_zz_[1];
146 }
147
148 /// \brief Returns this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component.
149 [[nodiscard]] constexpr NumericType xz() const noexcept {
150 return xx_xy_xz_yy_yz_zz_[2];
151 }
152
153 /// \brief Returns this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component.
154 [[nodiscard]] constexpr NumericType yx() const noexcept {
155 return xx_xy_xz_yy_yz_zz_[1];
156 }
157
158 /// \brief Returns this three-dimensional symmetric dyadic tensor's yy Cartesian component.
159 [[nodiscard]] constexpr NumericType yy() const noexcept {
160 return xx_xy_xz_yy_yz_zz_[3];
161 }
162
163 /// \brief Returns this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component.
164 [[nodiscard]] constexpr NumericType yz() const noexcept {
165 return xx_xy_xz_yy_yz_zz_[4];
166 }
167
168 /// \brief Returns this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component.
169 [[nodiscard]] constexpr NumericType zx() const noexcept {
170 return xx_xy_xz_yy_yz_zz_[2];
171 }
172
173 /// \brief Returns this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component.
174 [[nodiscard]] constexpr NumericType zy() const noexcept {
175 return xx_xy_xz_yy_yz_zz_[4];
176 }
177
178 /// \brief Returns this three-dimensional symmetric dyadic tensor's zz Cartesian component.
179 [[nodiscard]] constexpr NumericType zz() const noexcept {
180 return xx_xy_xz_yy_yz_zz_[5];
181 }
182
183 /// \brief Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz
184 /// Cartesian components as a mutable array.
185 [[nodiscard]] constexpr std::array<NumericType, 6>& Mutable_xx_xy_xz_yy_yz_zz() noexcept {
186 return xx_xy_xz_yy_yz_zz_;
187 }
188
189 /// \brief Returns this three-dimensional symmetric dyadic tensor's xx Cartesian component as a
190 /// mutable value.
191 [[nodiscard]] constexpr NumericType& Mutable_xx() noexcept {
192 return xx_xy_xz_yy_yz_zz_[0];
193 }
194
195 /// \brief Returns this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component as
196 /// a mutable value.
197 [[nodiscard]] constexpr NumericType& Mutable_xy() noexcept {
198 return xx_xy_xz_yy_yz_zz_[1];
199 }
200
201 /// \brief Returns this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component as
202 /// a mutable value.
203 [[nodiscard]] constexpr NumericType& Mutable_xz() noexcept {
204 return xx_xy_xz_yy_yz_zz_[2];
205 }
206
207 /// \brief Returns this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component as
208 /// a mutable value.
209 [[nodiscard]] constexpr NumericType& Mutable_yx() noexcept {
210 return xx_xy_xz_yy_yz_zz_[1];
211 }
212
213 /// \brief Returns this three-dimensional symmetric dyadic tensor's yy Cartesian component as a
214 /// mutable value.
215 [[nodiscard]] constexpr NumericType& Mutable_yy() noexcept {
216 return xx_xy_xz_yy_yz_zz_[3];
217 }
218
219 /// \brief Returns this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component as
220 /// a mutable value.
221 [[nodiscard]] constexpr NumericType& Mutable_yz() noexcept {
222 return xx_xy_xz_yy_yz_zz_[4];
223 }
224
225 /// \brief Returns this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component as
226 /// a mutable value.
227 [[nodiscard]] constexpr NumericType& Mutable_zx() noexcept {
228 return xx_xy_xz_yy_yz_zz_[2];
229 }
230
231 /// \brief Returns this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component as
232 /// a mutable value.
233 [[nodiscard]] constexpr NumericType& Mutable_zy() noexcept {
234 return xx_xy_xz_yy_yz_zz_[4];
235 }
236
237 /// \brief Returns this three-dimensional symmetric dyadic tensor's zz Cartesian component as a
238 /// mutable value.
239 [[nodiscard]] constexpr NumericType& Mutable_zz() noexcept {
240 return xx_xy_xz_yy_yz_zz_[5];
241 }
242
243 /// \brief Sets this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz
244 /// Cartesian components to the given values.
245 constexpr void Set_xx_xy_xz_yy_yz_zz(
246 const std::array<NumericType, 6>& xx_xy_xz_yy_yz_zz) noexcept {
248 }
249
250 /// \brief Sets this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz
251 /// Cartesian components to the given values.
252 constexpr void Set_xx_xy_xz_yy_yz_zz(
253 const NumericType xx, const NumericType xy, const NumericType xz, const NumericType yy,
254 const NumericType yz, const NumericType zz) noexcept {
261 }
262
263 /// \brief Sets this three-dimensional symmetric dyadic tensor's xx Cartesian component to a given
264 /// value.
265 constexpr void Set_xx(const NumericType xx) noexcept {
267 }
268
269 /// \brief Sets this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component to a
270 /// given value.
271 constexpr void Set_xy(const NumericType xy) noexcept {
273 }
274
275 /// \brief Sets this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component to a
276 /// given value.
277 constexpr void Set_xz(const NumericType xz) noexcept {
279 }
280
281 /// \brief Sets this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component to a
282 /// given value.
283 constexpr void Set_yx(const NumericType yx) noexcept {
285 }
286
287 /// \brief Sets this three-dimensional symmetric dyadic tensor's yy Cartesian component to a given
288 /// value.
289 constexpr void Set_yy(const NumericType yy) noexcept {
291 }
292
293 /// \brief Sets this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component to a
294 /// given value.
295 constexpr void Set_yz(const NumericType yz) noexcept {
297 }
298
299 /// \brief Sets this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component to a
300 /// given value.
301 constexpr void Set_zx(const NumericType zx) noexcept {
303 }
304
305 /// \brief Sets this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component to a
306 /// given value.
307 constexpr void Set_zy(const NumericType zy) noexcept {
309 }
310
311 /// \brief Sets this three-dimensional symmetric dyadic tensor's zz Cartesian component to a given
312 /// value.
313 constexpr void Set_zz(const NumericType zz) noexcept {
315 }
316
317 /// \brief Returns the trace of this three-dimensional symmetric dyadic tensor.
318 [[nodiscard]] constexpr NumericType Trace() const noexcept {
319 return xx() + yy() + zz();
320 }
321
322 /// \brief Returns the determinant of this three-dimensional symmetric dyadic tensor.
323 [[nodiscard]] constexpr NumericType Determinant() const noexcept {
324 return xx() * (yy() * zz() - yz() * zy()) + xy() * (yz() * zx() - yx() * zz())
325 + xz() * (yx() * zy() - yy() * zx());
326 }
327
328 /// \brief Returns the transpose of this three-dimensional symmetric dyadic tensor.
329 [[nodiscard]] constexpr const SymmetricDyad<NumericType>& Transpose() const noexcept {
330 return *this;
331 }
332
333 /// \brief Returns the cofactors of this three-dimensional symmetric dyadic tensor.
334 [[nodiscard]] constexpr SymmetricDyad<NumericType> Cofactors() const {
335 const NumericType cofactor_xx{yy() * zz() - yz() * yz()};
336 const NumericType cofactor_xy{xz() * yz() - xy() * zz()};
337 const NumericType cofactor_xz{xy() * yz() - xz() * yy()};
338 const NumericType cofactor_yy{xx() * zz() - xz() * xz()};
339 const NumericType cofactor_yz{xy() * xz() - xx() * yz()};
340 const NumericType cofactor_zz{xx() * yy() - xy() * xy()};
342 cofactor_xx, cofactor_xy, cofactor_xz, cofactor_yy, cofactor_yz, cofactor_zz};
343 }
344
345 /// \brief Returns the adjugate of this three-dimensional symmetric dyadic tensor.
346 [[nodiscard]] constexpr SymmetricDyad<NumericType> Adjugate() const {
347 // In general, for a dyadic tensor, this is cofactors().transpose(), but since this is a
348 // symmetric dyadic tensor, the transpose is redundant.
349 return Cofactors();
350 }
351
352 /// \brief Returns the inverse of this three-dimensional symmetric dyadic tensor if it exists, or
353 /// std::nullopt otherwise.
354 [[nodiscard]] std::optional<SymmetricDyad<NumericType>> Inverse() const;
355
356 /// \brief Prints this three-dimensional symmetric dyadic tensor as a string.
357 [[nodiscard]] std::string Print() const {
358 return "(" + PhQ::Print(xx_xy_xz_yy_yz_zz_[0]) + ", " + PhQ::Print(xx_xy_xz_yy_yz_zz_[1]) + ", "
361 }
362
363 /// \brief Serializes this three-dimensional symmetric dyadic tensor as a JSON message.
364 [[nodiscard]] std::string JSON() const {
365 return "{\"xx\":" + PhQ::Print(xx_xy_xz_yy_yz_zz_[0]) + ",\"xy\":"
367 + ",\"yy\":" + PhQ::Print(xx_xy_xz_yy_yz_zz_[3])
368 + ",\"yz\":" + PhQ::Print(xx_xy_xz_yy_yz_zz_[4])
369 + ",\"zz\":" + PhQ::Print(xx_xy_xz_yy_yz_zz_[5]) + "}";
370 }
371
372 /// \brief Serializes this three-dimensional symmetric dyadic tensor as an XML message.
373 [[nodiscard]] std::string XML() const {
374 return "<xx>" + PhQ::Print(xx_xy_xz_yy_yz_zz_[0]) + "</xx><xy>"
376 + "</xz><yy>" + PhQ::Print(xx_xy_xz_yy_yz_zz_[3]) + "</yy><yz>"
378 + "</zz>";
379 }
380
381 /// \brief Serializes this three-dimensional symmetric dyadic tensor as a YAML message.
382 [[nodiscard]] std::string YAML() const {
383 return "{xx:" + PhQ::Print(xx_xy_xz_yy_yz_zz_[0]) + ",xy:" + PhQ::Print(xx_xy_xz_yy_yz_zz_[1])
384 + ",xz:" + PhQ::Print(xx_xy_xz_yy_yz_zz_[2]) + ",yy:" + PhQ::Print(xx_xy_xz_yy_yz_zz_[3])
385 + ",yz:" + PhQ::Print(xx_xy_xz_yy_yz_zz_[4]) + ",zz:" + PhQ::Print(xx_xy_xz_yy_yz_zz_[5])
386 + "}";
387 }
388
389 /// \brief Adds another three-dimensional symmetric dyadic tensor to this one.
390 constexpr void operator+=(const SymmetricDyad<NumericType>& other) noexcept {
391 xx_xy_xz_yy_yz_zz_[0] += other.xx_xy_xz_yy_yz_zz_[0];
392 xx_xy_xz_yy_yz_zz_[1] += other.xx_xy_xz_yy_yz_zz_[1];
393 xx_xy_xz_yy_yz_zz_[2] += other.xx_xy_xz_yy_yz_zz_[2];
394 xx_xy_xz_yy_yz_zz_[3] += other.xx_xy_xz_yy_yz_zz_[3];
395 xx_xy_xz_yy_yz_zz_[4] += other.xx_xy_xz_yy_yz_zz_[4];
396 xx_xy_xz_yy_yz_zz_[5] += other.xx_xy_xz_yy_yz_zz_[5];
397 }
398
399 /// \brief Subtracts another three-dimensional symmetric dyadic tensor from this one.
400 constexpr void operator-=(const SymmetricDyad<NumericType>& other) noexcept {
401 xx_xy_xz_yy_yz_zz_[0] -= other.xx_xy_xz_yy_yz_zz_[0];
402 xx_xy_xz_yy_yz_zz_[1] -= other.xx_xy_xz_yy_yz_zz_[1];
403 xx_xy_xz_yy_yz_zz_[2] -= other.xx_xy_xz_yy_yz_zz_[2];
404 xx_xy_xz_yy_yz_zz_[3] -= other.xx_xy_xz_yy_yz_zz_[3];
405 xx_xy_xz_yy_yz_zz_[4] -= other.xx_xy_xz_yy_yz_zz_[4];
406 xx_xy_xz_yy_yz_zz_[5] -= other.xx_xy_xz_yy_yz_zz_[5];
407 }
408
409 /// \brief Multiplies this three-dimensional symmetric dyadic tensor by the given number.
410 /// \tparam OtherNumericType Floating-point numeric type of the given number. Deduced
411 /// automatically.
412 template <typename OtherNumericType>
413 constexpr void operator*=(const OtherNumericType number) noexcept {
414 xx_xy_xz_yy_yz_zz_[0] *= static_cast<NumericType>(number);
415 xx_xy_xz_yy_yz_zz_[1] *= static_cast<NumericType>(number);
416 xx_xy_xz_yy_yz_zz_[2] *= static_cast<NumericType>(number);
417 xx_xy_xz_yy_yz_zz_[3] *= static_cast<NumericType>(number);
418 xx_xy_xz_yy_yz_zz_[4] *= static_cast<NumericType>(number);
419 xx_xy_xz_yy_yz_zz_[5] *= static_cast<NumericType>(number);
420 }
421
422 /// \brief Divides this three-dimensional symmetric dyadic tensor by the given number.
423 /// \tparam OtherNumericType Floating-point numeric type of the given number. Deduced
424 /// automatically.
425 template <typename OtherNumericType>
426 constexpr void operator/=(const OtherNumericType number) noexcept {
427 xx_xy_xz_yy_yz_zz_[0] /= static_cast<NumericType>(number);
428 xx_xy_xz_yy_yz_zz_[1] /= static_cast<NumericType>(number);
429 xx_xy_xz_yy_yz_zz_[2] /= static_cast<NumericType>(number);
430 xx_xy_xz_yy_yz_zz_[3] /= static_cast<NumericType>(number);
431 xx_xy_xz_yy_yz_zz_[4] /= static_cast<NumericType>(number);
432 xx_xy_xz_yy_yz_zz_[5] /= static_cast<NumericType>(number);
433 }
434
435private:
436 /// \brief Cartesian components of this three-dimensional symmetric dyadic tensor.
437 std::array<NumericType, 6> xx_xy_xz_yy_yz_zz_;
438};
439
440template <typename NumericType>
441inline constexpr bool operator==(
442 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) noexcept {
443 return (left.xx() == right.xx() && left.xy() == right.xy() && left.xz() == right.xz()
444 && left.yy() == right.yy() && left.yz() == right.yz() && left.zz() == right.zz());
445}
446
447template <typename NumericType>
448inline constexpr bool operator!=(
449 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) noexcept {
450 return (left.xx() != right.xx() || left.xy() != right.xy() || left.xz() != right.xz()
451 || left.yy() != right.yy() || left.yz() != right.yz() || left.zz() != right.zz());
452}
453
454template <typename NumericType>
455inline constexpr bool operator<(
456 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) noexcept {
457 if (left.xx() != right.xx()) {
458 return left.xx() < right.xx();
459 }
460 if (left.xy() != right.xy()) {
461 return left.xy() < right.xy();
462 }
463 if (left.xz() != right.xz()) {
464 return left.xz() < right.xz();
465 }
466 if (left.yy() != right.yy()) {
467 return left.yy() < right.yy();
468 }
469 if (left.yz() != right.yz()) {
470 return left.yz() < right.yz();
471 }
472 return left.zz() < right.zz();
473}
474
475template <typename NumericType>
476inline constexpr bool operator>(
477 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) noexcept {
478 if (left.xx() != right.xx()) {
479 return left.xx() > right.xx();
480 }
481 if (left.xy() != right.xy()) {
482 return left.xy() > right.xy();
483 }
484 if (left.xz() != right.xz()) {
485 return left.xz() > right.xz();
486 }
487 if (left.yy() != right.yy()) {
488 return left.yy() > right.yy();
489 }
490 if (left.yz() != right.yz()) {
491 return left.yz() > right.yz();
492 }
493 return left.zz() > right.zz();
494}
495
496template <typename NumericType>
497inline constexpr bool operator<=(
498 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) noexcept {
499 return !(left > right);
500}
501
502template <typename NumericType>
503inline constexpr bool operator>=(
504 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) noexcept {
505 return !(left < right);
506}
507
508template <typename NumericType>
510 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) {
512 left.xx() + right.xx(), left.xy() + right.xy(), left.xz() + right.xz(),
513 left.yy() + right.yy(), left.yz() + right.yz(), left.zz() + right.zz()};
514}
515
516template <typename NumericType>
518 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right) {
520 left.xx() - right.xx(), left.xy() - right.xy(), left.xz() - right.xz(),
521 left.yy() - right.yy(), left.yz() - right.yz(), left.zz() - right.zz()};
522}
523
524template <typename NumericType, typename OtherNumericType>
526 const SymmetricDyad<NumericType>& symmetric_dyad, const OtherNumericType number) {
528 symmetric_dyad.xx() * static_cast<NumericType>(number),
529 symmetric_dyad.xy() * static_cast<NumericType>(number),
530 symmetric_dyad.xz() * static_cast<NumericType>(number),
531 symmetric_dyad.yy() * static_cast<NumericType>(number),
532 symmetric_dyad.yz() * static_cast<NumericType>(number),
533 symmetric_dyad.zz() * static_cast<NumericType>(number)};
534}
535
536template <typename NumericType, typename OtherNumericType>
538 const OtherNumericType number, const SymmetricDyad<NumericType>& symmetric_dyad) {
539 return SymmetricDyad<NumericType>{symmetric_dyad * number};
540}
541
542template <typename NumericType>
543inline constexpr Vector<NumericType> operator*(const SymmetricDyad<NumericType>& symmetric_dyad,
544 const PlanarVector<NumericType>& planar_vector) {
545 return Vector<NumericType>{
546 symmetric_dyad.xx() * planar_vector.x() + symmetric_dyad.xy() * planar_vector.y(),
547 symmetric_dyad.xy() * planar_vector.x() + symmetric_dyad.yy() * planar_vector.y(),
548 symmetric_dyad.xz() * planar_vector.x() + symmetric_dyad.yz() * planar_vector.y()};
549}
550
551template <typename NumericType>
553 const SymmetricDyad<NumericType>& symmetric_dyad, const Vector<NumericType>& vector) {
554 return Vector<NumericType>{
555 symmetric_dyad.xx() * vector.x() + symmetric_dyad.xy() * vector.y()
556 + symmetric_dyad.xz() * vector.z(),
557 symmetric_dyad.xy() * vector.x() + symmetric_dyad.yy() * vector.y()
558 + symmetric_dyad.yz() * vector.z(),
559 symmetric_dyad.xz() * vector.x() + symmetric_dyad.yz() * vector.y()
560 + symmetric_dyad.zz() * vector.z()};
561}
562
563template <typename NumericType>
564inline constexpr Dyad<NumericType> operator*(
565 const SymmetricDyad<NumericType>& left, const SymmetricDyad<NumericType>& right);
566
567template <typename NumericType>
568inline constexpr Dyad<NumericType> operator*(
569 const SymmetricDyad<NumericType>& symmetric_dyad, const Dyad<NumericType>& dyad);
570
571template <typename NumericType, typename OtherNumericType>
573 const SymmetricDyad<NumericType>& symmetric_dyad, const OtherNumericType number) {
575 symmetric_dyad.xx() / static_cast<NumericType>(number),
576 symmetric_dyad.xy() / static_cast<NumericType>(number),
577 symmetric_dyad.xz() / static_cast<NumericType>(number),
578 symmetric_dyad.yy() / static_cast<NumericType>(number),
579 symmetric_dyad.yz() / static_cast<NumericType>(number),
580 symmetric_dyad.zz() / static_cast<NumericType>(number)};
581}
582
583template <typename NumericType>
584inline std::optional<SymmetricDyad<NumericType>> SymmetricDyad<NumericType>::Inverse() const {
585 const NumericType determinant_{Determinant()};
586 if (determinant_ != 0.0) {
587 return std::optional<SymmetricDyad>{Adjugate() / determinant_};
588 }
589 return std::nullopt;
590}
591
592template <typename NumericType>
593inline std::ostream& operator<<(std::ostream& stream, const SymmetricDyad<NumericType>& symmetric) {
594 stream << symmetric.Print();
595 return stream;
596}
597
598} // namespace PhQ
599
600namespace std {
601
602template <typename NumericType>
603struct hash<PhQ::SymmetricDyad<NumericType>> {
604 inline size_t operator()(const PhQ::SymmetricDyad<NumericType>& symmetric) const {
605 size_t result{17};
606 result = static_cast<size_t>(31) * result + hash<NumericType>()(symmetric.xx());
607 result = static_cast<size_t>(31) * result + hash<NumericType>()(symmetric.xy());
608 result = static_cast<size_t>(31) * result + hash<NumericType>()(symmetric.xz());
609 result = static_cast<size_t>(31) * result + hash<NumericType>()(symmetric.yy());
610 result = static_cast<size_t>(31) * result + hash<NumericType>()(symmetric.yz());
611 result = static_cast<size_t>(31) * result + hash<NumericType>()(symmetric.zz());
612 return result;
613 }
614};
615
616} // namespace std
617
618#endif // PHQ_SYMMETRIC_DYAD_HPP
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.
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...
std::optional< SymmetricDyad< NumericType > > Inverse() const
Returns the inverse of this three-dimensional symmetric dyadic tensor if it exists,...
constexpr NumericType xy() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component.
constexpr void Set_zz(const NumericType zz) noexcept
Sets this three-dimensional symmetric dyadic tensor's zz Cartesian component to a given value.
static constexpr SymmetricDyad< NumericType > Zero()
Statically creates a three-dimensional symmetric dyadic tensor with its xx, xy, xz,...
std::array< NumericType, 6 > xx_xy_xz_yy_yz_zz_
Cartesian components of this three-dimensional symmetric dyadic tensor.
constexpr void Set_yx(const NumericType yx) noexcept
Sets this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component to a given value.
constexpr NumericType & Mutable_yx() noexcept
Returns this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component as a mutable val...
constexpr void Set_yz(const NumericType yz) noexcept
Sets this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component to a given value.
constexpr NumericType xx() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xx Cartesian component.
constexpr NumericType Trace() const noexcept
Returns the trace of this three-dimensional symmetric dyadic tensor.
constexpr SymmetricDyad< NumericType > & operator=(const SymmetricDyad< OtherNumericType > &other)
Copy assignment operator. Assigns this three-dimensional symmetric dyadic tensor by copying another o...
std::string XML() const
Serializes this three-dimensional symmetric dyadic tensor as an XML message.
constexpr const SymmetricDyad< NumericType > & Transpose() const noexcept
Returns the transpose of this three-dimensional symmetric dyadic tensor.
constexpr const std::array< NumericType, 6 > & xx_xy_xz_yy_yz_zz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz Cartesian compone...
constexpr NumericType & Mutable_xz() noexcept
Returns this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component as a mutable val...
constexpr void operator*=(const OtherNumericType number) noexcept
Multiplies this three-dimensional symmetric dyadic tensor by the given number.
constexpr NumericType zx() const noexcept
Returns this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component.
constexpr NumericType & Mutable_xy() noexcept
Returns this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component as a mutable val...
SymmetricDyad()=default
Default constructor. Constructs a three-dimensional symmetric dyadic tensor with uninitialized xx,...
constexpr void operator-=(const SymmetricDyad< NumericType > &other) noexcept
Subtracts another three-dimensional symmetric dyadic tensor from this one.
constexpr NumericType & Mutable_zy() noexcept
Returns this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component as a mutable val...
~SymmetricDyad() noexcept=default
Destructor. Destroys this three-dimensional symmetric dyadic tensor.
constexpr NumericType zz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's zz Cartesian component.
constexpr NumericType & Mutable_xx() noexcept
Returns this three-dimensional symmetric dyadic tensor's xx Cartesian component as a mutable value.
constexpr NumericType & Mutable_yy() noexcept
Returns this three-dimensional symmetric dyadic tensor's yy Cartesian component as a mutable value.
constexpr NumericType & Mutable_zx() noexcept
Returns this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component as a mutable val...
constexpr void Set_xx_xy_xz_yy_yz_zz(const std::array< NumericType, 6 > &xx_xy_xz_yy_yz_zz) noexcept
Sets this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz Cartesian components...
constexpr SymmetricDyad(const std::array< NumericType, 6 > &xx_xy_xz_yy_yz_zz)
Constructor. Constructs a three-dimensional symmetric dyadic tensor from a given array representing i...
constexpr void Set_xx_xy_xz_yy_yz_zz(const NumericType xx, const NumericType xy, const NumericType xz, const NumericType yy, const NumericType yz, const NumericType zz) noexcept
Sets this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz Cartesian components...
constexpr void Set_zy(const NumericType zy) noexcept
Sets this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component to a given value.
constexpr std::array< NumericType, 6 > & Mutable_xx_xy_xz_yy_yz_zz() noexcept
Returns this three-dimensional symmetric dyadic tensor's xx, xy, xz, yy, yz, and zz Cartesian compone...
constexpr SymmetricDyad< NumericType > & operator=(const std::array< NumericType, 6 > &xx_xy_xz_yy_yz_zz)
Assignment operator. Assigns this three-dimensional symmetric dyadic tensor by copying a given array ...
constexpr SymmetricDyad< NumericType > Cofactors() const
Returns the cofactors of this three-dimensional symmetric dyadic tensor.
constexpr NumericType yx() const noexcept
Returns this three-dimensional symmetric dyadic tensor's yx = xy Cartesian component.
constexpr void operator/=(const OtherNumericType number) noexcept
Divides this three-dimensional symmetric dyadic tensor by the given number.
constexpr SymmetricDyad< NumericType > & operator=(const SymmetricDyad< NumericType > &other)=default
Copy assignment operator. Assigns this three-dimensional symmetric dyadic tensor by copying another o...
constexpr NumericType Determinant() const noexcept
Returns the determinant of this three-dimensional symmetric dyadic tensor.
std::string JSON() const
Serializes this three-dimensional symmetric dyadic tensor as a JSON message.
constexpr void Set_xz(const NumericType xz) noexcept
Sets this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component to a given value.
constexpr NumericType yy() const noexcept
Returns this three-dimensional symmetric dyadic tensor's yy Cartesian component.
constexpr void Set_xy(const NumericType xy) noexcept
Sets this three-dimensional symmetric dyadic tensor's xy = yx Cartesian component to a given value.
constexpr void Set_xx(const NumericType xx) noexcept
Sets this three-dimensional symmetric dyadic tensor's xx Cartesian component to a given value.
std::string YAML() const
Serializes this three-dimensional symmetric dyadic tensor as a YAML message.
constexpr SymmetricDyad< NumericType > & operator=(SymmetricDyad< NumericType > &&other) noexcept=default
Move assignment operator. Assigns this three-dimensional symmetric dyadic tensor by moving another on...
constexpr SymmetricDyad< NumericType > Adjugate() const
Returns the adjugate of this three-dimensional symmetric dyadic tensor.
constexpr NumericType & Mutable_zz() noexcept
Returns this three-dimensional symmetric dyadic tensor's zz Cartesian component as a mutable value.
constexpr NumericType xz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's xz = zx Cartesian component.
constexpr void Set_zx(const NumericType zx) noexcept
Sets this three-dimensional symmetric dyadic tensor's zx = xz Cartesian component to a given value.
constexpr NumericType yz() const noexcept
Returns this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component.
constexpr void operator+=(const SymmetricDyad< NumericType > &other) noexcept
Adds another three-dimensional symmetric dyadic tensor to this one.
constexpr NumericType & Mutable_yz() noexcept
Returns this three-dimensional symmetric dyadic tensor's yz = zy Cartesian component as a mutable val...
constexpr void Set_yy(const NumericType yy) noexcept
Sets this three-dimensional symmetric dyadic tensor's yy Cartesian component to a given value.
constexpr NumericType zy() const noexcept
Returns this three-dimensional symmetric dyadic tensor's zy = yz Cartesian component.
constexpr SymmetricDyad(const NumericType xx, const NumericType xy, const NumericType xz, const NumericType yy, const NumericType yz, const NumericType zz)
Constructor. Constructs a three-dimensional symmetric dyadic tensor from the given xx,...
std::string Print() const
Prints this three-dimensional symmetric dyadic tensor as a string.
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
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.
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)
constexpr Dyad< NumericType > operator+(const Dyad< NumericType > &left, const Dyad< NumericType > &right)
Definition Dyad.hpp:568
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 > &dyad, const OtherNumericType number)
Definition Dyad.hpp:696
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 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 bool operator!=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
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