Skip to content

Commit 5ee319c

Browse files
hyeoksu-leeHyeoksu LeeHyeoksu LeesbryngelsonHyeoksu Lee
authored
Add Liutex to post_process using LAPACK (#970)
Co-authored-by: Hyeoksu Lee <[email protected]> Co-authored-by: Hyeoksu Lee <[email protected]> Co-authored-by: Spencer Bryngelson <[email protected]> Co-authored-by: Hyeoksu Lee <[email protected]>
1 parent 6b3fe8e commit 5ee319c

File tree

15 files changed

+296
-17
lines changed

15 files changed

+296
-17
lines changed

CMakeLists.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -391,9 +391,10 @@ HANDLE_SOURCES(syscheck OFF)
391391
# * FFTW (optional) Should be linked with an FFTW-like library (fftw/cufftw),
392392
# depending on whether OpenACC is enabled and which compiler is
393393
# being used.
394+
# * LAPACK (optional) Should be linked with LAPACK
394395

395396
function(MFC_SETUP_TARGET)
396-
cmake_parse_arguments(ARGS "OpenACC;MPI;SILO;HDF5;FFTW" "TARGET" "SOURCES" ${ARGN})
397+
cmake_parse_arguments(ARGS "OpenACC;MPI;SILO;HDF5;FFTW;LAPACK" "TARGET" "SOURCES" ${ARGN})
397398

398399
add_executable(${ARGS_TARGET} ${ARGS_SOURCES})
399400
set(IPO_TARGETS ${ARGS_TARGET})
@@ -461,6 +462,11 @@ function(MFC_SETUP_TARGET)
461462
endif()
462463
endif()
463464

465+
if (ARGS_LAPACK)
466+
find_package(LAPACK REQUIRED)
467+
target_link_libraries(${a_target} PRIVATE LAPACK::LAPACK)
468+
endif()
469+
464470
if (MFC_OpenACC AND ARGS_OpenACC)
465471
find_package(OpenACC)
466472

@@ -547,7 +553,7 @@ endif()
547553
if (MFC_POST_PROCESS)
548554
MFC_SETUP_TARGET(TARGET post_process
549555
SOURCES "${post_process_SRCs}"
550-
MPI SILO HDF5 FFTW)
556+
MPI SILO HDF5 FFTW LAPACK)
551557

552558
# -O0 is in response to https://github.com/MFlowCode/MFC-develop/issues/95
553559
target_compile_options(post_process PRIVATE -O0)

