1# 1 "/home/runner/work/MFC/MFC/src/post_process/m_derived_variables.fpp"
33 if (schlieren_wrt)
then
41 if (omega_wrt(2) .or. omega_wrt(3) .or. qm_wrt .or. schlieren_wrt .or. liutex_wrt)
then
45 if (omega_wrt(1) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt))
then
49 if (omega_wrt(1) .or. omega_wrt(2) .or. qm_wrt .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt))
then
59 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
60 & intent(inout) :: q_sf
78 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
79 & intent(inout) :: q_sf
96 integer,
intent(in) :: i
97 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
99 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
100 & intent(inout) :: q_sf
102 real(wp) :: top, bottom, slope
108 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
109 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j - 1,
k,
l)
110 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
112 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 2,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l)
113 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
115 else if (i == 2)
then
116 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
117 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k - 1,
l)
118 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
120 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 2,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l)
121 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
124 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
125 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l - 1)
126 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
128 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 2) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1)
129 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
133 if (abs(top) < 1.e-8_wp) top = 0._wp
134 if (abs(bottom) < 1.e-8_wp) bottom = 0._wp
139 slope = (top*bottom)/(bottom**2._wp + 1.e-16_wp)
142 if (flux_lim == 1)
then
143 q_sf(
j,
k,
l) = max(0._wp, min(1._wp, slope))
144 else if (flux_lim == 2)
then
145 q_sf(
j,
k,
l) = max(0._wp, min(2._wp*slope, 5.e-1_wp*(1._wp + slope), 2._wp))
146 else if (flux_lim == 3)
then
147 q_sf(
j,
k,
l) = (15.e-1_wp*(slope**2._wp + slope))/(slope**2._wp + slope + 1._wp)
148 else if (flux_lim == 4)
then
149 q_sf(
j,
k,
l) = max(0._wp, min(1._wp, 2._wp*slope), min(slope, 2._wp))
150 else if (flux_lim == 5)
then
151 q_sf(
j,
k,
l) = max(0._wp, min(15.e-1_wp*slope, 1._wp), min(slope, 15.e-1_wp))
152 else if (flux_lim == 6)
then
153 q_sf(
j,
k,
l) = (slope**2._wp + slope)/(slope**2._wp + 1._wp)
154 else if (flux_lim == 7)
then
155 q_sf(
j,
k,
l) = (abs(slope) + slope)/(1._wp + abs(slope))
167 integer,
intent(in) :: i
168 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
170 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
171 & intent(inout) :: q_sf
173 integer ::
j,
k,
l, r
178 q_sf(
j,
k,
l) = 0._wp
182 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) + 1._wp/
y_cc(
k)*(
fd%fd_coeff_y(r, &
183 &
k)*
y_cc(r +
k)*q_prim_vf(eqn_idx%mom%end)%sf(
j, r +
k,
l) -
fd%fd_coeff_z(r, &
184 &
l)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(
j,
k, r +
l))
186 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) +
fd%fd_coeff_y(r,
k)*q_prim_vf(eqn_idx%mom%end)%sf(
j, r +
k, &
187 &
l) -
fd%fd_coeff_z(r,
l)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(
j,
k, r +
l)
193 else if (i == 2)
then
197 q_sf(
j,
k,
l) = 0._wp
201 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) +
fd%fd_coeff_z(r,
l)/
y_cc(
k)*q_prim_vf(eqn_idx%mom%beg)%sf(
j,
k, &
202 & r +
l) -
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%end)%sf(r +
j,
k,
l)
204 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) +
fd%fd_coeff_z(r,
l)*q_prim_vf(eqn_idx%mom%beg)%sf(
j,
k, &
205 & r +
l) -
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%end)%sf(r +
j,
k,
l)
215 q_sf(
j,
k,
l) = 0._wp
218 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) +
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(r +
j,
k, &
219 &
l) -
fd%fd_coeff_y(r,
k)*q_prim_vf(eqn_idx%mom%beg)%sf(
j, r +
k,
l)
232 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
234 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
235 & intent(inout) :: q_sf
237 real(wp),
dimension(1:3,1:3) :: q_jacobian_sf, s, s2, o, o2
238 real(wp) :: trs, q, iis
239 integer ::
j,
k,
l, r, jj, kk
244 q_jacobian_sf(:,:) = 0._wp
249 q_jacobian_sf(jj, 1) = q_jacobian_sf(jj, 1) +
fd%fd_coeff_x(r, &
250 &
j)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(r +
j,
k,
l)
252 q_jacobian_sf(jj, 2) = q_jacobian_sf(jj, 2) +
fd%fd_coeff_y(r, &
253 &
k)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(
j, r +
k,
l)
255 q_jacobian_sf(jj, 3) = q_jacobian_sf(jj, 3) +
fd%fd_coeff_z(r, &
256 &
l)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(
j,
k, r +
l)
263 s(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj))
264 o(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj))
270 o2(jj, kk) = o(jj, 1)*o(kk, 1) + o(jj, 2)*o(kk, 2) + o(jj, 3)*o(kk, 3)
271 s2(jj, kk) = s(jj, 1)*s(kk, 1) + s(jj, 2)*s(kk, 2) + s(jj, 3)*s(kk, 3)
276 q = 0.5_wp*((o2(1, 1) + o2(2, 2) + o2(3, 3)) - (s2(1, 1) + s2(2, 2) + s2(3, 3)))
277 trs = s(1, 1) + s(2, 2) + s(3, 3)
279 iis = 0.5_wp*((s(1, 1) + s(2, 2) + s(3, 3))**2 - (s2(1, 1) + s2(2, 2) + s2(3, 3)))
280 q_sf(
j,
k,
l) = q + iis
292 integer,
parameter :: nm = 3
293 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
297 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
298 & intent(out) :: liutex_mag
300 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,nm), &
301 & intent(out) :: liutex_axis
302 character,
parameter :: ivl =
'N'
303 character,
parameter :: ivr =
'V'
304 real(wp),
dimension(nm, nm) :: vgt
305 real(wp),
dimension(nm) :: lr, li
306 real(wp),
dimension(nm, nm) :: vl, vr
307 integer,
parameter :: lwork = 4*nm
308 real(wp),
dimension(lwork) :: work
310 real(wp),
dimension(nm) :: eigvec
311 real(wp) :: eigvec_mag
312 real(wp) :: omega_proj
315 integer ::
j,
k,
l, r, i
327 vgt(i, 1) = vgt(i, 1) +
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%beg + i - 1)%sf(r +
j,
k,
l)
329 vgt(i, 2) = vgt(i, 2) +
fd%fd_coeff_y(r,
k)*q_prim_vf(eqn_idx%mom%beg + i - 1)%sf(
j, r +
k,
l)
331 vgt(i, 3) = vgt(i, 3) +
fd%fd_coeff_z(r,
l)*q_prim_vf(eqn_idx%mom%beg + i - 1)%sf(
j,
k, r +
l)
336#ifdef MFC_SINGLE_PRECISION
337 call sgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
339 call dgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
345 if (abs(li(r)) < abs(li(idx)))
then
352 eigvec_mag = sqrt(eigvec(1)**2._wp + eigvec(2)**2._wp + eigvec(3)**2._wp)
354 eigvec = eigvec/eigvec_mag
360 omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) + (vgt(1, 3) - vgt(3, 1))*eigvec(2) + (vgt(2, 1) - vgt(1, &
364 if (omega_proj < 0._wp)
then
366 omega_proj = -omega_proj
370 lci = li(mod(idx, 3) + 1)
373 alpha = omega_proj**2._wp - 4._wp*lci**2._wp
375 if (alpha > 0._wp)
then
376 liutex_mag(
j,
k,
l) = omega_proj - sqrt(alpha)
378 liutex_mag(
j,
k,
l) = omega_proj
382 liutex_axis(
j,
k,
l, 1) = eigvec(1)
383 liutex_axis(
j,
k,
l, 2) = eigvec(2)
384 liutex_axis(
j,
k,
l, 3) = eigvec(3)
397 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
398 & intent(inout) :: q_sf
400 real(wp) :: drho_dx, drho_dy, drho_dz
401 real(wp),
dimension(2) :: gm_rho_max
402 real(wp) :: alpha_last
403 integer :: i,
j,
k,
l
412 drho_dx = drho_dx +
fd%fd_coeff_x(i,
j)*
rho_sf(i +
j,
k,
l)
413 drho_dy = drho_dy +
fd%fd_coeff_y(i,
k)*
rho_sf(
j, i +
k,
l)
416 fd%gm_rho_sf(
j,
k,
l) = drho_dx*drho_dx + drho_dy*drho_dy
431 drho_dz = drho_dz +
fd%fd_coeff_z(i,
l)*
rho_sf(
j,
k, i +
l)
435 fd%gm_rho_sf(
j,
k,
l) =
fd%gm_rho_sf(
j,
k,
l) + drho_dz*drho_dz
441 fd%gm_rho_sf = sqrt(
fd%gm_rho_sf)
443 gm_rho_max = (/maxval(
fd%gm_rho_sf), real(
proc_rank, wp)/)
445 if (
num_procs > 1)
call s_mpi_reduce_maxloc(gm_rho_max)
453 q_sf = -
fd%gm_rho_sf/gm_rho_max(1)
458 q_sf(
j,
k,
l) = 0._wp
466 do i = 1, eqn_idx%adv%end - eqn_idx%E
467 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(i)*
q_cons_vf(i + eqn_idx%E)%sf(
j,
k, &
468 &
l)*
fd%gm_rho_sf(
j,
k,
l)/gm_rho_max(1)
469 alpha_last = alpha_last -
q_cons_vf(i + eqn_idx%E)%sf(
j,
k,
l)
471 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(num_fluids)*alpha_last*
fd%gm_rho_sf(
j,
k, &
474 do i = 1, eqn_idx%adv%end - eqn_idx%E
475 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(i)*
q_cons_vf(i + eqn_idx%E)%sf(
j,
k, &
476 &
l)*
fd%gm_rho_sf(
j,
k,
l)/gm_rho_max(1)
495 if (schlieren_wrt)
deallocate (
fd%gm_rho_sf)
499 if (
allocated(
fd%fd_coeff_x))
deallocate (
fd%fd_coeff_x)
500 if (
allocated(
fd%fd_coeff_y))
deallocate (
fd%fd_coeff_y)
501 if (
allocated(
fd%fd_coeff_z))
deallocate (
fd%fd_coeff_z)
type(scalar_field), dimension(sys_size), intent(inout) q_cons_vf
Compile-time constant parameters: default values, tolerances, and physical constants.
real(wp), parameter sgm_eps
Segmentation tolerance.
integer, parameter model_eqns_gamma_law
Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures.
Computes derived flow quantities (sound speed, vorticity, Schlieren, etc.) from conservative and prim...
type(fd_context), public fd
Finite-difference state: density gradient magnitude and centered FD coefficients in x-,...
impure subroutine, public s_derive_liutex(q_prim_vf, liutex_mag, liutex_axis)
Compute the Liutex vector and its magnitude based on Xu et al. (2019).
subroutine, public s_derive_specific_heat_ratio(q_sf)
Derive the specific heat ratio from the specific heat ratio function gamma_sf. The latter is stored i...
subroutine, public s_derive_liquid_stiffness(q_sf)
Compute the liquid stiffness from the specific heat ratio function gamma_sf and the liquid stiffness ...
impure subroutine, public s_initialize_derived_variables_module
Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the...
subroutine, public s_derive_vorticity_component(i, q_prim_vf, q_sf)
Compute the specified component of the vorticity from the primitive variables. From those inputs,...
impure subroutine, public s_derive_numerical_schlieren_function(q_cons_vf, q_sf)
Compute the values of the numerical Schlieren function, which are subsequently stored in the derived ...
subroutine, public s_derive_flux_limiter(i, q_prim_vf, q_sf)
Derive the flux limiter at cell boundary i+1/2. This is an approximation because the velocity used to...
impure subroutine, public s_finalize_derived_variables_module
Deallocation procedures for the module.
subroutine, public s_derive_qm(q_prim_vf, q_sf)
Compute the Q_M criterion from the primitive variables. The Q_M function, which are subsequently stor...
Equations of state in Gamma/Pi form, rho e = Gamma(rho) p + Pi(rho).
real(wp) function, public f_isentrope_pressure(pi_inf, gamma)
Reference pressure of that isentrope. Precomputed per fluid as isentrope_B.
subroutine, public s_compute_speed_of_sound(pres, rho, gamma, pi_inf, adv, c, alpha_rho)
Speed of sound of a thermodynamic state. Enthalpy is not an argument: for a real state H,...
real(wp) function, public f_isentrope_exponent(gamma)
Exponent of the stiffened-gas isentrope p + B = const rho**n. Precomputed per fluid as isentrope_n.
Global parameters for the post-process: domain geometry, equation of state, and output database setti...
type(int_bounds_info) offset_y
real(wp), dimension(:), allocatable y_cc
integer proc_rank
Rank of the local processor.
integer fd_number
Finite-difference half-stencil size: MAX(1, fd_order/2).
type(int_bounds_info) offset_x
integer num_procs
Number of processors.
type(int_bounds_info) offset_z
Basic floating-point utilities: approximate equality, default detection, and coordinate bounds.
logical elemental function, public f_approx_equal(a, b, tol_input)
Check if two floating point numbers of wp are within tolerance.
MPI gather and scatter operations for distributing post-process grid and flow-variable data.
Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation.
real(wp), dimension(:,:,:), allocatable, public pi_inf_sf
Scalar liquid stiffness function.
real(wp), dimension(:,:,:), allocatable, public gamma_sf
Scalar sp. heat ratio function.
real(wp), dimension(:,:,:), allocatable, public rho_sf
Scalar density function.
Finite-difference state for post_process: density gradient magnitude for numerical Schlieren and cent...
Derived type annexing a scalar field (SF).