1# 1 "/home/runner/work/MFC/MFC/src/post_process/m_derived_variables.fpp"
33 if (schlieren_wrt)
then
39 if (omega_wrt(2) .or. omega_wrt(3) .or. qm_wrt .or. schlieren_wrt .or. liutex_wrt)
then
43 if (omega_wrt(1) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt))
then
47 if (omega_wrt(1) .or. omega_wrt(2) .or. qm_wrt .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt))
then
57 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
58 & intent(inout) :: q_sf
76 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
77 & intent(inout) :: q_sf
94 integer,
intent(in) :: i
95 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
97 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
98 & intent(inout) :: q_sf
100 real(wp) :: top, bottom, slope
106 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
107 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j - 1,
k,
l)
108 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
110 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)
111 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
113 else if (i == 2)
then
114 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
115 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k - 1,
l)
116 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
118 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)
119 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
122 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
123 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l - 1)
124 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
126 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)
127 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
131 if (abs(top) < 1.e-8_wp) top = 0._wp
132 if (abs(bottom) < 1.e-8_wp) bottom = 0._wp
137 slope = (top*bottom)/(bottom**2._wp + 1.e-16_wp)
140 if (flux_lim == 1)
then
141 q_sf(
j,
k,
l) = max(0._wp, min(1._wp, slope))
142 else if (flux_lim == 2)
then
143 q_sf(
j,
k,
l) = max(0._wp, min(2._wp*slope, 5.e-1_wp*(1._wp + slope), 2._wp))
144 else if (flux_lim == 3)
then
145 q_sf(
j,
k,
l) = (15.e-1_wp*(slope**2._wp + slope))/(slope**2._wp + slope + 1._wp)
146 else if (flux_lim == 4)
then
147 q_sf(
j,
k,
l) = max(0._wp, min(1._wp, 2._wp*slope), min(slope, 2._wp))
148 else if (flux_lim == 5)
then
149 q_sf(
j,
k,
l) = max(0._wp, min(15.e-1_wp*slope, 1._wp), min(slope, 15.e-1_wp))
150 else if (flux_lim == 6)
then
151 q_sf(
j,
k,
l) = (slope**2._wp + slope)/(slope**2._wp + 1._wp)
152 else if (flux_lim == 7)
then
153 q_sf(
j,
k,
l) = (abs(slope) + slope)/(1._wp + abs(slope))
165 integer,
intent(in) :: i
166 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
168 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
169 & intent(inout) :: q_sf
171 integer ::
j,
k,
l, r
176 q_sf(
j,
k,
l) = 0._wp
180 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) + 1._wp/
y_cc(
k)*(
fd%fd_coeff_y(r, &
181 &
k)*
y_cc(r +
k)*q_prim_vf(eqn_idx%mom%end)%sf(
j, r +
k,
l) -
fd%fd_coeff_z(r, &
182 &
l)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(
j,
k, r +
l))
184 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, &
185 &
l) -
fd%fd_coeff_z(r,
l)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(
j,
k, r +
l)
191 else if (i == 2)
then
195 q_sf(
j,
k,
l) = 0._wp
199 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, &
200 & r +
l) -
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%end)%sf(r +
j,
k,
l)
202 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, &
203 & r +
l) -
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%end)%sf(r +
j,
k,
l)
213 q_sf(
j,
k,
l) = 0._wp
216 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, &
217 &
l) -
fd%fd_coeff_y(r,
k)*q_prim_vf(eqn_idx%mom%beg)%sf(
j, r +
k,
l)
230 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
232 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
233 & intent(inout) :: q_sf
235 real(wp),
dimension(1:3,1:3) :: q_jacobian_sf, s, s2, o, o2
236 real(wp) :: trs, q, iis
237 integer ::
j,
k,
l, r, jj, kk
242 q_jacobian_sf(:,:) = 0._wp
247 q_jacobian_sf(jj, 1) = q_jacobian_sf(jj, 1) +
fd%fd_coeff_x(r, &
248 &
j)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(r +
j,
k,
l)
250 q_jacobian_sf(jj, 2) = q_jacobian_sf(jj, 2) +
fd%fd_coeff_y(r, &
251 &
k)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(
j, r +
k,
l)
253 q_jacobian_sf(jj, 3) = q_jacobian_sf(jj, 3) +
fd%fd_coeff_z(r, &
254 &
l)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(
j,
k, r +
l)
261 s(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj))
262 o(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj))
268 o2(jj, kk) = o(jj, 1)*o(kk, 1) + o(jj, 2)*o(kk, 2) + o(jj, 3)*o(kk, 3)
269 s2(jj, kk) = s(jj, 1)*s(kk, 1) + s(jj, 2)*s(kk, 2) + s(jj, 3)*s(kk, 3)
274 q = 0.5_wp*((o2(1, 1) + o2(2, 2) + o2(3, 3)) - (s2(1, 1) + s2(2, 2) + s2(3, 3)))
275 trs = s(1, 1) + s(2, 2) + s(3, 3)
277 iis = 0.5_wp*((s(1, 1) + s(2, 2) + s(3, 3))**2 - (s2(1, 1) + s2(2, 2) + s2(3, 3)))
278 q_sf(
j,
k,
l) = q + iis
290 integer,
parameter :: nm = 3
291 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
295 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
296 & intent(out) :: liutex_mag
298 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), &
299 & intent(out) :: liutex_axis
300 character,
parameter :: ivl =
'N'
301 character,
parameter :: ivr =
'V'
302 real(wp),
dimension(nm, nm) :: vgt
303 real(wp),
dimension(nm) :: lr, li
304 real(wp),
dimension(nm, nm) :: vl, vr
305 integer,
parameter :: lwork = 4*nm
306 real(wp),
dimension(lwork) :: work
308 real(wp),
dimension(nm) :: eigvec
309 real(wp) :: eigvec_mag
310 real(wp) :: omega_proj
313 integer ::
j,
k,
l, r, i
325 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)
327 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)
329 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)
334#ifdef MFC_SINGLE_PRECISION
335 call sgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
337 call dgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
343 if (abs(li(r)) < abs(li(idx)))
then
350 eigvec_mag = sqrt(eigvec(1)**2._wp + eigvec(2)**2._wp + eigvec(3)**2._wp)
352 eigvec = eigvec/eigvec_mag
358 omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) + (vgt(1, 3) - vgt(3, 1))*eigvec(2) + (vgt(2, 1) - vgt(1, &
362 if (omega_proj < 0._wp)
then
364 omega_proj = -omega_proj
368 lci = li(mod(idx, 3) + 1)
371 alpha = omega_proj**2._wp - 4._wp*lci**2._wp
373 if (alpha > 0._wp)
then
374 liutex_mag(
j,
k,
l) = omega_proj - sqrt(alpha)
376 liutex_mag(
j,
k,
l) = omega_proj
380 liutex_axis(
j,
k,
l, 1) = eigvec(1)
381 liutex_axis(
j,
k,
l, 2) = eigvec(2)
382 liutex_axis(
j,
k,
l, 3) = eigvec(3)
395 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
396 & intent(inout) :: q_sf
398 real(wp) :: drho_dx, drho_dy, drho_dz
399 real(wp),
dimension(2) :: gm_rho_max
400 real(wp) :: alpha_last
401 integer :: i,
j,
k,
l
410 drho_dx = drho_dx +
fd%fd_coeff_x(i,
j)*
rho_sf(i +
j,
k,
l)
411 drho_dy = drho_dy +
fd%fd_coeff_y(i,
k)*
rho_sf(
j, i +
k,
l)
414 fd%gm_rho_sf(
j,
k,
l) = drho_dx*drho_dx + drho_dy*drho_dy
429 drho_dz = drho_dz +
fd%fd_coeff_z(i,
l)*
rho_sf(
j,
k, i +
l)
433 fd%gm_rho_sf(
j,
k,
l) =
fd%gm_rho_sf(
j,
k,
l) + drho_dz*drho_dz
439 fd%gm_rho_sf = sqrt(
fd%gm_rho_sf)
441 gm_rho_max = (/maxval(
fd%gm_rho_sf), real(
proc_rank, wp)/)
443 if (
num_procs > 1)
call s_mpi_reduce_maxloc(gm_rho_max)
451 q_sf = -
fd%gm_rho_sf/gm_rho_max(1)
456 q_sf(
j,
k,
l) = 0._wp
464 do i = 1, eqn_idx%adv%end - eqn_idx%E
465 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(i)*
q_cons_vf(i + eqn_idx%E)%sf(
j,
k, &
466 &
l)*
fd%gm_rho_sf(
j,
k,
l)/gm_rho_max(1)
467 alpha_last = alpha_last -
q_cons_vf(i + eqn_idx%E)%sf(
j,
k,
l)
469 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(num_fluids)*alpha_last*
fd%gm_rho_sf(
j,
k, &
472 do i = 1, eqn_idx%adv%end - eqn_idx%E
473 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(i)*
q_cons_vf(i + eqn_idx%E)%sf(
j,
k, &
474 &
l)*
fd%gm_rho_sf(
j,
k,
l)/gm_rho_max(1)
493 if (schlieren_wrt)
deallocate (
fd%gm_rho_sf)
497 if (
allocated(
fd%fd_coeff_x))
deallocate (
fd%fd_coeff_x)
498 if (
allocated(
fd%fd_coeff_y))
deallocate (
fd%fd_coeff_y)
499 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).