Skip to content

Commit 9b7a503

Browse files
mrvandenboomclaudesbryngelson
authored
Output Immersed Boundary load and state data (#1302)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Spencer Bryngelson <sbryngelson@gmail.com>
1 parent b93dfa7 commit 9b7a503

15 files changed

Lines changed: 145 additions & 9 deletions

docs/documentation/case.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ To restart the simulation from $k$-th time step, see @ref running "Restarting Ca
615615
| `alpha_wrt(i)` | Logical | Add the volume fraction of fluid $i$ to the database |
616616
| `gamma_wrt` | Logical | Add the specific heat ratio function to the database |
617617
| `heat_ratio_wrt` | Logical | Add the specific heat ratio to the database |
618+
| `ib_state_wrt` | Logical | Write IB state and loads to a datafile at each time step |
618619
| `pi_inf_wrt` | Logical | Add the liquid stiffness function to the database |
619620
| `pres_inf_wrt` | Logical | Add the liquid stiffness to the formatted database |
620621
| `c_wrt` | Logical | Add the sound speed to the database |
@@ -675,6 +676,8 @@ If `file_per_process` is true, then pre_process, simulation, and post_process mu
675676

676677
- `probe_wrt` activates the output of state variables at coordinates specified by `probe(i)%[x;y,z]`.
677678

679+
- `ib_state_wrt` activates the output of data specified by patch_ib(i)%force(:) (and torque, vel, angular_vel, angles, [x,y,z]_centroid) into a single binary datafile for all IBs at all timesteps. During post_processing, this file is converted into separate time histories for each IB.
680+
678681
- `output_partial_domain` activates the output of part of the domain specified by `[x,y,z]_output%%beg` and `[x,y,z]_output%%end`.
679682
This is useful for large domains where only a portion of the domain is of interest.
680683
It is not supported when `precision = 1` and `format = 1`.

src/post_process/m_data_input.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impure subroutine s_read_ib_data_files(file_loc_base, t_step)
164164
if (parallel_io) then
165165
write (file_loc, '(A)') trim(file_loc_base)//'ib.dat'
166166
else
167-
write (file_loc, '(A)') trim(file_loc_base)//'/ib.dat'
167+
write (file_loc, '(A)') trim(file_loc_base)//'/ib_data.dat'
168168
end if
169169
inquire (FILE=trim(file_loc), EXIST=file_exist)
170170

src/post_process/m_data_output.fpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module m_data_output
3030
s_write_variable_to_formatted_database_file, &
3131
s_write_lag_bubbles_results_to_text, &
3232
s_write_lag_bubbles_to_formatted_database_file, &
33+
s_write_ib_state_files, &
3334
s_write_intf_data_file, &
3435
s_write_energy_data_file, &
3536
s_close_formatted_database_file, &
@@ -1501,6 +1502,61 @@ contains
15011502
15021503
end subroutine s_write_lag_variable_to_formatted_database_file
15031504
1505+
impure subroutine s_write_ib_state_files()
1506+
1507+
character(len=len_trim(case_dir) + 4*name_len) :: in_file, out_file, file_loc
1508+
integer :: iu_in, ios, i, rec_id
1509+
integer, allocatable, dimension(:) :: iu_out
1510+
real(wp) :: rec_time
1511+
real(wp), dimension(3) :: rec_force, rec_torque
1512+
real(wp), dimension(3) :: rec_vel, rec_angular_vel
1513+
real(wp), dimension(3) :: rec_angles, rec_centroid
1514+
1515+
file_loc = trim(case_dir)//'/D'
1516+
1517+
in_file = trim(file_loc)//'/ib_state.dat'
1518+
open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', &
1519+
status='old', action='read', iostat=ios)
1520+
if (ios /= 0) then
1521+
call s_mpi_abort('Cannot open IB state input file: '//trim(in_file))
1522+
end if
1523+
1524+
allocate (iu_out(num_ibs))
1525+
do i = 1, num_ibs
1526+
write (out_file, '(A,I0,A)') trim(file_loc)//'/ib_', i, '.txt'
1527+
open (newunit=iu_out(i), file=trim(out_file), form='formatted', status='replace', action='write', iostat=ios)
1528+
if (ios /= 0) then
1529+
call s_mpi_abort('Cannot open IB state output file: '//trim(out_file))
1530+
end if
1531+
write (iu_out(i), '(A)') &
1532+
'mytime fx fy fz Tau_x Tau_y Tau_z vx vy vz omega_x omega_y omega_z angle_x angle_y angle_z x_c y_c z_c'
1533+
end do
1534+
1535+
do
1536+
read (iu_in, iostat=ios) rec_time, rec_id, &
1537+
rec_force, rec_torque, rec_vel, rec_angular_vel, rec_angles, &
1538+
rec_centroid(1), rec_centroid(2), rec_centroid(3)
1539+
if (ios /= 0) exit
1540+
1541+
if (rec_id >= 1 .and. rec_id <= num_ibs) then
1542+
write (iu_out(rec_id), '(19(ES24.16E3,1X))') rec_time, &
1543+
rec_force(1), rec_force(2), rec_force(3), &
1544+
rec_torque(1), rec_torque(2), rec_torque(3), &
1545+
rec_vel(1), rec_vel(2), rec_vel(3), &
1546+
rec_angular_vel(1), rec_angular_vel(2), rec_angular_vel(3), &
1547+
rec_angles(1), rec_angles(2), rec_angles(3), &
1548+
rec_centroid(1), rec_centroid(2), rec_centroid(3)
1549+
end if
1550+
end do
1551+
1552+
close (iu_in)
1553+
do i = 1, num_ibs
1554+
close (iu_out(i))
1555+
end do
1556+
deallocate (iu_out)
1557+
1558+
end subroutine s_write_ib_state_files
1559+
15041560
!> @brief Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data file.
15051561
impure subroutine s_write_intf_data_file(q_prim_vf)
15061562

src/post_process/m_global_parameters.fpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ module m_global_parameters
261261
logical :: schlieren_wrt
262262
logical :: cf_wrt
263263
logical :: ib
264+
logical :: ib_state_wrt
264265
logical :: chem_wrt_Y(1:num_species)
265266
logical :: chem_wrt_T
266267
logical :: lag_header
@@ -494,6 +495,7 @@ contains
494495
sim_data = .false.
495496
cf_wrt = .false.
496497
ib = .false.
498+
ib_state_wrt = .false.
497499
lag_txt_wrt = .false.
498500
lag_header = .true.
499501
lag_db_wrt = .false.

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
& 'adv_n', 'ib', 'cfl_adap_dt', 'cfl_const_dt', 'cfl_dt', &
102102
& 'surface_tension', 'hyperelasticity', 'bubbles_lagrange', &
103103
& 'output_partial_domain', 'relativity', 'cont_damage', 'bc_io', &
104-
& 'down_sample','fft_wrt', 'hyper_cleaning' ]
104+
& 'down_sample','fft_wrt', 'hyper_cleaning', 'ib_state_wrt']
105105
call MPI_BCAST(${VAR}$, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr)
106106
#:endfor
107107

