Physical Quantities  v1.0.0
C++ library of physical quantities, physical models, and units of measure for scientific computing. https://github.com/acodcha/phq
ElasticIsotropicSolid.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_CONSTITUTIVE_MODEL_ELASTIC_ISOTROPIC_SOLID_HPP
26 #define PHQ_CONSTITUTIVE_MODEL_ELASTIC_ISOTROPIC_SOLID_HPP
27 
28 #include <cmath>
29 #include <cstddef>
30 #include <functional>
31 #include <ostream>
32 #include <string>
33 
34 #include "../Base.hpp"
35 #include "../BulkDynamicViscosity.hpp"
36 #include "../ConstitutiveModel.hpp"
37 #include "../DynamicViscosity.hpp"
38 #include "../IsentropicBulkModulus.hpp"
39 #include "../IsothermalBulkModulus.hpp"
40 #include "../LameFirstModulus.hpp"
41 #include "../PoissonRatio.hpp"
42 #include "../PWaveModulus.hpp"
43 #include "../ShearModulus.hpp"
44 #include "../Strain.hpp"
45 #include "../StrainRate.hpp"
46 #include "../Stress.hpp"
47 #include "../SymmetricDyad.hpp"
48 #include "../Unit/Pressure.hpp"
49 #include "../YoungModulus.hpp"
50 
51 namespace PhQ {
52 
53 /// \brief Constitutive model for an elastic isotropic solid. This is the simplest constitutive
54 /// model for a deformable solid material.
55 template <typename NumericType = double>
57 public:
58  /// \brief Default constructor. Constructs an elastic isotropic solid constitutive model with an
59  /// uninitialized value.
61 
62  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
63  /// Young's modulus and Poisson's ratio.
65  const PoissonRatio<NumericType>& poisson_ratio)
68  young_modulus.Value()
69  / (static_cast<NumericType>(2) * (static_cast<NumericType>(1) + poisson_ratio.Value()))),
70  lame_first_modulus(young_modulus.Value() * poisson_ratio.Value()
71  / ((static_cast<NumericType>(1) + poisson_ratio.Value())
72  * (static_cast<NumericType>(1)
73  - static_cast<NumericType>(2) * poisson_ratio.Value()))) {}
74 
75  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
76  /// Young's modulus and shear modulus.
77  constexpr ElasticIsotropicSolid(const YoungModulus<NumericType>& young_modulus,
81  (shear_modulus.Value()
82  * (young_modulus.Value() - static_cast<NumericType>(2) * shear_modulus.Value()))
83  / (static_cast<NumericType>(3) * shear_modulus.Value() - young_modulus.Value())) {}
84 
85  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
86  /// Young's modulus and isentropic bulk modulus.
88  const IsentropicBulkModulus<NumericType>& isentropic_bulk_modulus)
91  static_cast<NumericType>(3) * young_modulus.Value() * isentropic_bulk_modulus.Value()
92  / (static_cast<NumericType>(9) * isentropic_bulk_modulus.Value()
93  - young_modulus.Value())),
95  static_cast<NumericType>(3) * isentropic_bulk_modulus.Value()
96  * (static_cast<NumericType>(3) * isentropic_bulk_modulus.Value() - young_modulus.Value())
97  / (static_cast<NumericType>(9) * isentropic_bulk_modulus.Value()
98  - young_modulus.Value())) {}
99 
100  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
101  /// Young's modulus and isothermal bulk modulus.
103  const IsothermalBulkModulus<NumericType>& isothermal_bulk_modulus)
104  : ConstitutiveModel(),
106  static_cast<NumericType>(3) * young_modulus.Value() * isothermal_bulk_modulus.Value()
107  / (static_cast<NumericType>(9) * isothermal_bulk_modulus.Value()
108  - young_modulus.Value())),
110  static_cast<NumericType>(3) * isothermal_bulk_modulus.Value()
111  * (static_cast<NumericType>(3) * isothermal_bulk_modulus.Value() - young_modulus.Value())
112  / (static_cast<NumericType>(9) * isothermal_bulk_modulus.Value()
113  - young_modulus.Value())) {}
114 
115  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
116  /// Young's modulus and Lamé's first modulus.
117  constexpr ElasticIsotropicSolid(const YoungModulus<NumericType>& young_modulus,
119  : ConstitutiveModel(),
121  static_cast<NumericType>(0.25)
122  * (young_modulus.Value() - static_cast<NumericType>(3) * lame_first_modulus.Value()
123  + ::std::sqrt(::std::pow(young_modulus.Value(), 2)
124  + static_cast<NumericType>(9) * ::std::pow(lame_first_modulus.Value(), 2)
125  + static_cast<NumericType>(2) * young_modulus.Value()
126  * lame_first_modulus.Value()))),
128 
129  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
130  /// Young's modulus and P-wave modulus.
131  constexpr ElasticIsotropicSolid(const YoungModulus<NumericType>& young_modulus,
132  const PWaveModulus<NumericType>& p_wave_modulus)
133  : ConstitutiveModel(),
135  static_cast<NumericType>(0.125)
136  * (static_cast<NumericType>(3) * p_wave_modulus.Value() + young_modulus.Value()
137  - ::std::sqrt(
138  ::std::pow(young_modulus.Value(), 2)
139  + static_cast<NumericType>(9) * ::std::pow(p_wave_modulus.Value(), 2)
140  - static_cast<NumericType>(10) * young_modulus.Value() * p_wave_modulus.Value()))),
142  static_cast<NumericType>(0.25)
143  * (p_wave_modulus.Value() - young_modulus.Value()
144  + ::std::sqrt(::std::pow(young_modulus.Value(), 2)
145  + static_cast<NumericType>(9) * ::std::pow(p_wave_modulus.Value(), 2)
146  - static_cast<NumericType>(10) * young_modulus.Value()
147  * p_wave_modulus.Value()))) {}
148 
149  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
150  /// shear modulus and Poisson's ratio.
152  const PoissonRatio<NumericType>& poisson_ratio)
155  (static_cast<NumericType>(2) * shear_modulus.Value() * poisson_ratio.Value())
156  / (static_cast<NumericType>(1) - static_cast<NumericType>(2) * poisson_ratio.Value())) {}
157 
158  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
159  /// shear modulus and isentropic bulk modulus.
161  const IsentropicBulkModulus<NumericType>& isentropic_bulk_modulus)
164  isentropic_bulk_modulus.Value()
165  - static_cast<NumericType>(2) / static_cast<NumericType>(3) * shear_modulus.Value()) {}
166 
167  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
168  /// shear modulus and isothermal bulk modulus.
170  const IsothermalBulkModulus<NumericType>& isothermal_bulk_modulus)
173  isothermal_bulk_modulus.Value()
174  - static_cast<NumericType>(2) / static_cast<NumericType>(3) * shear_modulus.Value()) {}
175 
176  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
177  /// shear modulus and Lamé's first modulus.
181 
182  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
183  /// shear modulus and P-wave modulus.
185  const PWaveModulus<NumericType>& p_wave_modulus)
188  p_wave_modulus.Value() - static_cast<NumericType>(2) * shear_modulus.Value()) {}
189 
190  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
191  /// isentropic bulk modulus and Lamé's first modulus.
192  constexpr ElasticIsotropicSolid(const IsentropicBulkModulus<NumericType>& isentropic_bulk_modulus,
194  : ConstitutiveModel(),
195  shear_modulus(static_cast<NumericType>(1.5)
196  * (isentropic_bulk_modulus.Value() - lame_first_modulus.Value())),
198 
199  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
200  /// isothermal bulk modulus and Lamé's first modulus.
201  constexpr ElasticIsotropicSolid(const IsothermalBulkModulus<NumericType>& isothermal_bulk_modulus,
203  : ConstitutiveModel(),
204  shear_modulus(static_cast<NumericType>(1.5)
205  * (isothermal_bulk_modulus.Value() - lame_first_modulus.Value())),
207 
208  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
209  /// isentropic bulk modulus and P-wave modulus.
210  constexpr ElasticIsotropicSolid(const IsentropicBulkModulus<NumericType>& isentropic_bulk_modulus,
211  const PWaveModulus<NumericType>& p_wave_modulus)
212  : ConstitutiveModel(),
213  shear_modulus(static_cast<NumericType>(0.75)
214  * (p_wave_modulus.Value() - isentropic_bulk_modulus.Value())),
215  lame_first_modulus(static_cast<NumericType>(1.5) * isentropic_bulk_modulus.Value()
216  - static_cast<NumericType>(0.5) * p_wave_modulus.Value()) {}
217 
218  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
219  /// isothermal bulk modulus and P-wave modulus.
220  constexpr ElasticIsotropicSolid(const IsothermalBulkModulus<NumericType>& isothermal_bulk_modulus,
221  const PWaveModulus<NumericType>& p_wave_modulus)
222  : ConstitutiveModel(),
223  shear_modulus(static_cast<NumericType>(0.75)
224  * (p_wave_modulus.Value() - isothermal_bulk_modulus.Value())),
225  lame_first_modulus(static_cast<NumericType>(1.5) * isothermal_bulk_modulus.Value()
226  - static_cast<NumericType>(0.5) * p_wave_modulus.Value()) {}
227 
228  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
229  /// isentropic bulk modulus and Poisson's ratio.
230  constexpr ElasticIsotropicSolid(const IsentropicBulkModulus<NumericType>& isentropic_bulk_modulus,
231  const PoissonRatio<NumericType>& poisson_ratio)
232  : ConstitutiveModel(),
234  static_cast<NumericType>(3) * isentropic_bulk_modulus.Value()
235  * (static_cast<NumericType>(1) - static_cast<NumericType>(2) * poisson_ratio.Value())
236  / (static_cast<NumericType>(2) + static_cast<NumericType>(2) * poisson_ratio.Value())),
238  static_cast<NumericType>(3) * isentropic_bulk_modulus.Value() * poisson_ratio.Value()
239  / (static_cast<NumericType>(1) + poisson_ratio.Value())) {}
240 
241  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
242  /// isothermal bulk modulus and Poisson's ratio.
243  constexpr ElasticIsotropicSolid(const IsothermalBulkModulus<NumericType>& isothermal_bulk_modulus,
244  const PoissonRatio<NumericType>& poisson_ratio)
245  : ConstitutiveModel(),
247  static_cast<NumericType>(3) * isothermal_bulk_modulus.Value()
248  * (static_cast<NumericType>(1) - static_cast<NumericType>(2) * poisson_ratio.Value())
249  / (static_cast<NumericType>(2) + static_cast<NumericType>(2) * poisson_ratio.Value())),
251  static_cast<NumericType>(3) * isothermal_bulk_modulus.Value() * poisson_ratio.Value()
252  / (static_cast<NumericType>(1) + poisson_ratio.Value())) {}
253 
254  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
255  /// Lamé's first modulus and P-wave modulus.
257  const PWaveModulus<NumericType>& p_wave_modulus)
258  : ConstitutiveModel(),
260  static_cast<NumericType>(0.5) * (p_wave_modulus.Value() - lame_first_modulus.Value())),
262 
263  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
264  /// Lamé's first modulus and Poisson's ratio.
266  const PoissonRatio<NumericType>& poisson_ratio)
267  : ConstitutiveModel(),
269  lame_first_modulus.Value()
270  * (static_cast<NumericType>(1) - static_cast<NumericType>(2) * poisson_ratio.Value())
271  / (static_cast<NumericType>(2) * poisson_ratio.Value())),
273 
274  /// \brief Constructor. Constructs an elastic isotropic solid constitutive model from a given
275  /// P-wave modulus and Poisson's ratio.
276  constexpr ElasticIsotropicSolid(const PWaveModulus<NumericType>& p_wave_modulus,
277  const PoissonRatio<NumericType>& poisson_ratio)
278  : ConstitutiveModel(),
280  p_wave_modulus.Value()
281  * (static_cast<NumericType>(1) - static_cast<NumericType>(2) * poisson_ratio.Value())
282  / (static_cast<NumericType>(2) - static_cast<NumericType>(2) * poisson_ratio.Value())),
283  lame_first_modulus(p_wave_modulus.Value() * poisson_ratio.Value()
284  / (static_cast<NumericType>(1) - poisson_ratio.Value())) {}
285 
286  /// \brief Destructor. Destroys this elastic isotropic solid constitutive model.
287  ~ElasticIsotropicSolid() noexcept override = default;
288 
289  /// \brief Copy constructor. Constructs an elastic isotropic solid constitutive model by copying
290  /// another one.
291  constexpr ElasticIsotropicSolid(const ElasticIsotropicSolid& other) = default;
292 
293  /// \brief Move constructor. Constructs an elastic isotropic solid constitutive model by moving
294  /// another one.
295  constexpr ElasticIsotropicSolid(ElasticIsotropicSolid&& other) noexcept = default;
296 
297  /// \brief Copy assignment operator. Assigns this elastic isotropic solid constitutive model by
298  /// copying another one.
299  ElasticIsotropicSolid& operator=(const ElasticIsotropicSolid& other) = default;
300 
301  /// \brief Move assignment operator. Assigns this elastic isotropic solid constitutive model by
302  /// moving another one.
303  ElasticIsotropicSolid& operator=(ElasticIsotropicSolid&& other) noexcept = default;
304 
305  /// \brief Shear modulus of this elastic isotropic solid constitutive model.
306  [[nodiscard]] inline constexpr const PhQ::ShearModulus<NumericType>&
307  ShearModulus() const noexcept {
308  return shear_modulus;
309  }
310 
311  /// \brief Lamé's first modulus of this elastic isotropic solid constitutive model.
312  [[nodiscard]] inline constexpr const PhQ::LameFirstModulus<NumericType>&
313  LameFirstModulus() const noexcept {
314  return lame_first_modulus;
315  }
316 
317  /// \brief Young's modulus of this elastic isotropic solid constitutive model.
318  [[nodiscard]] inline PhQ::YoungModulus<NumericType> YoungModulus() const {
319  const NumericType numerator{shear_modulus.Value()
320  * (static_cast<NumericType>(3) * lame_first_modulus.Value()
321  + static_cast<NumericType>(2) * shear_modulus.Value())};
322  const NumericType denominator{shear_modulus.Value() + lame_first_modulus.Value()};
323  return PhQ::YoungModulus<NumericType>{numerator / denominator, Standard<Unit::Pressure>};
324  }
325 
326  /// \brief Isentropic bulk modulus of this elastic isotropic solid constitutive model.
329  lame_first_modulus.Value()
330  + static_cast<NumericType>(2) / static_cast<NumericType>(3) * shear_modulus.Value(),
331  Standard<Unit::Pressure>};
332  }
333 
334  /// \brief Isothermal bulk modulus of this elastic isotropic solid constitutive model.
337  lame_first_modulus.Value()
338  + static_cast<NumericType>(2) / static_cast<NumericType>(3) * shear_modulus.Value(),
339  Standard<Unit::Pressure>};
340  }
341 
342  /// \brief P-wave modulus of this elastic isotropic solid constitutive model.
343  [[nodiscard]] inline PhQ::PWaveModulus<NumericType> PWaveModulus() const {
345  lame_first_modulus.Value() + static_cast<NumericType>(2) * shear_modulus.Value(),
346  Standard<Unit::Pressure>};
347  }
348 
349  /// \brief Poisson's ratio of this elastic isotropic solid constitutive model.
350  [[nodiscard]] inline PhQ::PoissonRatio<NumericType> PoissonRatio() const {
351  const NumericType numerator{static_cast<NumericType>(0.5) * lame_first_modulus.Value()};
352  const NumericType denominator{shear_modulus.Value() + lame_first_modulus.Value()};
353  return PhQ::PoissonRatio<NumericType>{numerator / denominator};
354  }
355 
356  /// \brief Returns this constitutive model's type.
357  [[nodiscard]] inline ConstitutiveModel::Type GetType() const noexcept override {
359  }
360 
361  /// \brief Returns the stress resulting from a given strain and strain rate. Since this is an
362  /// elastic isotropic solid constitutive model, the strain rate does not contribute to the stress
363  /// and is ignored.
364  [[nodiscard]] inline PhQ::Stress<float> Stress(
365  const PhQ::Strain<float>& strain,
366  const PhQ::StrainRate<float>& /*strain_rate*/) const override {
367  return this->Stress(strain);
368  }
369 
370  /// \brief Returns the stress resulting from a given strain and strain rate. Since this is an
371  /// elastic isotropic solid constitutive model, the strain rate does not contribute to the stress
372  /// and is ignored.
373  [[nodiscard]] inline PhQ::Stress<double> Stress(
374  const PhQ::Strain<double>& strain,
375  const PhQ::StrainRate<double>& /*strain_rate*/) const override {
376  return this->Stress(strain);
377  }
378 
379  /// \brief Returns the stress resulting from a given strain and strain rate. Since this is an
380  /// elastic isotropic solid constitutive model, the strain rate does not contribute to the stress
381  /// and is ignored.
382  [[nodiscard]] inline PhQ::Stress<long double> Stress(
383  const PhQ::Strain<long double>& strain,
384  const PhQ::StrainRate<long double>& /*strain_rate*/) const override {
385  return this->Stress(strain);
386  }
387 
388  /// \brief Returns the stress resulting from a given strain.
389  [[nodiscard]] inline PhQ::Stress<float> Stress(const PhQ::Strain<float>& strain) const override {
390  // stress = a * strain + b * trace(strain) * identity_matrix
391  // a = 2 * shear_modulus
392  // b = lame_first_modulus
393  const float temporary{static_cast<float>(lame_first_modulus.Value())
394  * static_cast<float>(strain.Value().Trace())};
395  return {
396  static_cast<float>(2) * static_cast<float>(shear_modulus.Value())
397  * static_cast<SymmetricDyad<float>>(strain.Value())
398  + SymmetricDyad<float>{temporary, static_cast<float>(0), static_cast<float>(0),
399  temporary, static_cast<float>(0), temporary},
400  Standard<Unit::Pressure>
401  };
402  }
403 
404  /// \brief Returns the stress resulting from a given strain.
405  [[nodiscard]] inline PhQ::Stress<double> Stress(
406  const PhQ::Strain<double>& strain) const override {
407  // stress = a * strain + b * trace(strain) * identity_matrix
408  // a = 2 * shear_modulus
409  // b = lame_first_modulus
410  const double temporary{static_cast<double>(lame_first_modulus.Value())
411  * static_cast<double>(strain.Value().Trace())};
412  return {
413  static_cast<double>(2) * static_cast<double>(shear_modulus.Value())
414  * static_cast<SymmetricDyad<double>>(strain.Value())
415  + SymmetricDyad<double>{temporary, static_cast<double>(0), static_cast<double>(0),
416  temporary, static_cast<double>(0), temporary},
417  Standard<Unit::Pressure>
418  };
419  }
420 
421  /// \brief Returns the stress resulting from a given strain.
422  [[nodiscard]] inline PhQ::Stress<long double> Stress(
423  const PhQ::Strain<long double>& strain) const override {
424  // stress = a * strain + b * trace(strain) * identity_matrix
425  // a = 2 * shear_modulus
426  // b = lame_first_modulus
427  const long double temporary{static_cast<long double>(lame_first_modulus.Value())
428  * static_cast<long double>(strain.Value().Trace())};
429  return {
430  static_cast<long double>(2) * static_cast<long double>(shear_modulus.Value())
431  * static_cast<SymmetricDyad<long double>>(strain.Value())
432  + SymmetricDyad<long double>{temporary, static_cast<long double>(0),
433  static_cast<long double>(0), temporary,
434  static_cast<long double>(0), temporary},
435  Standard<Unit::Pressure>
436  };
437  }
438 
439  /// \brief Returns the stress resulting from a given strain rate. Since this is an elastic
440  /// isotropic solid constitutive model, the strain rate does not contribute to the stress, so this
441  /// always returns a stress of zero.
442  [[nodiscard]] inline PhQ::Stress<float> Stress(
443  const PhQ::StrainRate<float>& /*strain_rate*/) const override {
444  return PhQ::Stress<float>::Zero();
445  }
446 
447  /// \brief Returns the stress resulting from a given strain rate. Since this is an elastic
448  /// isotropic solid constitutive model, the strain rate does not contribute to the stress, so this
449  /// always returns a stress of zero.
450  [[nodiscard]] inline PhQ::Stress<double> Stress(
451  const PhQ::StrainRate<double>& /*strain_rate*/) const override {
452  return PhQ::Stress<double>::Zero();
453  }
454 
455  /// \brief Returns the stress resulting from a given strain rate. Since this is an elastic
456  /// isotropic solid constitutive model, the strain rate does not contribute to the stress, so this
457  /// always returns a stress of zero.
458  [[nodiscard]] inline PhQ::Stress<long double> Stress(
459  const PhQ::StrainRate<long double>& /*strain_rate*/) const override {
461  }
462 
463  /// \brief Returns the strain resulting from a given stress.
464  [[nodiscard]] inline PhQ::Strain<float> Strain(const PhQ::Stress<float>& stress) const override {
465  // strain = a * stress + b * trace(stress) * identity_matrix
466  // a = 1 / (2 * shear_modulus)
467  // b = -1 * lame_first_modulus / (2 * shear_modulus * (2 * shear_modulus + 3
468  // * lame_first_modulus))
469  const float a{static_cast<float>(1)
470  / (static_cast<float>(2) * static_cast<float>(shear_modulus.Value()))};
471  const float b{-static_cast<float>(lame_first_modulus.Value())
472  / (static_cast<float>(2) * static_cast<float>(shear_modulus.Value())
473  * (static_cast<float>(2) * static_cast<float>(shear_modulus.Value())
474  + static_cast<float>(3) * static_cast<float>(lame_first_modulus.Value())))};
475  const float c{b * static_cast<float>(stress.Value().Trace())};
476  return PhQ::Strain<float>{
477  a * static_cast<SymmetricDyad<float>>(stress.Value())
479  c, static_cast<float>(0), static_cast<float>(0), c, static_cast<float>(0), c}
480  };
481  }
482 
483  /// \brief Returns the strain resulting from a given stress.
484  [[nodiscard]] inline PhQ::Strain<double> Strain(
485  const PhQ::Stress<double>& stress) const override {
486  // strain = a * stress + b * trace(stress) * identity_matrix
487  // a = 1 / (2 * shear_modulus)
488  // b = -1 * lame_first_modulus / (2 * shear_modulus * (2 * shear_modulus + 3
489  // * lame_first_modulus))
490  const double a{static_cast<double>(1)
491  / (static_cast<double>(2) * static_cast<double>(shear_modulus.Value()))};
492  const double b{
493  -static_cast<double>(lame_first_modulus.Value())
494  / (static_cast<double>(2) * static_cast<double>(shear_modulus.Value())
495  * (static_cast<double>(2) * static_cast<double>(shear_modulus.Value())
496  + static_cast<double>(3) * static_cast<double>(lame_first_modulus.Value())))};
497  const double c{b * static_cast<double>(stress.Value().Trace())};
498  return PhQ::Strain<double>{
499  a * static_cast<SymmetricDyad<double>>(stress.Value())
501  c, static_cast<double>(0), static_cast<double>(0), c, static_cast<double>(0), c}
502  };
503  }
504 
505  /// \brief Returns the strain resulting from a given stress.
506  [[nodiscard]] inline PhQ::Strain<long double> Strain(
507  const PhQ::Stress<long double>& stress) const override {
508  // strain = a * stress + b * trace(stress) * identity_matrix
509  // a = 1 / (2 * shear_modulus)
510  // b = -1 * lame_first_modulus / (2 * shear_modulus * (2 * shear_modulus + 3
511  // * lame_first_modulus))
512  const long double a{
513  static_cast<long double>(1)
514  / (static_cast<long double>(2) * static_cast<long double>(shear_modulus.Value()))};
515  const long double b{
516  -static_cast<long double>(lame_first_modulus.Value())
517  / (static_cast<long double>(2) * static_cast<long double>(shear_modulus.Value())
518  * (static_cast<long double>(2) * static_cast<long double>(shear_modulus.Value())
519  + static_cast<long double>(3)
520  * static_cast<long double>(lame_first_modulus.Value())))};
521  const long double c{b * static_cast<long double>(stress.Value().Trace())};
523  a * static_cast<SymmetricDyad<long double>>(stress.Value())
524  + SymmetricDyad<long double>{c, static_cast<long double>(0), static_cast<long double>(0), c,
525  static_cast<long double>(0), c}
526  };
527  }
528 
529  /// \brief Returns the strain rate resulting from a given stress. Since this is an elastic
530  /// isotropic solid constitutive model, stress does not depend on strain rate, so this always
531  /// returns a strain rate of zero.
532  [[nodiscard]] inline PhQ::StrainRate<float> StrainRate(
533  const PhQ::Stress<float>& /*stress*/) const override {
535  }
536 
537  /// \brief Returns the strain rate resulting from a given stress. Since this is an elastic
538  /// isotropic solid constitutive model, stress does not depend on strain rate, so this always
539  /// returns a strain rate of zero.
540  [[nodiscard]] inline PhQ::StrainRate<double> StrainRate(
541  const PhQ::Stress<double>& /*stress*/) const override {
543  }
544 
545  /// \brief Returns the strain rate resulting from a given stress. Since this is an elastic
546  /// isotropic solid constitutive model, stress does not depend on strain rate, so this always
547  /// returns a strain rate of zero.
549  const PhQ::Stress<long double>& /*stress*/) const override {
551  }
552 
553  /// \brief Prints this elastic isotropic solid constitutive model as a string.
554  [[nodiscard]] inline std::string Print() const override {
555  return {"Type = " + std::string{Abbreviation(this->GetType())} + ", Shear Modulus = "
556  + shear_modulus.Print() + ", Lamé's First Modulus = " + lame_first_modulus.Print()};
557  }
558 
559  /// \brief Serializes this elastic isotropic solid constitutive model as a JSON message.
560  [[nodiscard]] inline std::string JSON() const override {
561  return {R"({"type":")" + SnakeCase(Abbreviation(this->GetType())) + R"(","shear_modulus":)"
562  + shear_modulus.JSON() + ",\"lame_first_modulus\":" + lame_first_modulus.JSON() + "}"};
563  }
564 
565  /// \brief Serializes this elastic isotropic solid constitutive model as an XML message.
566  [[nodiscard]] inline std::string XML() const override {
567  return {"<type>" + SnakeCase(Abbreviation(this->GetType())) + "</type><shear_modulus>"
568  + shear_modulus.XML() + "</shear_modulus><lame_first_modulus>"
569  + lame_first_modulus.XML() + "</lame_first_modulus>"};
570  }
571 
572  /// \brief Serializes this elastic isotropic solid constitutive model as a YAML message.
573  [[nodiscard]] inline std::string YAML() const override {
574  return {"{type:\"" + SnakeCase(Abbreviation(this->GetType())) + "\",shear_modulus:"
575  + shear_modulus.YAML() + ",lame_first_modulus:" + lame_first_modulus.YAML() + "}"};
576  }
577 
578 private:
579  /// \brief Shear modulus of this elastic isotropic solid constitutive model.
581 
582  /// \brief Lamé's first modulus of this elastic isotropic solid constitutive model.
584 };
585 
586 template <typename NumericType>
587 inline constexpr bool operator==(
589  const typename ConstitutiveModel::ElasticIsotropicSolid<NumericType>& right) noexcept {
590  return left.ShearModulus() == right.ShearModulus()
591  && left.LameFirstModulus() == right.LameFirstModulus();
592 }
593 
594 template <typename NumericType>
595 inline constexpr bool operator!=(
597  const typename ConstitutiveModel::ElasticIsotropicSolid<NumericType>& right) noexcept {
598  return left.ShearModulus() != right.ShearModulus()
599  || left.LameFirstModulus() != right.LameFirstModulus();
600 }
601 
602 template <typename NumericType>
603 inline constexpr bool operator<(
605  const typename ConstitutiveModel::ElasticIsotropicSolid<NumericType>& right) noexcept {
606  if (left.ShearModulus() != right.ShearModulus()) {
607  return left.ShearModulus() < right.ShearModulus();
608  }
609  return left.LameFirstModulus() < right.LameFirstModulus();
610 }
611 
612 template <typename NumericType>
613 inline constexpr bool operator>(
615  const typename ConstitutiveModel::ElasticIsotropicSolid<NumericType>& right) noexcept {
616  if (left.ShearModulus() != right.ShearModulus()) {
617  return left.ShearModulus() > right.ShearModulus();
618  }
619  return left.LameFirstModulus() > right.LameFirstModulus();
620 }
621 
622 template <typename NumericType>
623 inline constexpr bool operator<=(
625  const typename ConstitutiveModel::ElasticIsotropicSolid<NumericType>& right) noexcept {
626  return !(left > right);
627 }
628 
629 template <typename NumericType>
630 inline constexpr bool operator>=(
632  const typename ConstitutiveModel::ElasticIsotropicSolid<NumericType>& right) noexcept {
633  return !(left < right);
634 }
635 
636 template <typename NumericType>
637 inline std::ostream& operator<<(
638  std::ostream& stream,
640  stream << model.Print();
641  return stream;
642 }
643 
644 } // namespace PhQ
645 
646 namespace std {
647 
648 template <typename NumericType>
649 struct hash<typename PhQ::ConstitutiveModel::ElasticIsotropicSolid<NumericType>> {
650  size_t operator()(
652  size_t result{17};
653  result = static_cast<size_t>(31) * result
654  + hash<PhQ::ShearModulus<NumericType>>()(model.ShearModulus());
655  result = static_cast<size_t>(31) * result
657  return result;
658  }
659 };
660 
661 } // namespace std
662 
663 #endif // PHQ_CONSTITUTIVE_MODEL_ELASTIC_ISOTROPIC_SOLID_HPP
Constitutive model for an elastic isotropic solid. This is the simplest constitutive model for a defo...
constexpr ElasticIsotropicSolid(const PWaveModulus< NumericType > &p_wave_modulus, const PoissonRatio< NumericType > &poisson_ratio)
Constructor. Constructs an elastic isotropic solid constitutive model from a given P-wave modulus and...
PhQ::ShearModulus< NumericType > shear_modulus
Shear modulus of this elastic isotropic solid constitutive model.
constexpr ElasticIsotropicSolid(const IsentropicBulkModulus< NumericType > &isentropic_bulk_modulus, const PoissonRatio< NumericType > &poisson_ratio)
Constructor. Constructs an elastic isotropic solid constitutive model from a given isentropic bulk mo...
constexpr ElasticIsotropicSolid(const LameFirstModulus< NumericType > &lame_first_modulus, const PWaveModulus< NumericType > &p_wave_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Lamé's first modul...
ElasticIsotropicSolid(const YoungModulus< NumericType > &young_modulus, const PoissonRatio< NumericType > &poisson_ratio)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Young's modulus an...
constexpr ElasticIsotropicSolid(const IsothermalBulkModulus< NumericType > &isothermal_bulk_modulus, const LameFirstModulus< NumericType > &lame_first_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given isothermal bulk mo...
PhQ::Stress< float > Stress(const PhQ::Strain< float > &strain) const override
Returns the stress resulting from a given strain.
PhQ::Stress< long double > Stress(const PhQ::StrainRate< long double > &) const override
Returns the stress resulting from a given strain rate. Since this is an elastic isotropic solid const...
constexpr ElasticIsotropicSolid(const YoungModulus< NumericType > &young_modulus, const LameFirstModulus< NumericType > &lame_first_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Young's modulus an...
constexpr const PhQ::LameFirstModulus< NumericType > & LameFirstModulus() const noexcept
Lamé's first modulus of this elastic isotropic solid constitutive model.
PhQ::PoissonRatio< NumericType > PoissonRatio() const
Poisson's ratio of this elastic isotropic solid constitutive model.
constexpr ElasticIsotropicSolid(const IsentropicBulkModulus< NumericType > &isentropic_bulk_modulus, const PWaveModulus< NumericType > &p_wave_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given isentropic bulk mo...
constexpr ElasticIsotropicSolid(const ShearModulus< NumericType > &shear_modulus, const IsentropicBulkModulus< NumericType > &isentropic_bulk_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given shear modulus and ...
ElasticIsotropicSolid()
Default constructor. Constructs an elastic isotropic solid constitutive model with an uninitialized v...
ElasticIsotropicSolid(const YoungModulus< NumericType > &young_modulus, const IsentropicBulkModulus< NumericType > &isentropic_bulk_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Young's modulus an...
constexpr ElasticIsotropicSolid(const YoungModulus< NumericType > &young_modulus, const PWaveModulus< NumericType > &p_wave_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Young's modulus an...
constexpr ElasticIsotropicSolid(const IsothermalBulkModulus< NumericType > &isothermal_bulk_modulus, const PoissonRatio< NumericType > &poisson_ratio)
Constructor. Constructs an elastic isotropic solid constitutive model from a given isothermal bulk mo...
constexpr ElasticIsotropicSolid(const ShearModulus< NumericType > &shear_modulus, const IsothermalBulkModulus< NumericType > &isothermal_bulk_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given shear modulus and ...
PhQ::Stress< double > Stress(const PhQ::StrainRate< double > &) const override
Returns the stress resulting from a given strain rate. Since this is an elastic isotropic solid const...
constexpr ElasticIsotropicSolid(const IsothermalBulkModulus< NumericType > &isothermal_bulk_modulus, const PWaveModulus< NumericType > &p_wave_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given isothermal bulk mo...
std::string JSON() const override
Serializes this elastic isotropic solid constitutive model as a JSON message.
PhQ::PWaveModulus< NumericType > PWaveModulus() const
P-wave modulus of this elastic isotropic solid constitutive model.
std::string XML() const override
Serializes this elastic isotropic solid constitutive model as an XML message.
PhQ::Stress< float > Stress(const PhQ::Strain< float > &strain, const PhQ::StrainRate< float > &) const override
Returns the stress resulting from a given strain and strain rate. Since this is an elastic isotropic ...
PhQ::IsentropicBulkModulus< NumericType > IsentropicBulkModulus() const
Isentropic bulk modulus of this elastic isotropic solid constitutive model.
PhQ::StrainRate< float > StrainRate(const PhQ::Stress< float > &) const override
Returns the strain rate resulting from a given stress. Since this is an elastic isotropic solid const...
constexpr ElasticIsotropicSolid(const ShearModulus< NumericType > &shear_modulus, const PoissonRatio< NumericType > &poisson_ratio)
Constructor. Constructs an elastic isotropic solid constitutive model from a given shear modulus and ...
constexpr ElasticIsotropicSolid(const ShearModulus< NumericType > &shear_modulus, const PWaveModulus< NumericType > &p_wave_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given shear modulus and ...
~ElasticIsotropicSolid() noexcept override=default
Destructor. Destroys this elastic isotropic solid constitutive model.
ConstitutiveModel::Type GetType() const noexcept override
Returns this constitutive model's type.
std::string Print() const override
Prints this elastic isotropic solid constitutive model as a string.
ElasticIsotropicSolid(const YoungModulus< NumericType > &young_modulus, const IsothermalBulkModulus< NumericType > &isothermal_bulk_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Young's modulus an...
constexpr ElasticIsotropicSolid(const IsentropicBulkModulus< NumericType > &isentropic_bulk_modulus, const LameFirstModulus< NumericType > &lame_first_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given isentropic bulk mo...
PhQ::Strain< float > Strain(const PhQ::Stress< float > &stress) const override
Returns the strain resulting from a given stress.
PhQ::Stress< double > Stress(const PhQ::Strain< double > &strain, const PhQ::StrainRate< double > &) const override
Returns the stress resulting from a given strain and strain rate. Since this is an elastic isotropic ...
PhQ::StrainRate< long double > StrainRate(const PhQ::Stress< long double > &) const override
Returns the strain rate resulting from a given stress. Since this is an elastic isotropic solid const...
constexpr ElasticIsotropicSolid(const YoungModulus< NumericType > &young_modulus, const ShearModulus< NumericType > &shear_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Young's modulus an...
std::string YAML() const override
Serializes this elastic isotropic solid constitutive model as a YAML message.
constexpr ElasticIsotropicSolid(const LameFirstModulus< NumericType > &lame_first_modulus, const PoissonRatio< NumericType > &poisson_ratio)
Constructor. Constructs an elastic isotropic solid constitutive model from a given Lamé's first modul...
PhQ::LameFirstModulus< NumericType > lame_first_modulus
Lamé's first modulus of this elastic isotropic solid constitutive model.
PhQ::Strain< long double > Strain(const PhQ::Stress< long double > &stress) const override
Returns the strain resulting from a given stress.
PhQ::StrainRate< double > StrainRate(const PhQ::Stress< double > &) const override
Returns the strain rate resulting from a given stress. Since this is an elastic isotropic solid const...
constexpr const PhQ::ShearModulus< NumericType > & ShearModulus() const noexcept
Shear modulus of this elastic isotropic solid constitutive model.
PhQ::Stress< double > Stress(const PhQ::Strain< double > &strain) const override
Returns the stress resulting from a given strain.
PhQ::Stress< long double > Stress(const PhQ::Strain< long double > &strain, const PhQ::StrainRate< long double > &) const override
Returns the stress resulting from a given strain and strain rate. Since this is an elastic isotropic ...
PhQ::Strain< double > Strain(const PhQ::Stress< double > &stress) const override
Returns the strain resulting from a given stress.
PhQ::IsothermalBulkModulus< NumericType > IsothermalBulkModulus() const
Isothermal bulk modulus of this elastic isotropic solid constitutive model.
PhQ::Stress< float > Stress(const PhQ::StrainRate< float > &) const override
Returns the stress resulting from a given strain rate. Since this is an elastic isotropic solid const...
PhQ::YoungModulus< NumericType > YoungModulus() const
Young's modulus of this elastic isotropic solid constitutive model.
PhQ::Stress< long double > Stress(const PhQ::Strain< long double > &strain) const override
Returns the stress resulting from a given strain.
constexpr ElasticIsotropicSolid(const ShearModulus< NumericType > &shear_modulus, const LameFirstModulus< NumericType > &lame_first_modulus)
Constructor. Constructs an elastic isotropic solid constitutive model from a given shear modulus and ...
Abstract base class for a material's constitutive model, which is a model that defines the relationsh...
Type
Type of a material's constitutive model.
@ ElasticIsotropicSolid
Elastic isotropic solid constitutive model.
constexpr const PhQ::SymmetricDyad< NumericType > & Value() const noexcept
Value of this physical quantity expressed in its standard unit of measure.
constexpr const PhQ::SymmetricDyad< NumericType > & Value() const noexcept
Value of this physical quantity.
Isentropic bulk modulus. Not to be confused with the isothermal bulk modulus; see PhQ::IsothermalBulk...
Isothermal bulk modulus of a material. Not to be confused with the isentropic bulk modulus; see PhQ::...
Lamé's first modulus of elasticity of a deformable solid material. First of the two Lamé parameters....
P-wave modulus of elasticity of a deformable solid material. A measure of a deformable solid material...
Poisson's ratio of a deformable solid material. Measures the deformation of a deformable solid materi...
Shear modulus of elasticity of a deformable solid material. A measure of a deformable solid material'...
Three-dimensional Euclidean strain rate symmetric dyadic tensor. Time rate of change of strain....
Definition: StrainRate.hpp:51
static constexpr StrainRate< NumericType > Zero()
Statically creates a strain rate tensor of zero.
Definition: StrainRate.hpp:111
Three-dimensional Euclidean strain symmetric dyadic tensor. Contains six components in Cartesian coor...
Definition: Strain.hpp:68
Three-dimensional Euclidean Cauchy stress symmetric dyadic tensor. Contains six components in Cartesi...
Definition: Stress.hpp:50
static constexpr Stress< NumericType > Zero()
Statically creates a stress tensor of zero.
Definition: Stress.hpp:105
Symmetric three-dimensional Euclidean dyadic tensor. Contains six components in Cartesian coordinates...
constexpr NumericType Trace() const noexcept
Returns the trace of this three-dimensional symmetric dyadic tensor.
Young's modulus of elasticity of a deformable solid material. A measure of a deformable solid materia...
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 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 SnakeCase(const std::string_view string)
Returns a copy of the given string in snake case: all characters are lowercase and all spaces are rep...
Definition: Base.hpp:263
std::string_view Abbreviation(const Enumeration enumeration)
Returns the abbreviation of a given enumeration value. For example, PhQ::Abbreviation(PhQ::Unit::Time...
Definition: Base.hpp:89
constexpr bool operator!=(const Acceleration< NumericType > &left, const Acceleration< NumericType > &right) noexcept
std::ostream & operator<<(std::ostream &stream, const Acceleration< NumericType > &acceleration)