Skip to content

Commit 423d5f1

Browse files
committed
feature: integrate rotations into ICPP patches (#1594)
Add a rotation framework to initial-condition (ICPP) patches, mirroring the existing immersed-boundary rotation support. - Extract the rotation-matrix computation into a new shared module m_patch_geometries, taking angle/matrix arrays as arguments so both ICPP and IB patches can call it (m_ib_patches now uses a thin wrapper). - Add angles + rotation_matrix(_inverse) fields to ic_patch_parameters, defaulting angles to zero (identity rotation) so existing cases are unaffected. - Apply the inverse-rotation transform in the rectangle inside-test as a proof of concept; remaining geometries are straightforward follow-up. - Register patch_icpp(i)%angles in the parameter definitions so the angle is settable from a case file. - Add a 2D_rotated_rectangle example demonstrating a 45-degree patch.
1 parent 4cebbb0 commit 423d5f1

7 files changed

Lines changed: 157 additions & 41 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
import json
3+
4+
# Configuring case dictionary
5+
print(
6+
json.dumps(
7+
{
8+
# Logistics
9+
"run_time_info": "T",
10+
# Computational Domain Parameters
11+
"x_domain%beg": 0.0e00,
12+
"x_domain%end": 1.0e00,
13+
"y_domain%beg": 0.0e00,
14+
"y_domain%end": 1.0e00,
15+
"m": 99,
16+
"n": 99,
17+
"p": 0,
18+
"dt": 5.0e-07,
19+
"t_step_start": 0,
20+
"t_step_stop": 1000,
21+
"t_step_save": 100,
22+
# Simulation Algorithm Parameters
23+
"num_patches": 2,
24+
"model_eqns": "6eq",
25+
"alt_soundspeed": "F",
26+
"num_fluids": 2,
27+
"mpp_lim": "T",
28+
"mixture_err": "T",
29+
"time_stepper": "rk3",
30+
"weno_order": 5,
31+
"weno_eps": 1.0e-16,
32+
"weno_Re_flux": "F",
33+
"weno_avg": "F",
34+
"mapped_weno": "T",
35+
"null_weights": "F",
36+
"mp_weno": "F",
37+
"riemann_solver": "hllc",
38+
"wave_speeds": "direct",
39+
"avg_state": "arithmetic",
40+
"bc_x%beg": -3,
41+
"bc_x%end": -3,
42+
"bc_y%beg": -3,
43+
"bc_y%end": -3,
44+
# Formatted Database Files Structure Parameters
45+
"format": "silo",
46+
"precision": "double",
47+
"prim_vars_wrt": "T",
48+
"parallel_io": "T",
49+
# Patch 1: Base
50+
"patch_icpp(1)%geometry": 3,
51+
"patch_icpp(1)%x_centroid": 0.5e00,
52+
"patch_icpp(1)%y_centroid": 0.5e00,
53+
"patch_icpp(1)%length_x": 1.0e00,
54+
"patch_icpp(1)%length_y": 1.0e00,
55+
"patch_icpp(1)%vel(1)": 100.0e00,
56+
"patch_icpp(1)%vel(2)": 100.0e00,
57+
"patch_icpp(1)%pres": 1.0e05,
58+
"patch_icpp(1)%alpha_rho(1)": 1000.0e00,
59+
"patch_icpp(1)%alpha_rho(2)": 1.0,
60+
"patch_icpp(1)%alpha(1)": 1.0e-12,
61+
"patch_icpp(1)%alpha(2)": 1.0 - 1.0e-12,
62+
# Patch 2: Rotated rectangle to transport
63+
"patch_icpp(2)%geometry": 3,
64+
"patch_icpp(2)%x_centroid": 0.5e00,
65+
"patch_icpp(2)%y_centroid": 0.5e00,
66+
"patch_icpp(2)%length_x": 0.4e00,
67+
"patch_icpp(2)%length_y": 0.15e00,
68+
"patch_icpp(2)%angles(3)": 0.785398e00,
69+
"patch_icpp(2)%alter_patch(1)": "T",
70+
"patch_icpp(2)%vel(1)": 100.0e00,
71+
"patch_icpp(2)%vel(2)": 100.0e00,
72+
"patch_icpp(2)%pres": 1.0e05,
73+
"patch_icpp(2)%alpha_rho(1)": 1.0,
74+
"patch_icpp(2)%alpha_rho(2)": 1.0,
75+
"patch_icpp(2)%alpha(1)": 0,
76+
"patch_icpp(2)%alpha(2)": 1.0,
77+
# Fluids Physical Parameters
78+
"fluid_pp(1)%gamma": 1.0e00 / (2.35e00 - 1.0e00),
79+
"fluid_pp(1)%pi_inf": 2.35e00 * 1.0e09 / (2.35e00 - 1.0e00),
80+
"fluid_pp(2)%gamma": 1.0e00 / (1.4e00 - 1.0e00),
81+
"fluid_pp(2)%pi_inf": 0.0e00,
82+
}
83+
)
84+
)

src/common/m_derived_types.fpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ module m_derived_types
284284
! Geometry 14 (3D spherical harmonic): sph_har_coeff(l,m) for real Y_lm
285285
real(wp), dimension(0:max_sph_harm_degree,-max_sph_harm_degree:max_sph_harm_degree) :: sph_har_coeff
286286
real(wp), dimension(3) :: normal !< Patch orientation normal vector (x, y, z)
287+
! Patch rotation (shared framework; see m_patch_geometries)
288+
real(wp), dimension(1:3) :: angles !< Rotation angles about x, y, z axes
289+
real(wp), dimension(1:3,1:3) :: rotation_matrix !< Rotation matrix built from angles
290+
real(wp), dimension(1:3,1:3) :: rotation_matrix_inverse !< Inverse of rotation matrix
287291
logical, dimension(0:num_patches_max - 1) :: alter_patch !< Overwrite permissions for preceding patches
288292
logical :: smoothen !< Whether patch boundaries are smoothed across cells
289293
integer :: smooth_patch_id !< Identity (id) of the patch with which current patch is to get smoothed

src/common/m_patch_geometries.fpp

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ module m_patch_geometries
1818

1919
implicit none
2020

21-
public :: f_is_inside_sphere, f_is_inside_cylinder, f_is_inside_cuboid, f_is_inside_airfoil, f_is_inside_ellipse
21+
public :: f_is_inside_sphere, f_is_inside_cylinder, f_is_inside_cuboid, f_is_inside_airfoil, f_is_inside_ellipse, &
22+
& s_compute_rotation_matrix
2223

2324
contains
2425

@@ -140,4 +141,52 @@ contains
140141

141142
end function f_is_inside_ellipse
142143

144+
!> Compute a rotation matrix for converting to the rotating frame of the boundary
145+
subroutine s_compute_rotation_matrix(angles, rotation_matrix, rotation_matrix_inverse)
146+
147+
$:GPU_ROUTINE(parallelism='[seq]')
148+
149+
real(wp), dimension(1:3), intent(in) :: angles
150+
real(wp), dimension(1:3,1:3), intent(out) :: rotation_matrix
151+
real(wp), dimension(1:3,1:3), intent(out) :: rotation_matrix_inverse
152+
real(wp), dimension(3, 3, 3) :: rotation
153+
real(wp) :: angle
154+
155+
! construct the x, y, and z rotation matrices
156+
157+
if (num_dims == 3) then
158+
! also compute the x and y axes in 3D
159+
angle = angles(1)
160+
rotation(1, 1,:) = [1._wp, 0._wp, 0._wp]
161+
rotation(1, 2,:) = [0._wp, cos(angle), -sin(angle)]
162+
rotation(1, 3,:) = [0._wp, sin(angle), cos(angle)]
163+
164+
angle = angles(2)
165+
rotation(2, 1,:) = [cos(angle), 0._wp, sin(angle)]
166+
rotation(2, 2,:) = [0._wp, 1._wp, 0._wp]
167+
rotation(2, 3,:) = [-sin(angle), 0._wp, cos(angle)]
168+
169+
! apply the y rotation to the x rotation
170+
rotation_matrix(:,:) = matmul(rotation(1,:,:), rotation(2,:,:))
171+
rotation_matrix_inverse(:,:) = matmul(transpose(rotation(2,:,:)), transpose(rotation(1,:,:)))
172+
end if
173+
174+
! z component first, since it applies in 2D and 3D
175+
angle = angles(3)
176+
rotation(3, 1,:) = [cos(angle), -sin(angle), 0._wp]
177+
rotation(3, 2,:) = [sin(angle), cos(angle), 0._wp]
178+
rotation(3, 3,:) = [0._wp, 0._wp, 1._wp]
179+
180+
if (num_dims == 3) then
181+
! apply the z rotation to the xy rotation in 3D
182+
rotation_matrix(:,:) = matmul(rotation_matrix(:,:), rotation(3,:,:))
183+
rotation_matrix_inverse(:,:) = matmul(transpose(rotation(3,:,:)), rotation_matrix_inverse(:,:))
184+
else
185+
! write out only the z rotation in 2D
186+
rotation_matrix(:,:) = rotation(3,:,:)
187+
rotation_matrix_inverse(:,:) = transpose(rotation(3,:,:))
188+
end if
189+
190+
end subroutine s_compute_rotation_matrix
191+
143192
end module m_patch_geometries

src/pre_process/m_global_parameters.fpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ contains
205205
patch_icpp(i)%epsilon = dflt_real
206206
patch_icpp(i)%beta = dflt_real
207207
patch_icpp(i)%normal = dflt_real
208+
patch_icpp(i)%angles = 0._wp
208209
patch_icpp(i)%radii = dflt_real
209210
patch_icpp(i)%alter_patch = .false.
210211
patch_icpp(i)%alter_patch(0) = .true.

src/pre_process/m_icpp_patches.fpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ contains
6666
print *, 'Processing patch', i
6767
end if
6868

69+
call s_compute_rotation_matrix(patch_icpp(i)%angles, patch_icpp(i)%rotation_matrix, &
70+
& patch_icpp(i)%rotation_matrix_inverse)
71+
6972
!> ICPP Patches
7073
!> @{
7174
! Spherical patch
@@ -103,6 +106,9 @@ contains
103106
print *, 'Processing patch', i
104107
end if
105108

109+
call s_compute_rotation_matrix(patch_icpp(i)%angles, patch_icpp(i)%rotation_matrix, &
110+
& patch_icpp(i)%rotation_matrix_inverse)
111+
106112
!> ICPP Patches
107113
!> @{
108114
! Circular patch
@@ -147,6 +153,9 @@ contains
147153
print *, 'Processing patch', i
148154
end if
149155

156+
call s_compute_rotation_matrix(patch_icpp(i)%angles, patch_icpp(i)%rotation_matrix, &
157+
& patch_icpp(i)%rotation_matrix_inverse)
158+
150159
! Line segment patch
151160
if (patch_icpp(i)%geometry == 1) then
152161
call s_icpp_line_segment(i, patch_id_fp, q_prim_vf)
@@ -604,7 +613,7 @@ contains
604613
type(scalar_field), dimension(1:sys_size), intent(inout) :: q_prim_vf
605614
integer :: i, j, k !< generic loop iterators
606615
real(wp) :: pi_inf, gamma, lit_gamma !< Equation of state parameters
607-
616+
real(wp), dimension(1:3) :: xyz_local
608617
@:HardcodedDimensionsExtrusion()
609618
@:Hardcoded2DVariables()
610619
@@ -630,7 +639,10 @@ contains
630639
! Assign patch vars if cell is covered and patch has write permission
631640
do j = 0, n
632641
do i = 0, m
633-
if (f_is_inside_cuboid(x_cc(i) - x_centroid, y_cc(j) - y_centroid, 0._wp, [length_x, length_y, 0._wp])) then
642+
! Rotate the centroid-relative grid point into the patch frame
643+
xyz_local = matmul(patch_icpp(patch_id)%rotation_matrix_inverse, [x_cc(i) - x_centroid, y_cc(j) - y_centroid, &
644+
& 0._wp])
645+
if (f_is_inside_cuboid(xyz_local(1), xyz_local(2), 0._wp, [length_x, length_y, 0._wp])) then
634646
if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then
635647
call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp)
636648

src/simulation/m_ib_patches.fpp

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -415,45 +415,10 @@ contains
415415

416416
$:GPU_ROUTINE(parallelism='[seq]')
417417

418-
integer, intent(in) :: patch_id
419-
real(wp), dimension(3, 3, 3) :: rotation
420-
real(wp) :: angle
418+
integer, intent(in) :: patch_id
421419

422-
! construct the x, y, and z rotation matrices
423-
424-
if (num_dims == 3) then
425-
! also compute the x and y axes in 3D
426-
angle = patch_ib(patch_id)%angles(1)
427-
rotation(1, 1,:) = [1._wp, 0._wp, 0._wp]
428-
rotation(1, 2,:) = [0._wp, cos(angle), -sin(angle)]
429-
rotation(1, 3,:) = [0._wp, sin(angle), cos(angle)]
430-
431-
angle = patch_ib(patch_id)%angles(2)
432-
rotation(2, 1,:) = [cos(angle), 0._wp, sin(angle)]
433-
rotation(2, 2,:) = [0._wp, 1._wp, 0._wp]
434-
rotation(2, 3,:) = [-sin(angle), 0._wp, cos(angle)]
435-
436-
! apply the y rotation to the x rotation
437-
patch_ib(patch_id)%rotation_matrix(:,:) = matmul(rotation(1,:,:), rotation(2,:,:))
438-
patch_ib(patch_id)%rotation_matrix_inverse(:,:) = matmul(transpose(rotation(2,:,:)), transpose(rotation(1,:,:)))
439-
end if
440-
441-
! z component first, since it applies in 2D and 3D
442-
angle = patch_ib(patch_id)%angles(3)
443-
rotation(3, 1,:) = [cos(angle), -sin(angle), 0._wp]
444-
rotation(3, 2,:) = [sin(angle), cos(angle), 0._wp]
445-
rotation(3, 3,:) = [0._wp, 0._wp, 1._wp]
446-
447-
if (num_dims == 3) then
448-
! apply the z rotation to the xy rotation in 3D
449-
patch_ib(patch_id)%rotation_matrix(:,:) = matmul(patch_ib(patch_id)%rotation_matrix(:,:), rotation(3,:,:))
450-
patch_ib(patch_id)%rotation_matrix_inverse(:,:) = matmul(transpose(rotation(3,:,:)), &
451-
& patch_ib(patch_id)%rotation_matrix_inverse(:,:))
452-
else
453-
! write out only the z rotation in 2D
454-
patch_ib(patch_id)%rotation_matrix(:,:) = rotation(3,:,:)
455-
patch_ib(patch_id)%rotation_matrix_inverse(:,:) = transpose(rotation(3,:,:))
456-
end if
420+
call s_compute_rotation_matrix(patch_ib(patch_id)%angles, patch_ib(patch_id)%rotation_matrix, &
421+
& patch_ib(patch_id)%rotation_matrix_inverse)
457422

458423
end subroutine s_update_ib_rotation_matrix
459424

toolchain/mfc/params/definitions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,7 @@ def _load():
820820
for j in range(1, 4):
821821
_r(f"{px}radii({j})", REAL)
822822
_r(f"{px}normal({j})", REAL)
823+
_r(f"{px}angles({j})", REAL)
823824
_r(f"{px}vel({j})", A_REAL, math=r"\f$u_" + str(j) + r"\f$")
824825
for f in range(1, NF + 1):
825826
_r(f"{px}alpha({f})", A_REAL, math=r"\f$\alpha_" + str(f) + r"\f$")

0 commit comments

Comments
 (0)