Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
Force.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_FORCE_HPP
26 #define PHQ_FORCE_HPP
27 
28 #include <array>
29 #include <cstddef>
30 #include <functional>
31 #include <ostream>
32 
33 #include "Angle.hpp"
34 #include "DimensionalVector.hpp"
35 #include "Direction.hpp"
36 #include "PlanarForce.hpp"
37 #include "ScalarForce.hpp"
38 #include "Unit/Force.hpp"
39 #include "Vector.hpp"
40 
41 namespace PhQ {
42 
43 // Forward declaration for class PhQ::Force.
44 template <typename NumericType>
45 class Traction;
46 
47 /// \brief Three-dimensional Euclidean force vector. Contains three components in Cartesian
48 /// coordinates: x, y, and z. For a two-dimensional Euclidean force vector in the XY plane, see
49 /// PhQ::PlanarForce. For scalar force components or for the magnitude of a force vector, see
50 /// PhQ::ScalarForce.
51 template <typename NumericType = double>
52 class Force : public DimensionalVector<Unit::Force, NumericType> {
53 public:
54  /// \brief Default constructor. Constructs a force vector with an uninitialized value.
55  Force() = default;
56 
57  /// \brief Constructor. Constructs a force vector with a given value expressed in a given force
58  /// unit.
60  : DimensionalVector<Unit::Force, NumericType>(value, unit) {}
61 
62  /// \brief Constructor. Constructs a force vector from a given set of scalar force components.
65  : Force<NumericType>({x.Value(), y.Value(), z.Value()}) {}
66 
67  /// \brief Constructor. Constructs a force vector from a given scalar force magnitude and
68  /// direction.
69  constexpr Force(
70  const ScalarForce<NumericType>& scalar_force, const Direction<NumericType>& direction)
71  : Force<NumericType>(scalar_force.Value() * direction.Value()) {}
72 
73  /// \brief Constructor. Constructs a force vector from a given planar force vector in the XY
74  /// plane. This force vector's z-component is initialized to zero.
75  explicit constexpr Force(const PlanarForce<NumericType>& planar_force)
76  : Force<NumericType>(Vector<NumericType>{planar_force.Value()}) {}
77 
78  /// \brief Constructor. Constructs a force vector from a given traction and area using the
79  /// definition of traction.
80  constexpr Force(const Traction<NumericType>& traction, const Area<NumericType>& area);
81 
82  /// \brief Destructor. Destroys this force vector.
83  ~Force() noexcept = default;
84 
85  /// \brief Copy constructor. Constructs a force vector by copying another one.
86  constexpr Force(const Force<NumericType>& other) = default;
87 
88  /// \brief Copy constructor. Constructs a force vector by copying another one.
89  template <typename OtherNumericType>
90  explicit constexpr Force(const Force<OtherNumericType>& other)
91  : Force(static_cast<Vector<NumericType>>(other.Value())) {}
92 
93  /// \brief Move constructor. Constructs a force vector by moving another one.
94  constexpr Force(Force<NumericType>&& other) noexcept = default;
95 
96  /// \brief Copy assignment operator. Assigns this force vector by copying another one.
97  constexpr Force<NumericType>& operator=(const Force<NumericType>& other) = default;
98 
99  /// \brief Copy assignment operator. Assigns this force vector by copying another one.
100  template <typename OtherNumericType>
102  this->value = static_cast<Vector<NumericType>>(other.Value());
103  return *this;
104  }
105 
106  /// \brief Move assignment operator. Assigns this force vector by moving another one.
107  constexpr Force<NumericType>& operator=(Force<NumericType>&& other) noexcept = default;
108 
109  /// \brief Statically creates a force vector of zero.
110  [[nodiscard]] static constexpr Force<NumericType> Zero() {
112  }
113 
114  /// \brief Statically creates a force vector from the given x, y, and z Cartesian components
115  /// expressed in a given force unit.
116  template <Unit::Force Unit>
117  [[nodiscard]] static constexpr Force<NumericType> Create(
118  const NumericType x, const NumericType y, const NumericType z) {
119  return Force<NumericType>{
120  ConvertStatically<Unit::Force, Unit, Standard<Unit::Force>>(Vector<NumericType>{x, y, z})};
121  }
122 
123  /// \brief Statically creates a force vector from the given x, y, and z Cartesian components
124  /// expressed in a given force unit.
125  template <Unit::Force Unit>
126  [[nodiscard]] static constexpr Force<NumericType> Create(
127  const std::array<NumericType, 3>& x_y_z) {
128  return Force<NumericType>{
129  ConvertStatically<Unit::Force, Unit, Standard<Unit::Force>>(Vector<NumericType>{x_y_z})};
130  }
131 
132  /// \brief Statically creates a force vector with a given value expressed in a given force unit.
133  template <Unit::Force Unit>
134  [[nodiscard]] static constexpr Force<NumericType> Create(const Vector<NumericType>& value) {
135  return Force<NumericType>{ConvertStatically<Unit::Force, Unit, Standard<Unit::Force>>(value)};
136  }
137 
138  /// \brief Returns the x Cartesian component of this force vector.
139  [[nodiscard]] constexpr ScalarForce<NumericType> x() const noexcept {
140  return ScalarForce<NumericType>{this->value.x()};
141  }
142 
143  /// \brief Returns the y Cartesian component of this force vector.
144  [[nodiscard]] constexpr ScalarForce<NumericType> y() const noexcept {
145  return ScalarForce<NumericType>{this->value.y()};
146  }
147 
148  /// \brief Returns the z Cartesian component of this force vector.
149  [[nodiscard]] constexpr ScalarForce<NumericType> z() const noexcept {
150  return ScalarForce<NumericType>{this->value.z()};
151  }
152 
153  /// \brief Returns the magnitude of this force vector.
154  [[nodiscard]] ScalarForce<NumericType> Magnitude() const {
155  return ScalarForce<NumericType>{this->value.Magnitude()};
156  }
157 
158  /// \brief Returns the direction of this force vector.
159  [[nodiscard]] PhQ::Direction<NumericType> Direction() const {
160  return this->value.Direction();
161  }
162 
163  /// \brief Returns the angle between this force vector and another one.
164  [[nodiscard]] PhQ::Angle<NumericType> Angle(const Force<NumericType>& force) const {
165  return PhQ::Angle<NumericType>{*this, force};
166  }
167 
168  constexpr Force<NumericType> operator+(const Force<NumericType>& force) const {
169  return Force<NumericType>{this->value + force.value};
170  }
171 
172  constexpr Force<NumericType> operator-(const Force<NumericType>& force) const {
173  return Force<NumericType>{this->value - force.value};
174  }
175 
176  constexpr Force<NumericType> operator*(const NumericType number) const {
177  return Force<NumericType>{this->value * number};
178  }
179 
180  constexpr Force<NumericType> operator/(const NumericType number) const {
181  return Force<NumericType>{this->value / number};
182  }
183 
184  constexpr Traction<NumericType> operator/(const Area<NumericType>& area) const;
185 
186  constexpr void operator+=(const Force<NumericType>& force) noexcept {
187  this->value += force.value;
188  }
189 
190  constexpr void operator-=(const Force<NumericType>& force) noexcept {
191  this->value -= force.value;
192  }
193 
194  constexpr void operator*=(const NumericType number) noexcept {
195  this->value *= number;
196  }
197 
198  constexpr void operator/=(const NumericType number) noexcept {
199  this->value /= number;
200  }
201 
202 private:
203  /// \brief Constructor. Constructs a force vector with a given value expressed in the standard
204  /// force unit.
205  explicit constexpr Force(const Vector<NumericType>& value)
206  : DimensionalVector<Unit::Force, NumericType>(value) {}
207 };
208 
209 template <typename NumericType>
210 inline constexpr bool operator==(
211  const Force<NumericType>& left, const Force<NumericType>& right) noexcept {
212  return left.Value() == right.Value();
213 }
214 
215 template <typename NumericType>
216 inline constexpr bool operator!=(
217  const Force<NumericType>& left, const Force<NumericType>& right) noexcept {
218  return left.Value() != right.Value();
219 }
220 
221 template <typename NumericType>
222 inline constexpr bool operator<(
223  const Force<NumericType>& left, const Force<NumericType>& right) noexcept {
224  return left.Value() < right.Value();
225 }
226 
227 template <typename NumericType>
228 inline constexpr bool operator>(
229  const Force<NumericType>& left, const Force<NumericType>& right) noexcept {
230  return left.Value() > right.Value();
231 }
232 
233 template <typename NumericType>
234 inline constexpr bool operator<=(
235  const Force<NumericType>& left, const Force<NumericType>& right) noexcept {
236  return left.Value() <= right.Value();
237 }
238 
239 template <typename NumericType>
240 inline constexpr bool operator>=(
241  const Force<NumericType>& left, const Force<NumericType>& right) noexcept {
242  return left.Value() >= right.Value();
243 }
244 
245 template <typename NumericType>
246 inline std::ostream& operator<<(std::ostream& stream, const Force<NumericType>& force) {
247  stream << force.Print();
248  return stream;
249 }
250 
251 template <typename NumericType>
252 inline constexpr Force<NumericType> operator*(
253  const NumericType number, const Force<NumericType>& force) {
254  return force * number;
255 }
256 
257 template <typename NumericType>
259  : Direction<NumericType>(force.Value()) {}
260 
261 template <typename NumericType>
262 inline Angle<NumericType>::Angle(const Force<NumericType>& force1, const Force<NumericType>& force2)
263  : Angle<NumericType>(force1.Value(), force2.Value()) {}
264 
265 template <typename NumericType>
267  const ScalarForce<NumericType>& scalar_force) const {
268  return Force<NumericType>{scalar_force, *this};
269 }
270 
271 template <typename NumericType>
273  const Direction<NumericType>& direction) const {
274  return Force<NumericType>{*this, direction};
275 }
276 
277 template <typename NumericType>
279  : PlanarForce(PlanarVector<NumericType>{force.Value()}) {}
280 
281 } // namespace PhQ
282 
283 namespace std {
284 
285 template <typename NumericType>
286 struct hash<PhQ::Force<NumericType>> {
287  inline size_t operator()(const PhQ::Force<NumericType>& force) const {
288  return hash<PhQ::Vector<NumericType>>()(force.Value());
289  }
290 };
291 
292 } // namespace std
293 
294 #endif // PHQ_FORCE_HPP
Plane angle between two lines or dihedral angle between two planes.
Definition: Angle.hpp:130
Angle()=default
Default constructor. Constructs an angle with an uninitialized value.
Surface area or cross-sectional area. Can also represent a scalar component of a vector area or the m...
Definition: Area.hpp:71
constexpr const PhQ::PlanarVector< NumericType > & Value() const noexcept
Value of this physical quantity expressed in its standard unit of measure.
Abstract base class that represents any dimensional vector physical quantity. Such a physical quantit...
std::string Print() const
Prints this physical quantity as a string. This physical quantity's value is expressed in its standar...
static constexpr Unit::Force Unit()
Standard unit of measure for this physical quantity. This physical quantity's value is stored interna...
PhQ::Vector< double > value
Value of this physical quantity expressed in its standard unit of measure.
constexpr const PhQ::Vector< double > & Value() const noexcept
Value of this physical quantity expressed in its standard unit of measure.
Three-dimensional Euclidean direction vector. Contains three components in Cartesian coordinates: x,...
Definition: Direction.hpp:115
constexpr Direction()
Default constructor. Initializes a direction to the zero vector.
Definition: Direction.hpp:118
constexpr Acceleration< NumericType > operator*(const ScalarAcceleration< NumericType > &scalar_acceleration) const
Three-dimensional Euclidean force vector. Contains three components in Cartesian coordinates: x,...
Definition: Force.hpp:52
constexpr Force(const Traction< NumericType > &traction, const Area< NumericType > &area)
Constructor. Constructs a force vector from a given traction and area using the definition of tractio...
static constexpr Force< NumericType > Create(const Vector< NumericType > &value)
Statically creates a force vector with a given value expressed in a given force unit.
Definition: Force.hpp:134
constexpr Force< NumericType > operator+(const Force< NumericType > &force) const
Definition: Force.hpp:168
constexpr ScalarForce< NumericType > x() const noexcept
Returns the x Cartesian component of this force vector.
Definition: Force.hpp:139
constexpr ScalarForce< NumericType > y() const noexcept
Returns the y Cartesian component of this force vector.
Definition: Force.hpp:144
constexpr Force< NumericType > & operator=(Force< NumericType > &&other) noexcept=default
Move assignment operator. Assigns this force vector by moving another one.
constexpr Force< NumericType > operator-(const Force< NumericType > &force) const
Definition: Force.hpp:172
constexpr void operator/=(const NumericType number) noexcept
Definition: Force.hpp:198
constexpr Force< NumericType > operator/(const NumericType number) const
Definition: Force.hpp:180
constexpr Force(const PlanarForce< NumericType > &planar_force)
Constructor. Constructs a force vector from a given planar force vector in the XY plane....
Definition: Force.hpp:75
constexpr Traction< NumericType > operator/(const Area< NumericType > &area) const
ScalarForce< NumericType > Magnitude() const
Returns the magnitude of this force vector.
Definition: Force.hpp:154
constexpr Force< NumericType > & operator=(const Force< NumericType > &other)=default
Copy assignment operator. Assigns this force vector by copying another one.
constexpr void operator*=(const NumericType number) noexcept
Definition: Force.hpp:194
static constexpr Force< NumericType > Create(const NumericType x, const NumericType y, const NumericType z)
Statically creates a force vector from the given x, y, and z Cartesian components expressed in a give...
Definition: Force.hpp:117
constexpr void operator-=(const Force< NumericType > &force) noexcept
Definition: Force.hpp:190
static constexpr Force< NumericType > Create(const std::array< NumericType, 3 > &x_y_z)
Statically creates a force vector from the given x, y, and z Cartesian components expressed in a give...
Definition: Force.hpp:126
PhQ::Direction< NumericType > Direction() const
Returns the direction of this force vector.
Definition: Force.hpp:159
PhQ::Angle< NumericType > Angle(const Force< NumericType > &force) const
Returns the angle between this force vector and another one.
Definition: Force.hpp:164
constexpr Force< NumericType > operator*(const NumericType number) const
Definition: Force.hpp:176
constexpr Force< NumericType > & operator=(const Force< OtherNumericType > &other)
Copy assignment operator. Assigns this force vector by copying another one.
Definition: Force.hpp:101
constexpr Force(const ScalarForce< NumericType > &scalar_force, const Direction< NumericType > &direction)
Constructor. Constructs a force vector from a given scalar force magnitude and direction.
Definition: Force.hpp:69
constexpr Force(const Vector< NumericType > &value)
Constructor. Constructs a force vector with a given value expressed in the standard force unit.
Definition: Force.hpp:205
constexpr void operator+=(const Force< NumericType > &force) noexcept
Definition: Force.hpp:186
Force(const Vector< NumericType > &value, const Unit::Force unit)
Constructor. Constructs a force vector with a given value expressed in a given force unit.
Definition: Force.hpp:59
~Force() noexcept=default
Destructor. Destroys this force vector.
Force()=default
Default constructor. Constructs a force vector with an uninitialized value.
constexpr ScalarForce< NumericType > z() const noexcept
Returns the z Cartesian component of this force vector.
Definition: Force.hpp:149
static constexpr Force< NumericType > Zero()
Statically creates a force vector of zero.
Definition: Force.hpp:110
Force(const ScalarForce< NumericType > &x, const ScalarForce< NumericType > &y, const ScalarForce< NumericType > &z)
Constructor. Constructs a force vector from a given set of scalar force components.
Definition: Force.hpp:63
constexpr Force(Force< NumericType > &&other) noexcept=default
Move constructor. Constructs a force vector by moving another one.
Two-dimensional Euclidean force vector in the XY plane. Contains two components in Cartesian coordina...
Definition: PlanarForce.hpp:50
PlanarForce()=default
Default constructor. Constructs a planar force vector with an uninitialized value.
Two-dimensional Euclidean vector in the XY plane. Contains two components in Cartesian coordinates: x...
Scalar force component or magnitude of a force vector. For a three-dimensional Euclidean force vector...
Definition: ScalarForce.hpp:66
constexpr ScalarForce< NumericType > operator*(const NumericType number) const
Three-dimensional Euclidean traction vector. Contains three components in Cartesian coordinates: x,...
Definition: Traction.hpp:54
Three-dimensional Euclidean vector. Contains three components in Cartesian coordinates: x,...
Definition: Vector.hpp:60
NumericType Magnitude() const noexcept
Returns the magnitude (also known as the L2 norm) of this three-dimensional vector.
Definition: Vector.hpp:209
static constexpr Vector< NumericType > Zero()
Statically creates a three-dimensional vector with its x, y, and z Cartesian components initialized t...
Definition: Vector.hpp:126
constexpr NumericType x() const noexcept
Returns this three-dimensional vector's x Cartesian component.
Definition: Vector.hpp:139
PhQ::Direction< NumericType > Direction() const
Returns the direction of this three-dimensional vector.
Definition: Direction.hpp:377
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
Force
Force units.
Definition: Force.hpp:53
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 bool operator>=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
constexpr bool operator!=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)