DNDSR 0.1.0.dev1+gcd065ad
Distributed Numeric Data Structure for CFV
Loading...
Searching...
No Matches
EulerP_Physics.hpp
Go to the documentation of this file.
1/**
2 * @file EulerP_Physics.hpp
3 * @brief Physics model definitions for the EulerP module: gas properties, state conversions,
4 * and inviscid flux computation.
5 *
6 * Provides:
7 * - `PhysicsParams:` POD struct of gas parameters (gamma, viscosity, specific heats), JSON-serializable.
8 * - `PhysicsDeviceView:` Device-callable view with conservative/primitive conversions and thermodynamic relations.
9 * - `Physics:` Host-side physics object managing device transfer of reference values.
10 * - `GasInviscidFlux_XY:` Device-callable inviscid flux projected onto a face normal.
11 *
12 * @note In EulerP, the primitive state stores @b internal @b energy (rho*e) at index I4,
13 * NOT pressure. This differs from the Euler module convention.
14 */
15#pragma once
16#include "DNDS/Defines.hpp"
18#include "DNDS/Errors.hpp"
20#include "EulerP.hpp"
21#include "DNDS/JsonUtil.hpp"
22#include <cmath>
23#include "Geom/Geometric.hpp"
24
25namespace DNDS::EulerP
26{
27
28 /**
29 * @brief POD struct holding gas physical properties for the ideal gas model.
30 *
31 * All members are simple scalar types suitable for device transfer.
32 * JSON-serializable via nlohmann_json intrusive macros.
33 */
35 {
36 //! only simple data here allowed
37 real gamma = 1.4; ///< Ratio of specific heats (Cp/Cv). Default: 1.4 for air.
38 real mu0 = 1e-100; ///< Dynamic viscosity coefficient. Default: effectively inviscid.
39 real cp = 1.; ///< Specific heat at constant pressure.
40 real cv = 1.; ///< Specific heat at constant volume.
41 real Rg = 1.; ///< Specific gas constant (Cp - Cv).
42 real TRef = 273.15; ///< Reference temperature [K] for viscosity models.
43
44 int muModel = 0; ///< Viscosity model selector (0 = constant viscosity).
47 gamma, mu0, cp, Rg, TRef,
48 muModel);
49 };
50
51 /**
52 * @brief Device-callable view of physics parameters providing thermodynamic operations.
53 *
54 * Wraps a device-resident view of reference values and a copy of `PhysicsParams.`
55 * All methods are `DNDS_DEVICE_CALLABLE` for use in both Host and CUDA kernels.
56 *
57 * @note Primitive state convention: prim[0] = rho, prim[1..3] = velocity, prim[I4] = internal energy (rho*e).
58 * This differs from the Euler module where prim[I4] stores pressure.
59 *
60 * @tparam B Device backend (Host or CUDA).
61 */
62 template <DeviceBackend B>
64 {
65 vector_DeviceView<B, real, int32_t> reference_values; ///< Device-resident reference values (e.g., freestream quantities).
66 PhysicsParams params; ///< Gas physical parameters (copied to device).
67
69
70 /**
71 * @brief Computes the total dynamic viscosity.
72 *
73 * Currently returns only the physical viscosity (no RANS turbulence model contribution).
74 *
75 * @tparam tUPrim Primitive state vector type (deduced).
76 * @tparam tDiffUPrim Primitive state gradient type (deduced).
77 * @param UPrim Primitive state vector (unused in current constant-viscosity model).
78 * @param DiffUPrim Primitive gradient (unused in current constant-viscosity model).
79 * @param nVars Total number of variables (flow + turbulence).
80 * @param p Pressure (unused in current model).
81 * @param T Temperature (unused in current model).
82 * @return Total dynamic viscosity mu_total = mu_physical.
83 */
84 template <class tUPrim, class tDiffUPrim>
86 tUPrim &&UPrim, tDiffUPrim &&DiffUPrim, int nVars,
87 real p, real T) const
88 {
89 // ! no rans model
90 real muPhy = params.mu0;
91 return muPhy;
92 }
93
94 /**
95 * @brief Converts conservative state to primitive state.
96 *
97 * Computes primitive variables from conservative variables:
98 * - prim[0] = rho (density, copied directly)
99 * - prim[1..3] = velocity components (U_i / rho)
100 * - prim[I4] = internal energy e = E - 0.5 * rho * v^2
101 * - prim[i >= nVarsFlow] = U_i / rho (specific turbulence quantities)
102 *
103 * @note prim[I4] stores internal energy (rho*e), NOT pressure.
104 *
105 * @tparam tUPrim Primitive state vector type (deduced).
106 * @tparam tU Conservative state vector type (deduced).
107 * @param U Input conservative state vector.
108 * @param[out] UPrim Output primitive state vector.
109 * @param nVars Total number of variables (flow + turbulence).
110 */
111 template <class tUPrim, class tU>
113 tU &&U, tUPrim &&UPrim, int nVars) const
114 {
115 real rho = U(0);
116 real vSqr = 0.0;
117#ifdef __CUDA_ARCH__
118# pragma unroll
119#endif
120 for (int i = 1; i < nVarsFlow - 1; i++)
121 UPrim(i) = U(i) / rho, vSqr += sqr(UPrim(i));
122 real E = U(I4);
123 real e = (E - rho * 0.5 * vSqr);
124 UPrim(0) = rho;
125 UPrim(I4) = e;
126 for (int i = nVarsFlow; i < nVars; i++)
127 UPrim(i) = U(i) / rho;
128 }
129
130 /**
131 * @brief Converts conservative variable gradients to primitive variable gradients.
132 *
133 * Given conservative state @p U, primitive state @p UPrim, and conservative gradient @p DiffU,
134 * computes the corresponding primitive gradient @p DiffUPrim using the chain rule:
135 * - nabla(v_i) = (nabla(rho*v_i) - nabla(rho) * v_i) / rho
136 * - nabla(e) = nabla(E) - 0.5 * nabla(rho) * v^2 - rho * dot(nabla(v), v)
137 *
138 * @tparam tU Conservative state type (deduced).
139 * @tparam tUPrim Primitive state type (deduced).
140 * @tparam tDiffU Conservative gradient type (deduced), 3 x nVars.
141 * @tparam tDiffUPrim Primitive gradient type (deduced), 3 x nVars.
142 * @param U Conservative state vector.
143 * @param UPrim Primitive state vector (must be pre-computed via Cons2Prim).
144 * @param DiffU Conservative variable spatial gradients (3 rows = x,y,z directions).
145 * @param[out] DiffUPrim Output primitive variable spatial gradients.
146 * @param nVars Total number of variables (flow + turbulence).
147 */
148 template <class tU, class tUPrim, class tDiffU, class tDiffUPrim>
150 tU &&U, tUPrim &&UPrim, tDiffU &&DiffU, tDiffUPrim &&DiffUPrim, int nVars) const
151 {
152
153 for (int d = 0; d < 3; d++)
154 DiffUPrim(d, 0) = DiffU(d, 0);
155 for (int i = 1; i < I4; i++)
156 for (int d = 0; d < 3; d++)
157 DiffUPrim(d, i) = (DiffU(d, i) - DiffUPrim(d, 0) * UPrim(i)) / UPrim(0);
158 real vSqr = 0.0;
159 real rho = UPrim(0);
160 for (int i = 1; i < nVarsFlow - 1; i++)
161 vSqr += sqr(UPrim(i));
162
163 // nabla(E - rho * 0.5 * dot(v,v)) =
164 // nabla(E) - 0.5 nabla(rho) * dot(v,v) -
165 // rho * dot(nabla(v), v)
166 for (int d = 0; d < 3; d++)
167 {
168 DiffUPrim(d, I4) = DiffU(d, I4) - 0.5 * DiffUPrim(d, 0) * vSqr;
169 for (int i = 1; i < nVarsFlow - 1; i++)
170 DiffUPrim(d, I4) -= rho * DiffUPrim(d, i) * UPrim(i);
171 }
172 for (int i = nVarsFlow; i < nVars; i++)
173 for (int d = 0; d < 3; d++)
174 DiffUPrim(d, i) = (DiffU(d, i) - DiffUPrim(d, 0) * UPrim(i)) / UPrim(0);
175 }
176
177 /**
178 * @brief Converts primitive state to conservative state.
179 *
180 * Inverse of Cons2Prim:
181 * - cons[0] = rho
182 * - cons[1..3] = rho * v_i
183 * - cons[I4] = E = e + 0.5 * rho * v^2 (total energy)
184 * - cons[i >= nVarsFlow] = rho * prim_i
185 *
186 * @tparam tUPrim Primitive state vector type (deduced).
187 * @tparam tU Conservative state vector type (deduced).
188 * @param UPrim Input primitive state vector.
189 * @param[out] U Output conservative state vector.
190 * @param nVars Total number of variables (flow + turbulence).
191 */
192 template <class tUPrim, class tU>
194 tUPrim &&UPrim, tU &&U, int nVars) const
195 {
196 real rho = UPrim(0);
197 real vSqr = 0.0;
198#ifdef __CUDA_ARCH__
199# pragma unroll
200#endif
201 for (int i = 1; i < nVarsFlow - 1; i++)
202 vSqr += sqr(UPrim(i)), U(i) = UPrim(i) * rho;
203 real e = UPrim(I4);
204 real E = (e + rho * 0.5 * vSqr);
205 U(0) = rho;
206 U(I4) = E;
207 for (int i = nVarsFlow; i < nVars; i++)
208 U(i) = UPrim(i) * rho;
209 }
210
211 /**
212 * @brief Extracts internal energy from a conservative state vector.
213 *
214 * Computes e = E - 0.5 * (rhoU^2 + rhoV^2 + rhoW^2) / rho.
215 *
216 * @tparam tU Conservative state vector type (deduced).
217 * @param U Conservative state vector.
218 * @param nVars Total number of variables (flow + turbulence).
219 * @return Internal energy e = rho * cv * T for an ideal gas.
220 */
221 template <class tU>
223 tU &&U, int nVars) const
224 {
225 real rho = U(0);
226 real rvSqr = 0.0;
227#ifdef __CUDA_ARCH__
228# pragma unroll
229#endif
230 for (int i = 1; i < nVarsFlow - 1; i++)
231 rvSqr += sqr(U(i));
232 rvSqr /= rho;
233 real E = U(I4);
234 real e = (E - 0.5 * rvSqr);
235 return e;
236 }
237
238 /**
239 * @brief Computes pressure from the primitive state using the ideal gas law.
240 *
241 * Delegates to `IdealGas::Pressure_From_InternalEnergy` using prim[I4] (internal energy)
242 * and the ratio of specific heats gamma.
243 *
244 * @tparam tUPrim Primitive state vector type (deduced).
245 * @param UPrim Primitive state vector (prim[I4] = internal energy).
246 * @param nVars Total number of variables.
247 * @param T Temperature (unused; pressure is computed from internal energy directly).
248 * @return Pressure p = (gamma - 1) * e.
249 */
250 template <class tUPrim>
252 tUPrim &&UPrim, int nVars, real T) const
253 {
254 //! perfect gas here — prim[I4] stores internal energy e
256 }
257
258 /**
259 * @brief Computes the ratio of specific heats and the acoustic speed of sound.
260 *
261 * @tparam tUPrim Primitive state vector type (deduced).
262 * @param UPrim Primitive state vector.
263 * @param nVars Total number of variables.
264 * @param p Pressure.
265 * @return A std::tuple of (gamma, speed_of_sound) where a = sqrt(gamma * p / rho).
266 */
267 template <class tUPrim>
269 tUPrim &&UPrim, int nVars, real p) const
270 {
271 return std::make_tuple(params.gamma,
272 std::sqrt(IdealGas::SpeedOfSoundSqr(params.gamma, p, UPrim(0))));
273 }
274
275 /**
276 * @brief Computes temperature from the primitive state.
277 *
278 * For a perfect gas: T = e / (rho * cp), where e = prim[I4] is internal energy.
279 *
280 * @tparam tUPrim Primitive state vector type (deduced).
281 * @param UPrim Primitive state vector.
282 * @param nVars Total number of variables.
283 * @return Temperature T.
284 */
285 template <class tUPrim>
287 tUPrim &&UPrim, int nVars) const
288 {
289 //! perfect gas here
290 return UPrim(I4) / UPrim(0) / params.cp;
291 }
292
293 /**
294 * @brief Computes specific total enthalpy from conservative state and pressure.
295 *
296 * H = (E + p) / rho, using `IdealGas::Enthalpy.`
297 *
298 * @tparam tU Conservative state vector type (deduced).
299 * @param U Conservative state vector.
300 * @param nVars Total number of variables.
301 * @param p Pressure.
302 * @return Specific total enthalpy H.
303 */
304 template <class tU>
306 tU &&U, int nVars, real p) const
307 {
308 //! perfect gas here
309 return IdealGas::Enthalpy(U(I4), U(0), p);
310 }
311
312 /**
313 * @brief Recovers pressure from specific total enthalpy and conservative state.
314 *
315 * p = H * rho - E (inverse of Pressure2Enthalpy).
316 *
317 * @tparam tU Conservative state vector type (deduced).
318 * @param U Conservative state vector.
319 * @param nVars Total number of variables.
320 * @param H Specific total enthalpy.
321 * @return Pressure p.
322 */
323 template <class tU>
325 tU &&U, int nVars, real H) const
326 {
327 //! perfect gas here
328 return H * U(0) - U(I4);
329 }
330 };
331
332 /**
333 * @brief Host-side physics object managing gas parameters and device-transferable reference values.
334 *
335 * Stores a `host_device_vector` of reference values (e.g., freestream quantities) and
336 * `PhysicsParams.` Supports JSON serialization and host/device transfer for GPU offloading.
337 * Use `deviceView<B>()` to obtain a `PhysicsDeviceView` for kernel invocation.
338 */
339 struct Physics
340 {
341 host_device_vector<real> reference_values; ///< Reference values (e.g., freestream state) for non-dimensionalization.
342 PhysicsParams params; ///< Gas physical parameters.
344 Physics,
346 params)
347
348 /// @brief Transfers reference values to host memory.
349 void to_host()
350 {
351 reference_values.to_host();
352 }
353
354 /// @brief Transfers reference values to the specified device backend.
355 /// @param B Target device backend (Host or CUDA).
357 {
358 reference_values.to_device(B);
359 }
360
361 /// @brief Returns the current device backend where reference values reside.
363 {
364 return reference_values.device();
365 }
366
367 template <DeviceBackend B>
368 using t_deviceView = PhysicsDeviceView<B>; ///< Device view type alias parameterized by backend.
369
370 /**
371 * @brief Creates a device-callable view of this Physics object.
372 *
373 * Asserts that the reference values reside on backend @p B (or Host with Unknown).
374 *
375 * @tparam B Target device backend.
376 * @return A `PhysicsDeviceView<B>` suitable for device kernel invocation.
377 */
378 template <DeviceBackend B>
380 {
381 DNDS_assert(reference_values.device() == B ||
383 return t_deviceView<B>{
384 reference_values.deviceView<B, int32_t>(),
385 params};
386 }
387
388 /**
389 * @brief Configures the physics for a calorically perfect ideal gas.
390 *
391 * Computes cp = Rg * gamma / (gamma - 1) and cv = cp / gamma.
392 *
393 * @param Rg Specific gas constant R = Cp - Cv.
394 * @param gamma Ratio of specific heats Cp/Cv.
395 */
396 void setPerfectGas(real Rg, real gamma)
397 {
398 params.Rg = Rg;
399 params.gamma = gamma;
400 params.cp = Rg * params.gamma / (params.gamma - 1);
402 }
403 };
404
405 /**
406 * @brief Computes the inviscid (Euler) flux projected onto a face normal direction.
407 *
408 * Accumulates the inviscid flux contribution into @p F:
409 * - F_i += U_i * (vn - vgn) for all variables (advection with grid velocity correction)
410 * - F_{d+1} += p * n_d for d = 0,1,2 (pressure contribution to momentum)
411 * - F_{I4} += vn * p (pressure work on energy)
412 *
413 * @note This function @b adds to @p F (does not zero it first). Caller must initialize F.
414 *
415 * @tparam TU Conservative state vector type (deduced).
416 * @tparam TF Flux vector type (deduced).
417 * @tparam TVecN Normal vector type (deduced).
418 * @param U Conservative state vector (rho, rhoU, rhoV, rhoW, E, ...).
419 * @param nVars Total number of variables.
420 * @param vn Normal velocity v dot n.
421 * @param vgn Grid normal velocity (for ALE/moving mesh; 0 for static mesh).
422 * @param n Outward unit face normal vector (3 components).
423 * @param p Pressure at the face.
424 * @param[in,out] F Flux vector to accumulate into.
425 */
426 template <typename TU, typename TF, class TVecN>
427 DNDS_DEVICE_CALLABLE inline void GasInviscidFlux_XY(TU &&U, int nVars, real vn, real vgn, TVecN &&n,
428 real p, TF &F)
429 {
430 for (int i = 0; i < nVars; i++)
431 F(i) += U(i) * (vn - vgn);
432 for (int d = 0; d < 3; d++)
433 F(d + 1) += p * n(d);
434 F(I4) += vn * p;
435 }
436}
Core type aliases, constants, and metaprogramming utilities for the DNDS framework.
#define DNDS_DEVICE_CALLABLE
Definition Defines.hpp:76
#define DNDS_DEVICE_TRIVIAL_COPY_DEFINE_NO_EMPTY_CTOR(T, T_Self)
Definition Defines.hpp:91
Device memory abstraction layer with backend-specific storage and factory creation.
Assertion / error-handling macros and supporting helper functions.
#define DNDS_assert(expr)
Debug-only assertion (compiled out when DNDS_NDEBUG is defined). Prints the expression + file/line + ...
Definition Errors.hpp:108
Core type definitions and utilities for the EulerP alternative Navier-Stokes evaluator module.
Shared ideal-gas thermodynamics and Roe-flux primitives.
JSON-to-Eigen conversion utilities and nlohmann_json helper macros.
Non-owning device-callable view {pointer, size} over a typed array.
Definition Vector.hpp:148
Namespace for the EulerP alternative evaluator module with GPU support.
Definition EulerP.hpp:29
DNDS_DEVICE_CALLABLE void GasInviscidFlux_XY(TU &&U, int nVars, real vn, real vgn, TVecN &&n, real p, TF &F)
Computes the inviscid (Euler) flux projected onto a face normal direction.
Eigen::Vector< real, nVarsFlow > TU
Fixed-size 5-component conservative state vector (rho, rhoU, rhoV, rhoW, E).
Definition EulerP.hpp:33
DNDS_DEVICE_CALLABLE real Pressure_From_InternalEnergy(real e, real gamma)
Pressure from internal energy: p = (gamma - 1) * e.
DNDS_DEVICE_CALLABLE real Enthalpy(real E, real rho, real p)
Specific enthalpy from conservative state: H = (E + p) / rho.
DNDS_DEVICE_CALLABLE real SpeedOfSoundSqr(real gamma, real p, real rho)
Speed of sound squared: a^2 = gamma * p / rho.
DeviceBackend
Enumerates the backends a DeviceStorage / Array can live on.
@ Unknown
Unset / sentinel.
@ Host
Plain CPU memory.
constexpr T sqr(const T &a)
a * a, constexpr. Works for all arithmetic types.
Definition Defines.hpp:517
double real
Canonical floating-point scalar used throughout DNDSR (double precision).
Definition Defines.hpp:105
Device-callable view of physics parameters providing thermodynamic operations.
vector_DeviceView< B, real, int32_t > reference_values
Device-resident reference values (e.g., freestream quantities).
DNDS_DEVICE_CALLABLE void Cons2PrimDiff(tU &&U, tUPrim &&UPrim, tDiffU &&DiffU, tDiffUPrim &&DiffUPrim, int nVars) const
Converts conservative variable gradients to primitive variable gradients.
DNDS_DEVICE_CALLABLE auto Prim2GammaAcousticSpeed(tUPrim &&UPrim, int nVars, real p) const
Computes the ratio of specific heats and the acoustic speed of sound.
DNDS_DEVICE_CALLABLE real Pressure2Enthalpy(tU &&U, int nVars, real p) const
Computes specific total enthalpy from conservative state and pressure.
DNDS_DEVICE_CALLABLE void Prim2Cons(tUPrim &&UPrim, tU &&U, int nVars) const
Converts primitive state to conservative state.
DNDS_DEVICE_CALLABLE real Cons2EInternal(tU &&U, int nVars) const
Extracts internal energy from a conservative state vector.
DNDS_DEVICE_CALLABLE void Cons2Prim(tU &&U, tUPrim &&UPrim, int nVars) const
Converts conservative state to primitive state.
DNDS_DEVICE_CALLABLE real getMuTot(tUPrim &&UPrim, tDiffUPrim &&DiffUPrim, int nVars, real p, real T) const
Computes the total dynamic viscosity.
DNDS_DEVICE_CALLABLE real Prim2Temperature(tUPrim &&UPrim, int nVars) const
Computes temperature from the primitive state.
PhysicsParams params
Gas physical parameters (copied to device).
DNDS_DEVICE_CALLABLE real Prim2Pressure(tUPrim &&UPrim, int nVars, real T) const
Computes pressure from the primitive state using the ideal gas law.
DNDS_DEVICE_CALLABLE real Enthalpy2Pressure(tU &&U, int nVars, real H) const
Recovers pressure from specific total enthalpy and conservative state.
POD struct holding gas physical properties for the ideal gas model.
real mu0
Dynamic viscosity coefficient. Default: effectively inviscid.
real TRef
Reference temperature [K] for viscosity models.
real gamma
only simple data here allowed
real cv
Specific heat at constant volume.
real Rg
Specific gas constant (Cp - Cv).
int muModel
Viscosity model selector (0 = constant viscosity).
real cp
Specific heat at constant pressure.
DNDS_NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_ORDERED_AND_UNORDERED_JSON(PhysicsParams, gamma, mu0, cp, Rg, TRef, muModel)
Host-side physics object managing gas parameters and device-transferable reference values.
void to_device(DeviceBackend B)
Transfers reference values to the specified device backend.
void setPerfectGas(real Rg, real gamma)
Configures the physics for a calorically perfect ideal gas.
PhysicsDeviceView< B > t_deviceView
Device view type alias parameterized by backend.
DNDS_NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_ORDERED_AND_UNORDERED_JSON(Physics, reference_values, params) void to_host()
Transfers reference values to host memory.
PhysicsParams params
Gas physical parameters.
DeviceBackend device()
Returns the current device backend where reference values reside.
t_deviceView< B > deviceView()
Creates a device-callable view of this Physics object.
host_device_vector< real > reference_values
Reference values (e.g., freestream state) for non-dimensionalization.
Eigen::Vector3d n(1.0, 0.0, 0.0)