-
Notifications
You must be signed in to change notification settings - Fork 132
Immersed Boundary force output #1292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
bfd6c65
4ba4703
647d4c0
a21a311
9192b58
1957f56
17bfe44
dedf570
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,7 @@ module m_data_output | |
| s_write_variable_to_formatted_database_file, & | ||
| s_write_lag_bubbles_results_to_text, & | ||
| s_write_lag_bubbles_to_formatted_database_file, & | ||
| s_write_ib_force_files, & | ||
| s_write_intf_data_file, & | ||
| s_write_energy_data_file, & | ||
| s_close_formatted_database_file, & | ||
|
|
@@ -1499,6 +1500,58 @@ contains | |
|
|
||
| end subroutine s_write_lag_variable_to_formatted_database_file | ||
|
|
||
| impure subroutine s_write_ib_force_files() | ||
|
|
||
| character(len=len_trim(case_dir) + 4*name_len) :: in_file, out_file, file_loc | ||
| integer :: iu_in, ios, i, rec_step, rec_id | ||
| integer, allocatable, dimension(:) :: iu_out | ||
| real(wp) :: rec_time | ||
| real(wp), dimension(3) :: rec_force, rec_torque | ||
|
|
||
| file_loc = trim(case_dir)//'/D' | ||
|
|
||
| in_file = trim(file_loc)//'/ib_force.dat' | ||
| open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', & | ||
| status='old', action='read', iostat=ios) | ||
| if (ios /= 0) then | ||
| print *, 'ERROR: cannot open input file: ', trim(in_file), ' iostat=', ios | ||
| return | ||
|
Comment on lines
+1514
to
+1518
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fail on bad force-file input.
🛠️ Suggested hard-fail read loop do
read (iu_in, iostat=ios) rec_step, rec_time, rec_id, rec_force, rec_torque
- if (ios /= 0) exit ! EOF (<0) or read error (>0)
- if (rec_id >= 1 .and. rec_id <= num_ibs) then
- write (iu_out(rec_id), '(7(ES24.16E3,1X))') rec_time, &
- rec_force(1), rec_force(2), rec_force(3), &
- rec_torque(1), rec_torque(2), rec_torque(3)
- end if
+ if (ios < 0) exit
+ if (ios > 0) call s_mpi_abort('Failed while reading '//trim(in_file)//'.')
+ if (rec_id < 1 .or. rec_id > num_ibs) then
+ call s_mpi_abort('IB force record id is out of range for current num_ibs.')
+ end if
+ write (iu_out(rec_id), '(7(ES24.16E3,1X))') rec_time, &
+ rec_force(1), rec_force(2), rec_force(3), &
+ rec_torque(1), rec_torque(2), rec_torque(3)
end doAlso applies to: 1524-1532, 1537-1544 |
||
| end if | ||
|
Comment on lines
+1514
to
+1519
|
||
|
|
||
| allocate (iu_out(num_ibs)) | ||
| do i = 1, num_ibs | ||
| write (out_file, '(A,I0,A)') trim(file_loc)//'/ib_', i, '.txt' | ||
|
Comment on lines
+1521
to
+1523
|
||
| open (newunit=iu_out(i), file=trim(out_file), form='formatted', status='replace', action='write', iostat=ios) | ||
|
Comment on lines
+1523
to
+1524
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is whitespace-delimited text, not CSV. The new files use Based on learnings: Flag modifications to public subroutine signatures, parameter defaults, or output formats - they affect downstream users. Also applies to: 1534-1543 |
||
| if (ios /= 0) then | ||
| print *, 'ERROR: cannot open output file: ', trim(out_file), ' iostat=', ios | ||
| close (iu_in) | ||
| do rec_id = 1, i - 1 | ||
| close (iu_out(rec_id)) | ||
| end do | ||
| deallocate (iu_out) | ||
| return | ||
| end if | ||
| write (iu_out(i), '(A)') 'mytime fx fy fz Tau_x Tau_y Tau_z' | ||
| end do | ||
|
Comment on lines
+1523
to
+1535
|
||
|
|
||
| do | ||
| read (iu_in, iostat=ios) rec_step, rec_time, rec_id, rec_force, rec_torque | ||
| if (ios /= 0) exit ! EOF (<0) or read error (>0) | ||
| if (rec_id >= 1 .and. rec_id <= num_ibs) then | ||
| write (iu_out(rec_id), '(7(ES24.16E3,1X))') rec_time, & | ||
| rec_force(1), rec_force(2), rec_force(3), & | ||
| rec_torque(1), rec_torque(2), rec_torque(3) | ||
| end if | ||
| end do | ||
|
|
||
| close (iu_in) | ||
| do i = 1, num_ibs | ||
| close (iu_out(i)) | ||
| end do | ||
| deallocate (iu_out) | ||
|
|
||
| end subroutine s_write_ib_force_files | ||
|
|
||
| !> @brief Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data file. | ||
| impure subroutine s_write_intf_data_file(q_prim_vf) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,6 +93,10 @@ program p_main | |
| end do | ||
| ! END: Time-Marching Loop | ||
|
|
||
| if (proc_rank == 0 .and. ib_force_wrt) then | ||
| call s_write_ib_force_files() | ||
| end if | ||
|
Comment on lines
+96
to
+98
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 5. Post_process can crash post_process calls s_write_ib_force_files() whenever ib_force_wrt is true, even if ib is false and num_ibs remains at its sentinel default. This can lead to invalid allocation sizes (allocate(iu_out(num_ibs))) and crashes for misconfigured inputs. Agent Prompt
|
||
|
|
||
| close (11) | ||
|
|
||
| call s_finalize_modules() | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -37,17 +37,20 @@ module m_data_output | |||||||||||||||||||||||||||||||||||||||||||||||
| s_open_run_time_information_file, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_open_com_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_open_probe_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_open_ib_force_file, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_run_time_information, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_data_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_serial_data_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_parallel_data_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_ib_data_file, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_com_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_probe_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_ib_force_file, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_close_run_time_information_file, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_close_com_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_close_probe_files, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_finalize_data_output_module, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_write_ib_data_file | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_close_ib_force_file, & | ||||||||||||||||||||||||||||||||||||||||||||||||
| s_finalize_data_output_module | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| real(wp), allocatable, dimension(:, :, :) :: icfl_sf !< ICFL stability criterion | ||||||||||||||||||||||||||||||||||||||||||||||||
| real(wp), allocatable, dimension(:, :, :) :: vcfl_sf !< VCFL stability criterion | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -254,6 +257,18 @@ contains | |||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| end subroutine s_open_probe_files | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| impure subroutine s_open_ib_force_file | ||||||||||||||||||||||||||||||||||||||||||||||||
| character(LEN=path_len + 2*name_len) :: file_loc | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| write (file_loc, '(A)') 'ib_force.dat' | ||||||||||||||||||||||||||||||||||||||||||||||||
| file_loc = trim(case_dir)//'/D/'//trim(file_loc) | ||||||||||||||||||||||||||||||||||||||||||||||||
| open (92, FILE=trim(file_loc), & | ||||||||||||||||||||||||||||||||||||||||||||||||
| FORM='unformatted', & | ||||||||||||||||||||||||||||||||||||||||||||||||
| ACCESS='stream', & | ||||||||||||||||||||||||||||||||||||||||||||||||
| STATUS='replace', & | ||||||||||||||||||||||||||||||||||||||||||||||||
| POSITION='append') | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+262
to
+269
|
||||||||||||||||||||||||||||||||||||||||||||||||
| write (file_loc, '(A)') 'ib_force.dat' | |
| file_loc = trim(case_dir)//'/D/'//trim(file_loc) | |
| open (92, FILE=trim(file_loc), & | |
| FORM='unformatted', & | |
| ACCESS='stream', & | |
| STATUS='replace', & | |
| POSITION='append') | |
| integer, save :: ib_force_unit = -1 | |
| integer :: istat | |
| write (file_loc, '(A)') 'ib_force.dat' | |
| file_loc = trim(case_dir)//'/D/'//trim(file_loc) | |
| open (newunit=ib_force_unit, FILE=trim(file_loc), & | |
| FORM='unformatted', & | |
| ACCESS='stream', & | |
| STATUS='replace', & | |
| POSITION='append', & | |
| iostat=istat) | |
| if (istat /= 0) then | |
| write (*,*) 'Error opening IB force file: ', trim(file_loc), ' iostat = ', istat | |
| end if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Uppercase keywords in open 📘 Rule violation ✓ Correctness
New Fortran code uses uppercase keywords (e.g., LEN, FILE, FORM, ACCESS, STATUS, POSITION) and non-2-space indentation, violating the required style conventions. This reduces consistency and can hinder maintainability across the codebase.
Agent Prompt
## Issue description
New Fortran code violates the required style conventions by using uppercase keywords (e.g., `LEN=`, `FILE=`, `FORM=`) and non-2-space indentation.
## Issue Context
Project style requires 2-space indentation and lowercase Fortran keywords for new/modified code.
## Fix Focus Areas
- src/simulation/m_data_output.fpp[260-269]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Copilot
AI
Mar 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s_write_serial_ib_data now writes ib_data.dat, but the post-process reader still looks for ib.dat (see src/post_process/m_data_input.f90). This will break post-processing (and possibly restarts) for serial I/O IB marker data. Either keep the original filename, or update the post-process input logic to accept the new name (ideally supporting both for backward compatibility).
| write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib_data.dat' | |
| write (file_path, '(A,I0,A)') trim(t_step_dir)//'/ib.dat' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find all references to ib_data.dat and ib.dat in the repo
echo "=== All references to ib_data.dat and ib.dat ==="
rg -n --no-heading -C2 '\bib(?:_data)?\.dat\b'Repository: MFlowCode/MFC
Length of output: 2384
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Examine the file around line 1089 and find the parallel I/O path
echo "=== Context around line 1089 in m_data_output.fpp ==="
sed -n '1080,1100p' src/simulation/m_data_output.fpp
echo -e "\n=== Search for parallel IB output (ib.dat) ==="
rg -n 'ib\.dat' src/simulation/m_data_output.fpp -C3Repository: MFlowCode/MFC
Length of output: 2082
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check if there's conditional logic for serial vs parallel IB output
echo "=== Search for s_write_serial_ib_data and related routines ==="
rg -n 's_write.*ib' src/simulation/m_data_output.fpp -A5Repository: MFlowCode/MFC
Length of output: 2628
Serial IB output filename breaks post-process reader compatibility.
s_write_serial_ib_data() writes ib_data.dat (line 1089), but src/post_process/m_data_input.f90 reads ib.dat for serial mode (lines 166–167). This mismatch will cause post-process to fail with "file not found" for IB data in serial-I/O mode. Either revert the serial filename to ib.dat to match the reader, or update the post-process reader to expect ib_data.dat in serial mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. Ib marker file rename breaks post_process 🐞 Bug ✓ Correctness
Simulation serial IB marker output was renamed to ib_data.dat, but post_process still looks for ib.dat and aborts if it’s missing. This will break post-processing for cases that rely on the per-timestep serial IB marker files.
Agent Prompt
### Issue description
Simulation now writes per-timestep serial IB marker files as `ib_data.dat`, but post-processing still requires `ib.dat` and aborts if not found.
### Issue Context
This breaks post-processing for IB cases in the serial-per-timestep path (`p_all/p<rank>/<tstep>/...`).
### Fix Focus Areas
- src/post_process/m_data_input.f90[164-208]
- src/simulation/m_data_output.fpp[1085-1093]
### Suggested approach
- In `s_read_ib_data_files`, when `parallel_io` is false, first try `ib_data.dat`; if missing, fall back to `ib.dat` (or switch fully to `ib_data.dat` if backward compatibility isn’t needed).
- Keep the `parallel_io` branch reading `restart_data/.../ib.dat` unchanged unless you also renamed that output.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -144,6 +144,7 @@ contains | |
| x_domain, y_domain, z_domain, & | ||
| hypoelasticity, & | ||
| ib, num_ibs, patch_ib, & | ||
| ib_force_wrt, & | ||
| fluid_pp, bub_pp, probe_wrt, prim_vars_wrt, & | ||
|
Comment on lines
146
to
148
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reject
🛡️ Suggested validation hook call s_check_inputs_common()
call s_check_inputs()
+ if (ib_force_wrt .and. .not. ib) then
+ call s_mpi_abort('ib_force_wrt requires ib = T. Exiting.')
+ end if |
||
| fd_order, probe, num_probes, t_step_old, & | ||
| alt_soundspeed, mixture_err, weno_Re_flux, & | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -463,6 +463,11 @@ contains | |||||
| call s_open_run_time_information_file() | ||||||
| end if | ||||||
|
|
||||||
| ! Opening and writing the header of the ib data file | ||||||
|
||||||
| ! Opening and writing the header of the ib data file | |
| ! Opening the IB force data file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gate the IB force file lifetime on ib too.
With ib_force_wrt = T and ib = F, Line 467 still opens and Line 1073 still closes the dedicated IB file, but the only write path is inside if (ib) at Lines 634-645. That leaves a misleading empty artifact unless this combination is rejected upstream.
Suggested fix
- if (proc_rank == 0 .and. ib_force_wrt) then
+ if (proc_rank == 0 .and. ib .and. ib_force_wrt) then
call s_open_ib_force_file()
end if
@@
- if (proc_rank == 0 .and. ib_force_wrt) then
+ if (proc_rank == 0 .and. ib .and. ib_force_wrt) then
call s_close_ib_force_file()
end ifBased on learnings, "Every new parameter must be added in at least 3 places: (1) toolchain/mfc/params/definitions.py, (2) Fortran variable declaration in src//m_global_parameters.fpp, (3) Fortran namelist in src//m_start_up.fpp, and optionally (4) toolchain/mfc/case_validator.py if the parameter has physics constraints".
Also applies to: 1072-1075
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving-IB force output can be stale or missing.
When moving_immersed_boundary_flag is true, Lines 636-641 bypass the fixed-IB force path and rely on s_propagate_immersed_boundaries(). Later in this file, that routine only calls s_compute_ib_forces() for moving_ibm == 2, so one-way moving IBs—and mixed fixed + one-way cases—reach Lines 643-645 with old or never-populated patch_ib(:)%force/torque.
Suggested fix
if (moving_immersed_boundary_flag) then
call s_propagate_immersed_boundaries(s)
- ! compute ib forces for fixed immersed boundaries if requested for output
- else if (ib_force_wrt .and. s == nstage) then
- call s_compute_ib_forces(q_prim_vf, fluid_pp)
end if
- ! Write IB forces to file if requested and at the RK final stage
if (ib_force_wrt .and. s == nstage) then
+ call s_compute_ib_forces(q_prim_vf, fluid_pp)
call s_write_ib_force_file(t_step)
end ifThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4. Forces may be stale/zero 🐞 Bug ✓ Correctness
When any IB is moving, the new logic skips s_compute_ib_forces in the main RK loop, yet still writes patch_ib(i)%force/torque for all IBs. This can produce incorrect force/torque output for fixed IBs in mixed cases and for moving_ibm==1 (analytic motion) where forces are never computed.
Agent Prompt
### Issue description
`m_time_steppers` writes IB forces at the final RK stage whenever `ib_force_wrt` is enabled, but it only computes forces in the non-moving case (or for `moving_ibm==2`). This can leave `patch_ib(:)%force/torque` unset/stale in mixed moving/fixed IB cases or for `moving_ibm==1`.
### Issue Context
`moving_immersed_boundary_flag` becomes true if *any* IB has `moving_ibm /= 0`, which prevents the fixed-IB compute path from running.
### Fix Focus Areas
- src/simulation/m_time_steppers.fpp[634-646]
- src/simulation/m_time_steppers.fpp[835-856]
### Suggested approach
- At `s == nstage` and `ib_force_wrt`, call `s_compute_ib_forces(q_prim_vf, fluid_pp)` unconditionally before `s_write_ib_force_file(t_step)`.
- Optionally avoid double-computation by tracking whether forces were already computed during this stage (e.g., a stage-local flag set by `s_propagate_immersed_boundaries`).
- Keep `s_propagate_immersed_boundaries` behavior for two-way coupling, but ensure final-stage output always reflects current state.
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Copilot
AI
Mar 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment says a footer is written for the IB force file, but s_close_ib_force_file only closes the unit and does not write any footer record. Please either implement a footer (and adjust the post-process reader) or update the comment to match the actual behavior.
| ! Writing the footer of and closing the IB data file | |
| ! Closing the IB data file |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -214,6 +214,7 @@ | |
| "prim_vars_wrt": "Write primitive variables", | ||
| "cons_vars_wrt": "Write conservative variables", | ||
| "run_time_info": "Print runtime info", | ||
| "ib_force_wrt": "Write IB force/torque data", | ||
| # Misc | ||
| "case_dir": "Case directory path", | ||
| "cantera_file": "Cantera mechanism file", | ||
|
|
@@ -932,7 +933,7 @@ def _load(): # pylint: disable=too-many-locals,too-many-statements | |
| _r("format", INT, {"output"}) | ||
| _r("schlieren_alpha", REAL, {"output"}) | ||
| for n in ["parallel_io", "file_per_process", "run_time_info", "prim_vars_wrt", | ||
| "cons_vars_wrt", "fft_wrt"]: | ||
| "cons_vars_wrt", "fft_wrt", "ib_force_wrt"]: | ||
| _r(n, LOG, {"output"}) | ||
|
Comment on lines
935
to
937
|
||
| for n in ["schlieren_wrt", "alpha_rho_wrt", "rho_wrt", "mom_wrt", "vel_wrt", | ||
| "flux_wrt", "E_wrt", "pres_wrt", "alpha_wrt", "kappa_wrt", "gamma_wrt", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. s_write_ib_force_files indentation
📘 Rule violation✓ CorrectnessAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools