1# 1 "/home/runner/work/MFC/MFC/src/post_process/m_derived_variables.fpp"
32 if (schlieren_wrt)
then
38 if (omega_wrt(2) .or. omega_wrt(3) .or. qm_wrt .or. schlieren_wrt .or. liutex_wrt)
then
42 if (omega_wrt(1) .or. omega_wrt(3) .or. qm_wrt .or. liutex_wrt .or. (n > 0 .and. schlieren_wrt))
then
46 if (omega_wrt(1) .or. omega_wrt(2) .or. qm_wrt .or. liutex_wrt .or. (p > 0 .and. schlieren_wrt))
then
56 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
57 & intent(inout) :: q_sf
75 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
76 & intent(inout) :: q_sf
94 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
96 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
97 & intent(inout) :: q_sf
100 real(wp) :: blkmod1, blkmod2
105 if (alt_soundspeed .neqv. .true.)
then
111 q_sf(i,
j,
k) = (1._wp/(
rho_sf(i,
j,
k)*(q_prim_vf(eqn_idx%adv%beg)%sf(i,
j, &
112 &
k)/blkmod1 + (1._wp - q_prim_vf(eqn_idx%adv%beg)%sf(i,
j,
k))/blkmod2)))
115 if (mixture_err .and. q_sf(i,
j,
k) < 0._wp)
then
116 q_sf(i,
j,
k) = 1.e-16_wp
118 q_sf(i,
j,
k) = sqrt(q_sf(i,
j,
k))
130 integer,
intent(in) :: i
131 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
133 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
134 & intent(inout) :: q_sf
136 real(wp) :: top, bottom, slope
142 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
143 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j - 1,
k,
l)
144 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
146 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)
147 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j + 1,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
149 else if (i == 2)
then
150 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
151 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k - 1,
l)
152 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
154 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)
155 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k + 1,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
158 if (q_prim_vf(eqn_idx%cont%end + i)%sf(
j,
k,
l) >= 0._wp)
then
159 top = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l - 1)
160 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
162 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)
163 bottom = q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l + 1) - q_prim_vf(eqn_idx%adv%beg)%sf(
j,
k,
l)
167 if (abs(top) < 1.e-8_wp) top = 0._wp
168 if (abs(bottom) < 1.e-8_wp) bottom = 0._wp
173 slope = (top*bottom)/(bottom**2._wp + 1.e-16_wp)
176 if (flux_lim == 1)
then
177 q_sf(
j,
k,
l) = max(0._wp, min(1._wp, slope))
178 else if (flux_lim == 2)
then
179 q_sf(
j,
k,
l) = max(0._wp, min(2._wp*slope, 5.e-1_wp*(1._wp + slope), 2._wp))
180 else if (flux_lim == 3)
then
181 q_sf(
j,
k,
l) = (15.e-1_wp*(slope**2._wp + slope))/(slope**2._wp + slope + 1._wp)
182 else if (flux_lim == 4)
then
183 q_sf(
j,
k,
l) = max(0._wp, min(1._wp, 2._wp*slope), min(slope, 2._wp))
184 else if (flux_lim == 5)
then
185 q_sf(
j,
k,
l) = max(0._wp, min(15.e-1_wp*slope, 1._wp), min(slope, 15.e-1_wp))
186 else if (flux_lim == 6)
then
187 q_sf(
j,
k,
l) = (slope**2._wp + slope)/(slope**2._wp + 1._wp)
188 else if (flux_lim == 7)
then
189 q_sf(
j,
k,
l) = (abs(slope) + slope)/(1._wp + abs(slope))
201 integer,
intent(in) :: i
202 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
204 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
205 & intent(inout) :: q_sf
207 integer ::
j,
k,
l, r
212 q_sf(
j,
k,
l) = 0._wp
216 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) + 1._wp/
y_cc(
k)*(
fd%fd_coeff_y(r, &
217 &
k)*
y_cc(r +
k)*q_prim_vf(eqn_idx%mom%end)%sf(
j, r +
k,
l) -
fd%fd_coeff_z(r, &
218 &
l)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(
j,
k, r +
l))
220 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, &
221 &
l) -
fd%fd_coeff_z(r,
l)*q_prim_vf(eqn_idx%mom%beg + 1)%sf(
j,
k, r +
l)
227 else if (i == 2)
then
231 q_sf(
j,
k,
l) = 0._wp
235 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, &
236 & r +
l) -
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%end)%sf(r +
j,
k,
l)
238 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, &
239 & r +
l) -
fd%fd_coeff_x(r,
j)*q_prim_vf(eqn_idx%mom%end)%sf(r +
j,
k,
l)
249 q_sf(
j,
k,
l) = 0._wp
252 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, &
253 &
l) -
fd%fd_coeff_y(r,
k)*q_prim_vf(eqn_idx%mom%beg)%sf(
j, r +
k,
l)
266 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
268 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
269 & intent(inout) :: q_sf
271 real(wp),
dimension(1:3,1:3) :: q_jacobian_sf, s, s2, o, o2
272 real(wp) :: trs, q, iis
273 integer ::
j,
k,
l, r, jj, kk
278 q_jacobian_sf(:,:) = 0._wp
283 q_jacobian_sf(jj, 1) = q_jacobian_sf(jj, 1) +
fd%fd_coeff_x(r, &
284 &
j)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(r +
j,
k,
l)
286 q_jacobian_sf(jj, 2) = q_jacobian_sf(jj, 2) +
fd%fd_coeff_y(r, &
287 &
k)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(
j, r +
k,
l)
289 q_jacobian_sf(jj, 3) = q_jacobian_sf(jj, 3) +
fd%fd_coeff_z(r, &
290 &
l)*q_prim_vf(eqn_idx%mom%beg + jj - 1)%sf(
j,
k, r +
l)
297 s(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) + q_jacobian_sf(kk, jj))
298 o(jj, kk) = 0.5_wp*(q_jacobian_sf(jj, kk) - q_jacobian_sf(kk, jj))
304 o2(jj, kk) = o(jj, 1)*o(kk, 1) + o(jj, 2)*o(kk, 2) + o(jj, 3)*o(kk, 3)
305 s2(jj, kk) = s(jj, 1)*s(kk, 1) + s(jj, 2)*s(kk, 2) + s(jj, 3)*s(kk, 3)
310 q = 0.5_wp*((o2(1, 1) + o2(2, 2) + o2(3, 3)) - (s2(1, 1) + s2(2, 2) + s2(3, 3)))
311 trs = s(1, 1) + s(2, 2) + s(3, 3)
313 iis = 0.5_wp*((s(1, 1) + s(2, 2) + s(3, 3))**2 - (s2(1, 1) + s2(2, 2) + s2(3, 3)))
314 q_sf(
j,
k,
l) = q + iis
326 integer,
parameter :: nm = 3
327 type(
scalar_field),
dimension(sys_size),
intent(in) :: q_prim_vf
331 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
332 & intent(out) :: liutex_mag
334 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), &
335 & intent(out) :: liutex_axis
336 character,
parameter :: ivl =
'N'
337 character,
parameter :: ivr =
'V'
338 real(wp),
dimension(nm, nm) :: vgt
339 real(wp),
dimension(nm) :: lr, li
340 real(wp),
dimension(nm, nm) :: vl, vr
341 integer,
parameter :: lwork = 4*nm
342 real(wp),
dimension(lwork) :: work
344 real(wp),
dimension(nm) :: eigvec
345 real(wp) :: eigvec_mag
346 real(wp) :: omega_proj
349 integer ::
j,
k,
l, r, i
361 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)
363 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)
365 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)
370#ifdef MFC_SINGLE_PRECISION
371 call sgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
373 call dgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
379 if (abs(li(r)) < abs(li(idx)))
then
386 eigvec_mag = sqrt(eigvec(1)**2._wp + eigvec(2)**2._wp + eigvec(3)**2._wp)
388 eigvec = eigvec/eigvec_mag
394 omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) + (vgt(1, 3) - vgt(3, 1))*eigvec(2) + (vgt(2, 1) - vgt(1, &
398 if (omega_proj < 0._wp)
then
400 omega_proj = -omega_proj
404 lci = li(mod(idx, 3) + 1)
407 alpha = omega_proj**2._wp - 4._wp*lci**2._wp
409 if (alpha > 0._wp)
then
410 liutex_mag(
j,
k,
l) = omega_proj - sqrt(alpha)
412 liutex_mag(
j,
k,
l) = omega_proj
416 liutex_axis(
j,
k,
l, 1) = eigvec(1)
417 liutex_axis(
j,
k,
l, 2) = eigvec(2)
418 liutex_axis(
j,
k,
l, 3) = eigvec(3)
431 real(wp),
dimension(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end), &
432 & intent(inout) :: q_sf
434 real(wp) :: drho_dx, drho_dy, drho_dz
435 real(wp),
dimension(2) :: gm_rho_max
436 real(wp) :: alpha_last
437 integer :: i,
j,
k,
l
446 drho_dx = drho_dx +
fd%fd_coeff_x(i,
j)*
rho_sf(i +
j,
k,
l)
447 drho_dy = drho_dy +
fd%fd_coeff_y(i,
k)*
rho_sf(
j, i +
k,
l)
450 fd%gm_rho_sf(
j,
k,
l) = drho_dx*drho_dx + drho_dy*drho_dy
465 drho_dz = drho_dz +
fd%fd_coeff_z(i,
l)*
rho_sf(
j,
k, i +
l)
469 fd%gm_rho_sf(
j,
k,
l) =
fd%gm_rho_sf(
j,
k,
l) + drho_dz*drho_dz
475 fd%gm_rho_sf = sqrt(
fd%gm_rho_sf)
477 gm_rho_max = (/maxval(
fd%gm_rho_sf), real(
proc_rank, wp)/)
479 if (
num_procs > 1)
call s_mpi_reduce_maxloc(gm_rho_max)
487 q_sf = -
fd%gm_rho_sf/gm_rho_max(1)
492 q_sf(
j,
k,
l) = 0._wp
500 do i = 1, eqn_idx%adv%end - eqn_idx%E
501 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(i)*
q_cons_vf(i + eqn_idx%E)%sf(
j,
k, &
502 &
l)*
fd%gm_rho_sf(
j,
k,
l)/gm_rho_max(1)
503 alpha_last = alpha_last -
q_cons_vf(i + eqn_idx%E)%sf(
j,
k,
l)
505 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(num_fluids)*alpha_last*
fd%gm_rho_sf(
j,
k, &
508 do i = 1, eqn_idx%adv%end - eqn_idx%E
509 q_sf(
j,
k,
l) = q_sf(
j,
k,
l) - schlieren_alpha(i)*
q_cons_vf(i + eqn_idx%E)%sf(
j,
k, &
510 &
l)*
fd%gm_rho_sf(
j,
k,
l)/gm_rho_max(1)
529 if (schlieren_wrt)
deallocate (
fd%gm_rho_sf)
533 if (
allocated(
fd%fd_coeff_x))
deallocate (
fd%fd_coeff_x)
534 if (
allocated(
fd%fd_coeff_y))
deallocate (
fd%fd_coeff_y)
535 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,...
subroutine, public s_derive_sound_speed(q_prim_vf, q_sf)
Compute the speed of sound from the primitive variables, density, specific heat ratio function,...
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...
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 gammas
subroutine s_compute_speed_of_sound(pres, rho, gamma, pi_inf, h, adv, vel_sum, c_c, c, qv)
Compute the speed of sound from thermodynamic state variables, supporting multiple equation-of-state ...
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.
real(wp), dimension(:), allocatable, public pi_infs
Finite-difference state for post_process: density gradient magnitude for numerical Schlieren and cent...
Derived type annexing a scalar field (SF).