@@ -19,8 +19,8 @@ module m_data_output
1919 & s_open_intf_data_file, s_open_energy_data_file, s_write_grid_to_formatted_database_file, &
2020 & s_write_variable_to_formatted_database_file, s_write_lag_bubbles_results_to_text, &
2121 & s_write_lag_bubbles_to_formatted_database_file, s_write_ib_state_files, s_write_intf_data_file, &
22- & s_write_energy_data_file, s_close_formatted_database_file, s_close_intf_data_file, s_close_energy_data_file , &
23- & s_finalize_data_output_module
22+ & s_write_energy_data_file, s_write_ib_bodies_to_formatted_database_file, s_close_formatted_database_file , &
23+ & s_close_intf_data_file, s_close_energy_data_file, s_finalize_data_output_module
2424
2525 ! Include Silo- HDF5 interface library
2626 include ' silo_f9x.inc'
@@ -1341,6 +1341,137 @@ contains
13411341
13421342 end subroutine s_write_energy_data_file
13431343
1344+ !> Read IB state and write a Silo point mesh with per-body scalar fields.
1345+ impure subroutine s_write_ib_bodies_to_formatted_database_file(t_step)
1346+
1347+ integer, intent(in) :: t_step
1348+ character(len=len_trim(case_dir) + 3*name_len) :: file_loc
1349+
1350+ #ifdef MFC_MPI
1351+ integer, parameter :: NFIELDS_PER_IB = 20
1352+ real(wp) :: ib_buf(NFIELDS_PER_IB)
1353+ real(wp), dimension(:,:), allocatable :: ib_data
1354+ logical :: file_exist
1355+ character(LEN=4*name_len), dimension(num_procs) :: meshnames
1356+ integer, dimension(num_procs) :: meshtypes
1357+ integer :: i, ios, file_unit
1358+ integer :: ierr, nBodies
1359+ real(wp), dimension(:), allocatable :: px, py, pz
1360+ real(wp), dimension(:), allocatable :: force_x, force_y, force_z
1361+ real(wp), dimension(:), allocatable :: torque_x, torque_y, torque_z
1362+ real(wp), dimension(:), allocatable :: vel_x, vel_y, vel_z
1363+ real(wp), dimension(:), allocatable :: omega_x, omega_y, omega_z
1364+ real(wp), dimension(:), allocatable :: angle_x, angle_y, angle_z
1365+ real(wp), dimension(:), allocatable :: ib_diameter
1366+
1367+ ! Build path to per-timestep IB state file
1368+ write (file_loc, ' (A,I0,A)' ) ' / restart_data/ ib_state_' , t_step, ' .dat'
1369+ file_loc = trim(case_dir) // trim(file_loc)
1370+
1371+ inquire (FILE=trim(file_loc), EXIST=file_exist)
1372+ if (.not. file_exist) then
1373+ call s_mpi_abort(' Restart file ' // trim(file_loc) // ' does not exist!' )
1374+ end if
1375+
1376+ nBodies = num_ibs
1377+
1378+ if (nBodies > 0) then
1379+ allocate (ib_data(nBodies, NFIELDS_PER_IB))
1380+ allocate (px(nBodies), py(nBodies), pz(nBodies))
1381+ allocate (force_x(nBodies), force_y(nBodies), force_z(nBodies))
1382+ allocate (torque_x(nBodies), torque_y(nBodies), torque_z(nBodies))
1383+ allocate (vel_x(nBodies), vel_y(nBodies), vel_z(nBodies))
1384+ allocate (omega_x(nBodies), omega_y(nBodies), omega_z(nBodies))
1385+ allocate (angle_x(nBodies), angle_y(nBodies), angle_z(nBodies))
1386+ allocate (ib_diameter(nBodies))
1387+
1388+ if (proc_rank == 0) then
1389+ open (newunit=file_unit, file=trim(file_loc), form=' unformatted' , access=' stream' , status=' old' , iostat=ios)
1390+ if (ios /= 0) call s_mpi_abort(' Cannot open IB state file: ' // trim(file_loc))
1391+
1392+ do i = 1, nBodies
1393+ read (file_unit, iostat=ios) ib_buf
1394+ if (ios /= 0) call s_mpi_abort(' Error reading IB state file' )
1395+ ib_data(i,:) = ib_buf(:)
1396+ end do
1397+
1398+ close (file_unit)
1399+ end if
1400+
1401+ call MPI_BCAST(ib_data, nBodies*NFIELDS_PER_IB, mpi_p, 0, MPI_COMM_WORLD, ierr)
1402+
1403+ do i = 1, nBodies
1404+ force_x(i) = ib_data(i, 2); force_y(i) = ib_data(i, 3); force_z(i) = ib_data(i, 4)
1405+ torque_x(i) = ib_data(i, 5); torque_y(i) = ib_data(i, 6); torque_z(i) = ib_data(i, 7)
1406+ vel_x(i) = ib_data(i, 8); vel_y(i) = ib_data(i, 9); vel_z(i) = ib_data(i, 10)
1407+ omega_x(i) = ib_data(i, 11); omega_y(i) = ib_data(i, 12); omega_z(i) = ib_data(i, 13)
1408+ angle_x(i) = ib_data(i, 14); angle_y(i) = ib_data(i, 15); angle_z(i) = ib_data(i, 16)
1409+ px(i) = ib_data(i, 17); py(i) = ib_data(i, 18); pz(i) = ib_data(i, 19)
1410+ ib_diameter(i) = ib_data(i, 20)*2.0_wp
1411+ end do
1412+
1413+ if (proc_rank == 0) then
1414+ do i = 1, num_procs
1415+ write (meshnames(i), ' (A,I0,A,I0,A)' ) ' ../ p' , i - 1, ' / ' , t_step, ' .silo:ib_bodies'
1416+ meshtypes(i) = DB_POINTMESH
1417+ end do
1418+ err = DBSET2DSTRLEN(len(meshnames(1)))
1419+ err = DBPUTMMESH(dbroot, ' ib_bodies' , 16, num_procs, meshnames, len_trim(meshnames), meshtypes, DB_F77NULL, ierr)
1420+ end if
1421+
1422+ err = DBPUTPM(dbfile, ' ib_bodies' , 9, 3, px, py, pz, nBodies, DB_DOUBLE, DB_F77NULL, ierr)
1423+
1424+ call s_write_ib_variable(' ib_force_x' , t_step, force_x, nBodies)
1425+ call s_write_ib_variable(' ib_force_y' , t_step, force_y, nBodies)
1426+ call s_write_ib_variable(' ib_force_z' , t_step, force_z, nBodies)
1427+ call s_write_ib_variable(' ib_torque_x' , t_step, torque_x, nBodies)
1428+ call s_write_ib_variable(' ib_torque_y' , t_step, torque_y, nBodies)
1429+ call s_write_ib_variable(' ib_torque_z' , t_step, torque_z, nBodies)
1430+ call s_write_ib_variable(' ib_vel_x' , t_step, vel_x, nBodies)
1431+ call s_write_ib_variable(' ib_vel_y' , t_step, vel_y, nBodies)
1432+ call s_write_ib_variable(' ib_vel_z' , t_step, vel_z, nBodies)
1433+ call s_write_ib_variable(' ib_omega_x' , t_step, omega_x, nBodies)
1434+ call s_write_ib_variable(' ib_omega_y' , t_step, omega_y, nBodies)
1435+ call s_write_ib_variable(' ib_omega_z' , t_step, omega_z, nBodies)
1436+ call s_write_ib_variable(' ib_angle_x' , t_step, angle_x, nBodies)
1437+ call s_write_ib_variable(' ib_angle_y' , t_step, angle_y, nBodies)
1438+ call s_write_ib_variable(' ib_angle_z' , t_step, angle_z, nBodies)
1439+ call s_write_ib_variable(' ib_diameter' , t_step, ib_diameter, nBodies)
1440+
1441+ deallocate (ib_data, px, py, pz, force_x, force_y, force_z)
1442+ deallocate (torque_x, torque_y, torque_z, vel_x, vel_y, vel_z)
1443+ deallocate (omega_x, omega_y, omega_z, angle_x, angle_y, angle_z)
1444+ deallocate (ib_diameter)
1445+ end if
1446+ #endif
1447+
1448+ end subroutine s_write_ib_bodies_to_formatted_database_file
1449+
1450+ !> Write a single IB point-variable to the Silo database slave and master files.
1451+ subroutine s_write_ib_variable(varname, t_step, data, nBodies)
1452+
1453+ character(len=*), intent(in) :: varname
1454+ integer, intent(in) :: t_step
1455+ real(wp), dimension(:), intent(in) :: data
1456+ integer, intent(in) :: nBodies
1457+ character(len=4*name_len), dimension(num_procs) :: var_names
1458+ integer, dimension(num_procs) :: var_types
1459+ integer :: ierr, i
1460+
1461+ if (proc_rank == 0) then
1462+ do i = 1, num_procs
1463+ write (var_names(i), ' (A,I0,A,I0,A)' ) ' ../ p' , i - 1, ' / ' , t_step, ' .silo:' // trim(varname)
1464+ var_types(i) = DB_POINTVAR
1465+ end do
1466+ err = DBSET2DSTRLEN(len(var_names(1)))
1467+ err = DBPUTMVAR(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, &
1468+ & DB_F77NULL, ierr)
1469+ end if
1470+
1471+ err = DBPUTPV1(dbfile, trim(varname), len_trim(varname), ' ib_bodies' , 9, data, nBodies, DB_DOUBLE, DB_F77NULL, ierr)
1472+
1473+ end subroutine s_write_ib_variable
1474+
13441475 !> Close the formatted database slave file and, for the root process, the master file.
13451476 impure subroutine s_close_formatted_database_file()
13461477
0 commit comments