src/post_process/m_start_up.fpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ contains
116116
lag_rad_wrt, lag_rvel_wrt, lag_r0_wrt, lag_rmax_wrt, &
117117
lag_rmin_wrt, lag_dphidt_wrt, lag_pres_wrt, lag_mv_wrt, &
118118
lag_mg_wrt, lag_betaT_wrt, lag_betaC_wrt, &
119-
alpha_rho_e_wrt
119+
alpha_rho_e_wrt, ib_state_wrt
120120

121121
! Inquiring the status of the post_process.inp file
122122
file_loc = 'post_process.inp'

src/post_process/p_main.fpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ program p_main
9393
end do
9494
! END: Time-Marching Loop
9595

96+
if (proc_rank == 0 .and. ib_state_wrt) then
97+
call s_write_ib_state_files()
98+
end if
99+
96100
close (11)
97101

98102
call s_finalize_modules()

src/simulation/m_checker.fpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ contains
4040

4141
call s_check_inputs_time_stepping
4242

43+
@:PROHIBIT(ib_state_wrt .and. .not. ib, "ib_state_wrt requires ib to be enabled")
44+
4345
end subroutine s_check_inputs
4446

4547
!> Checks constraints on compiler options

src/simulation/m_data_output.fpp

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,22 @@ module m_data_output
3737
s_open_run_time_information_file, &
3838
s_open_com_files, &
3939
s_open_probe_files, &
40+
s_open_ib_state_file, &
4041
s_write_run_time_information, &
4142
s_write_data_files, &
4243
s_write_serial_data_files, &
4344
s_write_parallel_data_files, &
45+
s_write_ib_data_file, &
4446
s_write_com_files, &
4547
s_write_probe_files, &
48+
s_write_ib_state_file, &
4649
s_close_run_time_information_file, &
4750
s_close_com_files, &
4851
s_close_probe_files, &
49-
s_finalize_data_output_module, &
50-
s_write_ib_data_file
52+
s_close_ib_state_file, &
53+
s_finalize_data_output_module
54+
55+
integer :: ib_state_unit = -1 !< I/O unit for IB state binary file
5156

5257
real(wp), allocatable, dimension(:, :, :) :: icfl_sf !< ICFL stability criterion
5358
real(wp), allocatable, dimension(:, :, :) :: vcfl_sf !< VCFL stability criterion
@@ -254,6 +259,20 @@ contains
254259

255260
end subroutine s_open_probe_files
256261

262+
impure subroutine s_open_ib_state_file
263+
character(len=path_len + 2*name_len) :: file_loc
264+
integer :: ios
265+
266+
write (file_loc, '(A)') 'ib_state.dat'
267+
file_loc = trim(case_dir)//'/D/'//trim(file_loc)
268+
open (newunit=ib_state_unit, file=trim(file_loc), &
269+
form='unformatted', &
270+
access='stream', &
271+
status='replace', &
272+
iostat=ios)
273+
if (ios /= 0) call s_mpi_abort('Cannot open IB state output file: '//trim(file_loc))
274+
end subroutine s_open_ib_state_file
275+
257276
!> The goal of the procedure is to output to the run-time
258277
!! information file the stability criteria extrema in the
259278
!! entire computational domain and at the given time-step.
@@ -1071,7 +1090,7 @@ contains
10711090
write (t_step_dir, '(A,I0,A,I0)') trim(case_dir)//'/p_all'
10721091
write (t_step_dir, '(a,i0,a,i0)') trim(case_dir)//'/p_all/p', &
10731092
proc_rank, '/', time_step
1074-
write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat'
1093+
write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib_data.dat'
10751094

10761095
open (2, FILE=trim(file_path), &
10771096
FORM='unformatted', &
@@ -1136,7 +1155,26 @@ contains
11361155
call s_write_serial_ib_data(time_step)
11371156
end if
11381157

1139-
end subroutine
1158+
end subroutine s_write_ib_data_file
1159+
1160+
!> @brief Writes IB state records to D/ib_state.dat. Must be called only on rank 0.
1161+
impure subroutine s_write_ib_state_file()
1162+
1163+
integer :: i
1164+
1165+
do i = 1, num_ibs
1166+
write (ib_state_unit) mytime, i, &
1167+
patch_ib(i)%force, &
1168+
patch_ib(i)%torque, &
1169+
patch_ib(i)%vel, &
1170+
patch_ib(i)%angular_vel, &
1171+
patch_ib(i)%angles, &
1172+
patch_ib(i)%x_centroid, &
1173+
patch_ib(i)%y_centroid, &
1174+
patch_ib(i)%z_centroid
1175+
end do
1176+
1177+
end subroutine s_write_ib_state_file
11401178

11411179
!> This writes a formatted data file where the root processor
11421180
!! can write out the CoM information
@@ -1907,6 +1945,12 @@ contains
19071945

19081946
end subroutine s_close_probe_files
19091947

1948+
impure subroutine s_close_ib_state_file
1949+
1950+
close (ib_state_unit)
1951+
1952+
end subroutine s_close_ib_state_file
1953+
19101954
!> The computation of parameters, the allocation of memory,
19111955
!! the association of pointers and/or the execution of any
19121956
!! other procedures that are necessary to setup the module.

src/simulation/m_global_parameters.fpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ module m_global_parameters
396396
!> @{
397397
logical :: ib
398398
integer :: num_ibs
399+
logical :: ib_state_wrt
399400

400401
type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib
401402
type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l
@@ -715,6 +716,7 @@ contains
715716
! Immersed Boundaries
716717
ib = .false.
717718
num_ibs = dflt_int
719+
ib_state_wrt = .false.
718720
719721
! Bubble modeling
720722
bubbles_euler = .false.

0 commit comments

Comments
 (0)