Line data Source code
1 : //
2 : // This header defines the :code:`Model::Propellant::Propellant` class, which introduces a static
3 : // dispatch mechanism to replicate traditional dynamic polymorphism without incurring the performance
4 : // cost of virtual table lookups.
5 : //
6 : // The :code:`Propellant` class acts as the static equivalent of a pure abstract interface for
7 : // composite solid propellant models. Each function (e.g., :code:`get_K`, :code:`get_cp`,
8 : // :code:`get_L`) statically dispatches to the appropriate underlying implementation, encapsulating
9 : // key thermophysical properties such as density, thermal conductivity, and specific heat. The
10 : // :code:`set_pressure` and :code:`get_*` functions are resolved at compile-time for GPU
11 : // compatibility and runtime performance.
12 : //
13 : // This system enables polymorphic behavior without relying on runtime virtual functions, making it
14 : // suitable for high-performance computing environments.
15 : //
16 :
17 : #ifndef MODEL_PROPELLANT_H
18 : #define MODEL_PROPELLANT_H
19 :
20 : #include "AMReX_Extension.H"
21 : #include "IO/ParmParse.H"
22 :
23 : namespace Model
24 : {
25 : namespace Propellant
26 : {
27 : template<typename... OBJ>
28 : class Propellant
29 : {
30 : private:
31 : friend IO::ParmParse;
32 : std::tuple<OBJ...> obj;
33 : static constexpr const char* names[] = { OBJ::name... };
34 : int selected = -1;
35 :
36 : public:
37 :
38 : template<int I = 0>
39 : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
40 : void set_pressure (Set::Scalar P)
41 : {
42 : if constexpr (I < sizeof...(OBJ))
43 : {
44 13862 : if (selected == I) return std::get<I>(obj).set_pressure(P);
45 2550 : else return set_pressure<I+1>(P);
46 : }
47 0 : else Util::Abort(INFO,selected);
48 0 : }
49 :
50 : template<int I = 0>
51 : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
52 : Set::Scalar get_K (const Set::Scalar phi)
53 : {
54 : if constexpr (I < sizeof...(OBJ))
55 : {
56 118216448 : if (selected == I) return std::get<I>(obj).get_K(phi);
57 1747840 : else return get_K<I+1>(phi);
58 : }
59 0 : else Util::Abort(INFO,selected);
60 0 : return NAN;
61 : }
62 :
63 : template<int I = 0>
64 : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
65 : Set::Scalar get_rho (const Set::Scalar phi)
66 : {
67 : if constexpr (I < sizeof...(OBJ))
68 : {
69 118216448 : if (selected == I) return std::get<I>(obj).get_rho(phi);
70 1747840 : else return get_rho<I+1>(phi);
71 : }
72 0 : else Util::Abort(INFO,selected);
73 0 : return NAN;
74 : }
75 :
76 : template<int I = 0>
77 : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
78 : Set::Scalar get_cp (const Set::Scalar phi)
79 : {
80 : if constexpr (I < sizeof...(OBJ))
81 : {
82 118216448 : if (selected == I) return std::get<I>(obj).get_cp(phi);
83 1747840 : else return get_cp<I+1>(phi);
84 : }
85 0 : else Util::Abort(INFO,selected);
86 0 : return NAN;
87 : }
88 :
89 : template<int I = 0>
90 : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
91 : Set::Scalar get_qdot (const Set::Scalar mdot, const Set::Scalar phi)
92 : {
93 : if constexpr (I < sizeof...(OBJ))
94 : {
95 3495680 : if (selected == I) return std::get<I>(obj).get_qdot(mdot,phi);
96 1747840 : else return get_qdot<I+1>(mdot,phi);
97 : }
98 0 : else Util::Abort(INFO,selected);
99 0 : return NAN;
100 : }
101 :
102 : template<int I = 0>
103 : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE
104 : Set::Scalar get_L (const Set::Scalar phi, const Set::Scalar T)
105 : {
106 : if constexpr (I < sizeof...(OBJ))
107 : {
108 118216448 : if (selected == I) return std::get<I>(obj).get_L(phi,T);
109 1747840 : else return get_L<I+1>(phi, T);
110 : }
111 0 : else Util::Abort(INFO,selected);
112 0 : return NAN;
113 : }
114 : };
115 : }
116 : }
117 :
118 :
119 : #endif
120 :
121 :
|