include/meltpooldg/compressible_flow/equation_of_state.hpp Source File

Developer Documentation: include/meltpooldg/compressible_flow/equation_of_state.hpp Source File
Developer Documentation
equation_of_state.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <deal.II/base/config.h>
4
5#include <deal.II/base/exceptions.h>
6#include <deal.II/base/tensor.h>
7#include <deal.II/base/vectorization.h>
8
12
13#include <cmath>
14#include <utility>
15
17{
22 template <typename T>
23 concept EOSIsValueView = requires(const T v) {
24 {
25 v.density()
26 };
27 {
28 v.velocity()
29 };
30 {
31 v.total_energy()
32 };
33 };
34
39 template <typename T>
40 concept EOSIsGradientView = requires(const T g) {
41 {
42 g.grad_density()
43 };
44 {
45 g.grad_velocity()
46 };
47 {
48 g.grad_total_energy()
49 };
50 };
51
56 template <typename T>
57 concept IdealGasIsMaterialView = requires(const T m) {
58 {
59 m.heat_capacity_ratio()
60 };
61 {
62 m.specific_gas_constant()
63 };
64 };
65
70 template <typename T>
71 concept StiffenedGasIsMaterialView = requires(const T m) {
72 {
73 m.heat_capacity_ratio()
74 };
75 {
76 m.specific_isobaric_heat()
77 };
78 {
79 m.stiffening_pressure()
80 };
81 };
82
87 template <typename T>
88 concept NobleAbelStiffenedGasIsMaterialView = requires(const T m) {
89 {
90 m.heat_capacity_ratio()
91 };
92 {
93 m.specific_isobaric_heat()
94 };
95 {
96 m.stiffening_pressure()
97 };
98 {
99 m.heat_bound()
100 };
101 {
102 m.covolume()
103 };
104 };
105
107 {
116 template <EOSIsValueView ValueView, IdealGasIsMaterialView MaterialView>
117 static inline DEAL_II_ALWAYS_INLINE //
118 auto
119 thermodynamic_pressure(const ValueView &value_view, const MaterialView &material_view)
120 {
121 return (material_view.heat_capacity_ratio() - 1.) *
122 (value_view.total_energy() -
123 value_view.density() * 0.5 *
124 scalar_product(value_view.velocity(), value_view.velocity()));
125 }
126
137 template <EOSIsValueView ValueView,
138 EOSIsGradientView GradientView,
139 IdealGasIsMaterialView MaterialView>
140 static inline DEAL_II_ALWAYS_INLINE //
141 auto
142 grad_temperature(const ValueView &value_view,
143 const GradientView &gradient_view,
144 const MaterialView &material_view)
145 {
146 const auto grad_E =
147 1. / value_view.density() *
148 (gradient_view.grad_total_energy() -
149 1. / value_view.density() * value_view.total_energy() * gradient_view.grad_density());
150
151 return (material_view.heat_capacity_ratio() - 1.0) / material_view.specific_gas_constant() *
152 (grad_E - matrix_vector_product(gradient_view.grad_velocity(), value_view.velocity()));
153 }
154
164 template <EOSIsValueView ValueView, IdealGasIsMaterialView MaterialView>
165 static inline DEAL_II_ALWAYS_INLINE //
166 auto
167 speed_of_sound(const ValueView &value_view, const MaterialView &material_view)
168 {
169 return std::sqrt(material_view.heat_capacity_ratio() *
170 thermodynamic_pressure(value_view, material_view) / value_view.density());
171 }
172
181 template <EOSIsValueView ValueView, IdealGasIsMaterialView MaterialView>
182 static inline DEAL_II_ALWAYS_INLINE //
183 auto
184 temperature(const ValueView &value_view, const MaterialView &material_view)
185 {
186 return thermodynamic_pressure(value_view, material_view) /
187 (material_view.specific_gas_constant() * value_view.density());
188 }
189
199 template <typename ValueType, EOSIsValueView ValueView, IdealGasIsMaterialView MaterialView>
200 static inline DEAL_II_ALWAYS_INLINE //
201 auto
202 inner_energy_from_pressure(const ValueType &pressure,
203 const ValueView &,
204 const MaterialView &material_view)
205 {
206 return pressure / (material_view.heat_capacity_ratio() - 1.);
207 }
208
216 template <typename ValueView, IdealGasIsMaterialView MaterialView>
217 static inline DEAL_II_ALWAYS_INLINE //
218 auto
219 specific_inner_energy(const ValueView &value_view, const MaterialView &material_view)
220 {
221 return thermodynamic_pressure(value_view, material_view) /
222 (value_view.density() * (material_view.heat_capacity_ratio() - 1.));
223 }
224 };
225
227 {
236 template <EOSIsValueView ValueView, StiffenedGasIsMaterialView MaterialView>
237 static inline DEAL_II_ALWAYS_INLINE //
238 auto
239 thermodynamic_pressure(const ValueView &value_view, const MaterialView &material_view)
240 {
241 return (material_view.heat_capacity_ratio() - 1.) *
242 (value_view.total_energy() -
243 value_view.density() * 0.5 *
244 scalar_product(value_view.velocity(), value_view.velocity())) -
245 material_view.heat_capacity_ratio() * material_view.stiffening_pressure();
246 }
247
258 template <EOSIsValueView ValueView,
259 EOSIsGradientView GradientView,
260 StiffenedGasIsMaterialView MaterialView>
261 static inline DEAL_II_ALWAYS_INLINE //
262 auto
263 grad_temperature(const ValueView &value_view,
264 const GradientView &gradient_view,
265 const MaterialView &material_view)
266 {
267 const auto inv_rho = 1. / value_view.density();
268
269 const auto grad_E =
270 inv_rho * (gradient_view.grad_total_energy() -
271 inv_rho * value_view.total_energy() * gradient_view.grad_density());
272
273 return material_view.heat_capacity_ratio() / material_view.specific_isobaric_heat() *
274 (grad_E - matrix_vector_product(gradient_view.grad_velocity(), value_view.velocity()) +
275 material_view.stiffening_pressure() * inv_rho * inv_rho *
276 gradient_view.grad_density());
277 }
278
288 template <EOSIsValueView ValueView, StiffenedGasIsMaterialView MaterialView>
289 static inline DEAL_II_ALWAYS_INLINE //
290 auto
291 speed_of_sound(const ValueView &value_view, const MaterialView &material_view)
292 {
293 return std::sqrt(
294 material_view.heat_capacity_ratio() *
295 (thermodynamic_pressure(value_view, material_view) + material_view.stiffening_pressure()) /
296 value_view.density());
297 }
298
308 template <EOSIsValueView ValueView, StiffenedGasIsMaterialView MaterialView>
309 static inline DEAL_II_ALWAYS_INLINE //
310 auto
311 temperature(const ValueView &value_view, const MaterialView &material_view)
312 {
313 return (thermodynamic_pressure(value_view, material_view) +
314 material_view.stiffening_pressure()) *
315 material_view.heat_capacity_ratio() /
316 (material_view.specific_isobaric_heat() * value_view.density() *
317 (material_view.heat_capacity_ratio() - 1.));
318 }
319
329 template <typename ValueType, EOSIsValueView ValueView, StiffenedGasIsMaterialView MaterialView>
330 static inline DEAL_II_ALWAYS_INLINE //
331 auto
332 inner_energy_from_pressure(const ValueType &pressure,
333 const ValueView &,
334 const MaterialView &material_view)
335 {
336 return (pressure +
337 material_view.heat_capacity_ratio() * material_view.stiffening_pressure()) /
338 (material_view.heat_capacity_ratio() - 1.);
339 }
340
348 template <typename ValueView, StiffenedGasIsMaterialView MaterialView>
349 static inline DEAL_II_ALWAYS_INLINE //
350 auto
351 specific_inner_energy(const ValueView &value_view, const MaterialView &material_view)
352 {
353 return (thermodynamic_pressure(value_view, material_view) +
354 material_view.heat_capacity_ratio() * material_view.stiffening_pressure()) /
355 (value_view.density() * (material_view.heat_capacity_ratio() - 1.));
356 }
357 };
358
360 {
369 template <EOSIsValueView ValueView, NobleAbelStiffenedGasIsMaterialView MaterialView>
370 static inline DEAL_II_ALWAYS_INLINE //
371 auto
372 thermodynamic_pressure(const ValueView &value_view, const MaterialView &material_view)
373 {
374 return ((material_view.heat_capacity_ratio() - 1.) *
375 (value_view.total_energy() -
376 0.5 * value_view.density() *
377 scalar_product(value_view.velocity(), value_view.velocity()) -
378 value_view.density() * material_view.heat_bound()) -
379 material_view.heat_capacity_ratio() * material_view.stiffening_pressure() *
380 (1. - value_view.density() * material_view.covolume())) /
381 (1. - value_view.density() * material_view.covolume());
382 }
383
394 template <EOSIsValueView ValueView,
395 EOSIsGradientView GradientView,
397 static inline DEAL_II_ALWAYS_INLINE //
398 auto
399 grad_temperature(const ValueView &value_view,
400 const GradientView &gradient_view,
401 const MaterialView &material_view)
402 {
403 const auto inv_rho = 1. / value_view.density();
404
405 const auto grad_E =
406 inv_rho * (gradient_view.grad_total_energy() -
407 inv_rho * value_view.total_energy() * gradient_view.grad_density());
408
409 return material_view.heat_capacity_ratio() / material_view.specific_isobaric_heat() *
410 (grad_E - matrix_vector_product(gradient_view.grad_velocity(), value_view.velocity()) +
411 material_view.stiffening_pressure() * inv_rho * inv_rho *
412 gradient_view.grad_density());
413 }
414
424 template <EOSIsValueView ValueView, NobleAbelStiffenedGasIsMaterialView MaterialView>
425 static inline DEAL_II_ALWAYS_INLINE //
426 auto
427 speed_of_sound(const ValueView &value_view, const MaterialView &material_view)
428 {
429 return std::sqrt(
430 material_view.heat_capacity_ratio() *
431 (thermodynamic_pressure(value_view, material_view) + material_view.stiffening_pressure()) /
432 (value_view.density() * (1. - value_view.density() * material_view.covolume())));
433 }
434
444 template <EOSIsValueView ValueView, NobleAbelStiffenedGasIsMaterialView MaterialView>
445 static inline DEAL_II_ALWAYS_INLINE //
446 auto
447 temperature(const ValueView &value_view, const MaterialView &material_view)
448 {
449 return (thermodynamic_pressure(value_view, material_view) +
450 material_view.stiffening_pressure()) *
451 (1. / value_view.density() - material_view.covolume()) *
452 material_view.heat_capacity_ratio() / (material_view.heat_capacity_ratio() - 1.) *
453 material_view.specific_isobaric_heat();
454 }
455
466 template <typename ValueType,
467 EOSIsValueView ValueView,
469 static inline DEAL_II_ALWAYS_INLINE //
470 auto
471 inner_energy_from_pressure(const ValueType &pressure,
472 const ValueView &value_view,
473 const MaterialView &material_view)
474 {
475 return (pressure +
476 material_view.heat_capacity_ratio() * material_view.stiffening_pressure()) /
477 (material_view.heat_capacity_ratio() - 1.) *
478 (1. - value_view.density() * material_view.covolume()) +
479 value_view.density() * material_view.heat_bound();
480 }
481
489 template <typename ValueView, NobleAbelStiffenedGasIsMaterialView MaterialView>
490 static inline DEAL_II_ALWAYS_INLINE //
491 auto
492 specific_inner_energy(const ValueView &value_view, const MaterialView &material_view)
493 {
494 return (thermodynamic_pressure(value_view, material_view) +
495 material_view.heat_capacity_ratio() * material_view.stiffening_pressure()) /
496 (material_view.heat_capacity_ratio() - 1.) *
497 (1. / value_view.density() - material_view.covolume()) +
498 material_view.heat_bound();
499 }
500 };
501
505 template <typename T>
506 concept HasSupportedEOS = requires {
507 {
508 T::supported_eos
509 } -> std::convertible_to<const std::array<CompressibleFlow::EquationOfState,
510 std::tuple_size_v<decltype(T::supported_eos)>> &>;
511 };
512
521 template <typename Derived, CompressibleFlow::EquationOfState EOS>
522 constexpr bool
524 {
525 return std::ranges::find(Derived::supported_eos, EOS) != Derived::supported_eos.end();
526 }
527
545 template <typename Derived, typename F>
546 inline DEAL_II_ALWAYS_INLINE decltype(auto)
547 dispatch_eos(CompressibleFlow::EquationOfState eos_type, F &&f)
548 {
549 auto check_support = [](CompressibleFlow::EquationOfState type) {
550 if constexpr (HasSupportedEOS<Derived>)
551 {
552 if (type == CompressibleFlow::EquationOfState::ideal_gas)
553 return supports_eos<Derived, CompressibleFlow::EquationOfState::ideal_gas>();
554 if (type == CompressibleFlow::EquationOfState::stiffened_gas)
555 return supports_eos<Derived, CompressibleFlow::EquationOfState::stiffened_gas>();
556 if (type == CompressibleFlow::EquationOfState::noble_abel_stiffened_gas)
557 return supports_eos<Derived,
558 CompressibleFlow::EquationOfState::noble_abel_stiffened_gas>();
559 return false;
560 }
561 return true;
562 };
563
564 switch (eos_type)
565 {
566 case CompressibleFlow::EquationOfState::ideal_gas:
567 if constexpr (check_support(CompressibleFlow::EquationOfState::ideal_gas))
568 return std::forward<F>(f)(IdealGasEOS{});
569 break;
570
571 case CompressibleFlow::EquationOfState::stiffened_gas:
572 if constexpr (check_support(CompressibleFlow::EquationOfState::stiffened_gas))
573 return std::forward<F>(f)(StiffenedGasEOS{});
574 break;
575
576 case CompressibleFlow::EquationOfState::noble_abel_stiffened_gas:
577 if constexpr (check_support(CompressibleFlow::EquationOfState::noble_abel_stiffened_gas))
578 return std::forward<F>(f)(NobleAbelStiffenedGasEOS{});
579 break;
580
581 default:
582 break;
583 }
584
585 AssertThrow(false, dealii::ExcMessage("The provided EOS is not supported by this View."));
586 }
587
588
589
598 template <int dim, ArithmeticType ValueType, typename Derived>
600 {
601 decltype(auto)
602 pressure() const
603 {
604 return dispatch_eos<Derived>(eos_type(), [&](auto eos) -> decltype(auto) {
605 return eos.thermodynamic_pressure(derived(), derived());
606 });
607 }
608
609 decltype(auto)
611 {
612 return dispatch_eos<Derived>(eos_type(), [&](auto eos) -> decltype(auto) {
613 return eos.temperature(derived(), derived());
614 });
615 }
616
617 decltype(auto)
619 {
620 return dispatch_eos<Derived>(eos_type(), [&](auto eos) -> decltype(auto) {
621 return eos.speed_of_sound(derived(), derived());
622 });
623 }
624
625 decltype(auto)
626 inner_energy_from_pressure(const ValueType &pressure) const
627 {
628 return dispatch_eos<Derived>(eos_type(), [&](auto eos) -> decltype(auto) {
629 return eos.inner_energy_from_pressure(pressure, derived(), derived());
630 });
631 }
632
633 decltype(auto)
635 {
636 return dispatch_eos<Derived>(eos_type(), [&](auto eos) -> decltype(auto) {
637 return eos.specific_inner_energy(derived(), derived());
638 });
639 }
640
641 private:
642 decltype(auto)
643 eos_type() const
644 {
645 return static_cast<const Derived &>(*this).eos_type();
646 }
647
648 const Derived &
649 derived() const
650 {
651 return static_cast<const Derived &>(*this);
652 }
653 };
654
663 template <int dim, typename Derived>
665 {
666 decltype(auto)
668 {
669 return dispatch_eos<Derived>(eos_type(), [&](auto eos) -> decltype(auto) {
670 return eos.grad_temperature(derived(), derived(), derived());
671 });
672 }
673
674 private:
675 const Derived &
676 derived() const
677 {
678 return static_cast<const Derived &>(*this);
679 }
680
681 decltype(auto)
682 eos_type() const
683 {
684 return static_cast<const Derived &>(*this).eos_type();
685 }
686 };
687} // namespace MeltPoolDG::Flow
Definition equation_of_state.hpp:40
Definition equation_of_state.hpp:23
Concept ensuring a type defines a specific, compatible supported_eos array.
Definition equation_of_state.hpp:506
Definition equation_of_state.hpp:57
Definition equation_of_state.hpp:71
Definition equation_of_state.hpp:17
DEAL_II_ALWAYS_INLINE decltype(auto) dispatch_eos(CompressibleFlow::EquationOfState eos_type, F &&f)
Definition equation_of_state.hpp:547
constexpr bool supports_eos()
Dispatch helper function that checks at compile-time whether an equation of state is supported.
Definition equation_of_state.hpp:523
dealii::VectorizedArray< number, N > scalar_product(const dealii::VectorizedArray< number, N > &scalar, const dealii::Tensor< 1, 1, dealii::VectorizedArray< number, N > > &vec)
Definition dealii_tensor.hpp:60
dealii::Tensor< 1, n_rows, number > matrix_vector_product(const dealii::Tensor< 1, n_rows, dealii::Tensor< 1, n_columns, number > > &matrix, const dealii::Tensor< 1, n_columns, number > &vector)
Definition dealii_tensor.hpp:80
Definition equation_of_state.hpp:665
const Derived & derived() const
Definition equation_of_state.hpp:676
decltype(auto) grad_temperature() const
Definition equation_of_state.hpp:667
decltype(auto) eos_type() const
Definition equation_of_state.hpp:682
Definition equation_of_state.hpp:600
const Derived & derived() const
Definition equation_of_state.hpp:649
decltype(auto) speed_of_sound() const
Definition equation_of_state.hpp:618
decltype(auto) specific_inner_energy() const
Definition equation_of_state.hpp:634
decltype(auto) eos_type() const
Definition equation_of_state.hpp:643
decltype(auto) temperature() const
Definition equation_of_state.hpp:610
decltype(auto) pressure() const
Definition equation_of_state.hpp:602
decltype(auto) inner_energy_from_pressure(const ValueType &pressure) const
Definition equation_of_state.hpp:626
Definition equation_of_state.hpp:107
static DEAL_II_ALWAYS_INLINE auto inner_energy_from_pressure(const ValueType &pressure, const ValueView &, const MaterialView &material_view)
Definition equation_of_state.hpp:202
static DEAL_II_ALWAYS_INLINE auto grad_temperature(const ValueView &value_view, const GradientView &gradient_view, const MaterialView &material_view)
Definition equation_of_state.hpp:142
static DEAL_II_ALWAYS_INLINE auto temperature(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:184
static DEAL_II_ALWAYS_INLINE auto speed_of_sound(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:167
static DEAL_II_ALWAYS_INLINE auto thermodynamic_pressure(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:119
static DEAL_II_ALWAYS_INLINE auto specific_inner_energy(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:219
Definition equation_of_state.hpp:360
static DEAL_II_ALWAYS_INLINE auto temperature(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:447
static DEAL_II_ALWAYS_INLINE auto specific_inner_energy(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:492
static DEAL_II_ALWAYS_INLINE auto thermodynamic_pressure(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:372
static DEAL_II_ALWAYS_INLINE auto speed_of_sound(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:427
static DEAL_II_ALWAYS_INLINE auto grad_temperature(const ValueView &value_view, const GradientView &gradient_view, const MaterialView &material_view)
Definition equation_of_state.hpp:399
static DEAL_II_ALWAYS_INLINE auto inner_energy_from_pressure(const ValueType &pressure, const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:471
Definition equation_of_state.hpp:227
static DEAL_II_ALWAYS_INLINE auto specific_inner_energy(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:351
static DEAL_II_ALWAYS_INLINE auto inner_energy_from_pressure(const ValueType &pressure, const ValueView &, const MaterialView &material_view)
Definition equation_of_state.hpp:332
static DEAL_II_ALWAYS_INLINE auto temperature(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:311
static DEAL_II_ALWAYS_INLINE auto thermodynamic_pressure(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:239
static DEAL_II_ALWAYS_INLINE auto speed_of_sound(const ValueView &value_view, const MaterialView &material_view)
Definition equation_of_state.hpp:291
static DEAL_II_ALWAYS_INLINE auto grad_temperature(const ValueView &value_view, const GradientView &gradient_view, const MaterialView &material_view)
Definition equation_of_state.hpp:263