docs/documentation/case.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ To restart the simulation from $k$-th time step, see [Restarting Cases](running.
589589
| `omega_wrt(i)` | Logical | Add the $i$-direction vorticity to the database |
590590
| `schlieren_wrt` | Logical | Add the numerical schlieren to the database|
591591
| `qm_wrt` | Logical | Add the Q-criterion to the database|
592+
| `liutex_wrt` | Logical | Add the Liutex to the database|
592593
| `tau_wrt` | Logical | Add the elastic stress components to the database|
593594
| `fd_order` | Integer | Order of finite differences for computing the vorticity and the numerical Schlieren function [1,2,4] |
594595
| `schlieren_alpha(i)` | Real | Intensity of the numerical Schlieren computed via `alpha(i)` |
@@ -628,7 +629,7 @@ If `file_per_process` is true, then pre_process, simulation, and post_process mu
628629
- `output_partial_domain` activates the output of part of the domain specified by `[x,y,z]_output%beg` and `[x,y,z]_output%end`.
629630
This is useful for large domains where only a portion of the domain is of interest.
630631
It is not supported when `precision = 1` and `format = 1`.
631-
It also cannot be enabled with `flux_wrt`, `heat_ratio_wrt`, `pres_inf_wrt`, `c_wrt`, `omega_wrt`, `ib`, `schlieren_wrt`, or `qm_wrt`.
632+
It also cannot be enabled with `flux_wrt`, `heat_ratio_wrt`, `pres_inf_wrt`, `c_wrt`, `omega_wrt`, `ib`, `schlieren_wrt`, `qm_wrt`, or 'liutex_wrt'.
632633

633634
### 8. Acoustic Source {#acoustic-source}
634635

docs/documentation/references.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,5 @@
6969
- <a id="Powell94">Powell, K. G. (1994). An approximate Riemann solver for magnetohydrodynamics: (That works in more than one dimension). In Upwind and high-resolution schemes (pp. 570-583). Springer.</a>
7070

7171
- <a id="Cao19">Cao, S., Zhang, Y., Liao, D., Zhong, P., and Wang, K. G. (2019). Shock-induced damage and dynamic fracture in cylindrical bodies submerged in liquid. International Journal of Solids and Structures, 169:55–71. Elsevier.</a>
72+
73+
- <a id="Xu2019">Xu, W., Gao, Y., Deng, Y., Liu, J., and Liu, C. (2019). An explicit expression for the calculation of the Rortex vector. Physics of Fluids, 31(9)..</a>

examples/3D_turb_mixing/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# 3D Turbulent Mixing layer (3D)
2+
3+
## Liutex visualization at transitional state
4+
<img src='result.png' height='MAX_HEIGHT'/>

examples/3D_turb_mixing/case.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
"omega_wrt(2)": "T",
9797
"omega_wrt(3)": "T",
9898
"qm_wrt": "T",
99+
"liutex_wrt": "T",
99100
# Patch 1
100101
"patch_icpp(1)%geometry": 9,
101102
"patch_icpp(1)%x_centroid": Lx / 2.0,

examples/3D_turb_mixing/result.png

2.01 MB
Loading

src/post_process/m_checker.fpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ contains
3232
call s_check_inputs_flux_limiter
3333
call s_check_inputs_volume_fraction
3434
call s_check_inputs_vorticity
35+
call s_check_inputs_qm
36+
call s_check_inputs_liutex
3537
call s_check_inputs_schlieren
3638
call s_check_inputs_surface_tension
3739
call s_check_inputs_no_flow_variables
@@ -49,8 +51,7 @@ contains
4951
impure subroutine s_check_inputs_partial_domain
5052
@:PROHIBIT(output_partial_domain .and. format == 1)
5153
@:PROHIBIT(output_partial_domain .and. precision == 1)
52-
@:PROHIBIT(output_partial_domain .and. any([flux_wrt, heat_ratio_wrt, pres_inf_wrt, c_wrt, schlieren_wrt, qm_wrt, ib, any(omega_wrt)]))
53-
54+
@:PROHIBIT(output_partial_domain .and. any([flux_wrt, heat_ratio_wrt, pres_inf_wrt, c_wrt, schlieren_wrt, qm_wrt, liutex_wrt, ib, any(omega_wrt)]))
5455
@:PROHIBIT(output_partial_domain .and. (f_is_default(x_output%beg) .or. f_is_default(x_output%end)))
5556
@:PROHIBIT(output_partial_domain .and. n /= 0 .and. (f_is_default(y_output%beg) .or. f_is_default(y_output%end)))
5657
@:PROHIBIT(output_partial_domain .and. p /= 0 .and. (f_is_default(z_output%beg) .or. f_is_default(z_output%end)))
@@ -110,6 +111,16 @@ contains
110111
@:PROHIBIT(any(omega_wrt) .and. fd_order == dflt_int, "fd_order must be set for omega_wrt")
111112
end subroutine s_check_inputs_vorticity
112113

114+
!> Checks constraints on Q-criterion parameters
115+
impure subroutine s_check_inputs_qm
116+
@:PROHIBIT(n == 0 .and. qm_wrt)
117+
end subroutine s_check_inputs_qm
118+
119+
!> Checks constraints on liutex parameters
120+
impure subroutine s_check_inputs_liutex
121+
@:PROHIBIT(n == 0 .and. liutex_wrt)
122+
end subroutine s_check_inputs_liutex
123+
113124
!> Checks constraints on numerical Schlieren parameters
114125
!! (schlieren_wrt and schlieren_alpha)
115126
impure subroutine s_check_inputs_schlieren

src/post_process/m_derived_variables.fpp

Lines changed: 133 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ module m_derived_variables
2929
s_derive_flux_limiter, &
3030
s_derive_vorticity_component, &
3131
s_derive_qm, &
32+
s_derive_liutex, &
3233
s_derive_numerical_schlieren_function, &
3334
s_compute_speed_of_sound, &
3435
s_finalize_derived_variables_module
@@ -80,21 +81,21 @@ contains
8081
! s_compute_finite_difference_coefficients.
8182

8283
! Allocating centered finite-difference coefficients in x-direction
83-
if (omega_wrt(2) .or. omega_wrt(3) .or. schlieren_wrt) then
84+
if (omega_wrt(2) .or. omega_wrt(3) .or. schlieren_wrt .or. liutex_wrt) then
8485
allocate (fd_coeff_x(-fd_number:fd_number, &
8586
-offset_x%beg:m + offset_x%end))
8687
end if
8788

8889
! Allocating centered finite-difference coefficients in y-direction
89-
if (omega_wrt(1) .or. omega_wrt(3) &
90+
if (omega_wrt(1) .or. omega_wrt(3) .or. liutex_wrt &
9091
.or. &
9192
(n > 0 .and. schlieren_wrt)) then
9293
allocate (fd_coeff_y(-fd_number:fd_number, &
9394
-offset_y%beg:n + offset_y%end))
9495
end if
9596

9697
! Allocating centered finite-difference coefficients in z-direction
97-
if (omega_wrt(1) .or. omega_wrt(2) &
98+
if (omega_wrt(1) .or. omega_wrt(2) .or. liutex_wrt &
9899
.or. &
99100
(p > 0 .and. schlieren_wrt)) then
100101
allocate (fd_coeff_z(-fd_number:fd_number, &
@@ -556,6 +557,135 @@ contains
556557
557558
end subroutine s_derive_qm
558559
560+
!> This subroutine gets as inputs the primitive variables. From those
561+
!! inputs, it proceeds to calculate the Liutex vector and its
562+
!! magnitude based on Xu et al. (2019).
563+
!! @param q_prim_vf Primitive variables
564+
!! @param liutex_mag Liutex magnitude
565+
!! @param liutex_axis Liutex axis
566+
impure subroutine s_derive_liutex(q_prim_vf, liutex_mag, liutex_axis)
567+
integer, parameter :: nm = 3
568+
type(scalar_field), &
569+
dimension(sys_size), &
570+
intent(in) :: q_prim_vf
571+
572+
real(wp), &
573+
dimension(-offset_x%beg:m + offset_x%end, &
574+
-offset_y%beg:n + offset_y%end, &
575+
-offset_z%beg:p + offset_z%end), &
576+
intent(out) :: liutex_mag !< Liutex magnitude
577+
578+
real(wp), &
579+
dimension(-offset_x%beg:m + offset_x%end, &
580+
-offset_y%beg:n + offset_y%end, &
581+
-offset_z%beg:p + offset_z%end, nm), &
582+
intent(out) :: liutex_axis !< Liutex rigid rotation axis
583+
584+
character, parameter :: ivl = 'N' !< compute left eigenvectors
585+
character, parameter :: ivr = 'V' !< compute right eigenvectors
586+
real(wp), dimension(nm, nm) :: vgt !< velocity gradient tensor
587+
real(wp), dimension(nm) :: lr, li !< real and imaginary parts of eigenvalues
588+
real(wp), dimension(nm, nm) :: vl, vr !< left and right eigenvectors
589+
integer, parameter :: lwork = 4*nm !< size of work array (4*nm recommended)
590+
real(wp), dimension(lwork) :: work !< work array
591+
integer :: info
592+
593+
real(wp), dimension(nm) :: eigvec !< real eigenvector
594+
real(wp) :: eigvec_mag !< magnitude of real eigenvector
595+
real(wp) :: omega_proj !< projection of vorticity on real eigenvector
596+
real(wp) :: lci !< imaginary part of complex eigenvalue
597+
real(wp) :: alpha
598+
599+
integer :: j, k, l, r, i !< Generic loop iterators
600+
integer :: idx
601+
602+
do l = -offset_z%beg, p + offset_z%end
603+
do k = -offset_y%beg, n + offset_y%end
604+
do j = -offset_x%beg, m + offset_x%end
605+
606+
! Get velocity gradient tensor (VGT)
607+
vgt(:, :) = 0._wp
608+
609+
do r = -fd_number, fd_number
610+
do i = 1, 3
611+
! d()/dx
612+
vgt(i, 1) = &
613+
vgt(i, 1) + &
614+
fd_coeff_x(r, j)* &
615+
q_prim_vf(mom_idx%beg + i - 1)%sf(r + j, k, l)
616+
! d()/dy
617+
vgt(i, 2) = &
618+
vgt(i, 2) + &
619+
fd_coeff_y(r, k)* &
620+
q_prim_vf(mom_idx%beg + i - 1)%sf(j, r + k, l)
621+
! d()/dz
622+
vgt(i, 3) = &
623+
vgt(i, 3) + &
624+
fd_coeff_z(r, l)* &
625+
q_prim_vf(mom_idx%beg + i - 1)%sf(j, k, r + l)
626+
end do
627+
end do
628+
629+
! Call appropriate LAPACK routine based on precision
630+
#ifdef MFC_SINGLE_PRECISION
631+
call sgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
632+
#else
633+
call dgeev(ivl, ivr, nm, vgt, nm, lr, li, vl, nm, vr, nm, work, lwork, info)
634+
#endif
635+
636+
! Find real eigenvector
637+
idx = 1
638+
do r = 2, 3
639+
if (abs(li(r)) < abs(li(idx))) then
640+
idx = r
641+
end if
642+
end do
643+
eigvec = vr(:, idx)
644+
645+
! Normalize real eigenvector if it is effectively non-zero
646+
eigvec_mag = sqrt(eigvec(1)**2._wp &
647+
+ eigvec(2)**2._wp &
648+
+ eigvec(3)**2._wp)
649+
if (eigvec_mag > sgm_eps) then
650+
eigvec = eigvec/eigvec_mag
651+
else
652+
eigvec = 0._wp
653+
end if
654+
655+
! Compute vorticity projected on the eigenvector
656+
omega_proj = (vgt(3, 2) - vgt(2, 3))*eigvec(1) &
657+
+ (vgt(1, 3) - vgt(3, 1))*eigvec(2) &
658+
+ (vgt(2, 1) - vgt(1, 2))*eigvec(3)
659+
660+
! As eigenvector can have +/- signs, we can choose the sign
661+
! so that omega_proj is positive
662+
if (omega_proj < 0._wp) then
663+
eigvec = -eigvec
664+
omega_proj = -omega_proj
665+
end if
666+
667+
! Find imaginary part of complex eigenvalue
668+
lci = li(mod(idx, 3) + 1)
669+
670+
! Compute Liutex magnitude
671+
alpha = omega_proj**2._wp - 4._wp*lci**2._wp ! (2*alpha)^2
672+
if (alpha > 0._wp) then
673+
liutex_mag(j, k, l) = omega_proj - sqrt(alpha)
674+
else
675+
liutex_mag(j, k, l) = omega_proj
676+
end if
677+
678+
! Compute Liutex axis
679+
liutex_axis(j, k, l, 1) = eigvec(1)
680+
liutex_axis(j, k, l, 2) = eigvec(2)
681+
liutex_axis(j, k, l, 3) = eigvec(3)
682+
683+
end do
684+
end do
685+
end do
686+
687+
end subroutine s_derive_liutex
688+
559689
!> This subroutine gets as inputs the conservative variables
560690
!! and density. From those inputs, it proceeds to calculate
561691
!! the values of the numerical Schlieren function, which are

src/post_process/m_global_parameters.fpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ module m_global_parameters
252252
logical :: c_wrt
253253
logical, dimension(3) :: omega_wrt
254254
logical :: qm_wrt
255+
logical :: liutex_wrt
255256
logical :: schlieren_wrt
256257
logical :: cf_wrt
257258
logical :: ib
@@ -432,6 +433,7 @@ contains
432433
c_wrt = .false.
433434
omega_wrt = .false.
434435
qm_wrt = .false.
436+
liutex_wrt = .false.
435437
schlieren_wrt = .false.
436438
sim_data = .false.
437439
cf_wrt = .false.
@@ -835,7 +837,7 @@ contains
835837
buff_size = max(offset_x%beg, offset_x%end, offset_y%beg, &
836838
offset_y%end, offset_z%beg, offset_z%end)
837839

838-
if (any(omega_wrt) .or. schlieren_wrt .or. qm_wrt) then
840+
if (any(omega_wrt) .or. schlieren_wrt .or. qm_wrt .or. liutex_wrt) then
839841
fd_number = max(1, fd_order/2)
840842
buff_size = buff_size + fd_number
841843
end if

src/post_process/m_mpi_proxy.fpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ contains
101101
& 'heat_ratio_wrt', 'pi_inf_wrt', 'pres_inf_wrt', 'cons_vars_wrt', &
102102
& 'prim_vars_wrt', 'c_wrt', 'qm_wrt','schlieren_wrt','chem_wrt_T', &
103103
& 'bubbles_euler', 'qbmm', 'polytropic', 'polydisperse', &
104-
& 'file_per_process', 'relax', 'cf_wrt', 'igr', &
104+
& 'file_per_process', 'relax', 'cf_wrt', 'igr', 'liutex_wrt', &
105105
& 'adv_n', 'ib', 'cfl_adap_dt', 'cfl_const_dt', 'cfl_dt', &
106106
& 'surface_tension', 'hyperelasticity', 'bubbles_lagrange', &
107107
& 'output_partial_domain', 'relativity', 'cont_damage', 'bc_io', &

0 commit comments

Comments
 (0)