bem_output_writer.f90 Source File


This file depends on

sourcefile~~bem_output_writer.f90~~EfferentGraph sourcefile~bem_output_writer.f90 bem_output_writer.f90 sourcefile~bem_app_config_types.f90 bem_app_config_types.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_app_config_types.f90 sourcefile~bem_charge_ledger.f90 bem_charge_ledger.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_charge_ledger.f90 sourcefile~bem_checkpoint_contract.f90 bem_checkpoint_contract.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_checkpoint_contract.f90 sourcefile~bem_electrostatic_snapshot.f90 bem_electrostatic_snapshot.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_electrostatic_snapshot.f90 sourcefile~bem_filesystem.f90 bem_filesystem.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_filesystem.f90 sourcefile~bem_kinds.f90 bem_kinds.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_kinds.f90 sourcefile~bem_types.f90 bem_types.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_types.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_types.f90 sourcefile~bem_physics_config_types.f90 bem_physics_config_types.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_charge_ledger.f90->sourcefile~bem_kinds.f90 sourcefile~bem_checkpoint_contract.f90->sourcefile~bem_filesystem.f90 sourcefile~bem_checkpoint_contract.f90->sourcefile~bem_kinds.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_kinds.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_types.f90 sourcefile~bem_constants.f90 bem_constants.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_constants.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90 bem_coulomb_fmm_periodic_nonzero_reference.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90 bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90 sourcefile~bem_field_solver.f90 bem_field_solver.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_field_solver.f90 sourcefile~bem_panel_geometry.f90 bem_panel_geometry.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_panel_kernel.f90 bem_panel_kernel.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_panel_kernel.f90 sourcefile~bem_periodic_zero_mode_eval.f90 bem_periodic_zero_mode_eval.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_periodic_zero_mode_eval.f90 sourcefile~bem_periodic_zero_mode_plan.f90 bem_periodic_zero_mode_plan.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_periodic_zero_mode_plan.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_string_utils.f90 bem_string_utils.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_constants.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90->sourcefile~bem_types.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90->sourcefile~bem_constants.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_triangle_quadrature.f90 bem_triangle_quadrature.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_reference.f90->sourcefile~bem_triangle_quadrature.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90->sourcefile~bem_types.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90->sourcefile~bem_constants.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_kinds.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_types.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_constants.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_coulomb_fmm_core.f90 bem_coulomb_fmm_core.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_coulomb_fmm_core.f90 sourcefile~bem_panel_geometry.f90->sourcefile~bem_kinds.f90 sourcefile~bem_panel_kernel.f90->sourcefile~bem_kinds.f90 sourcefile~bem_panel_kernel.f90->sourcefile~bem_constants.f90 sourcefile~bem_panel_kernel.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_panel_self_terms.f90 bem_panel_self_terms.f90 sourcefile~bem_panel_kernel.f90->sourcefile~bem_panel_self_terms.f90 sourcefile~bem_periodic_zero_mode_eval.f90->sourcefile~bem_kinds.f90 sourcefile~bem_periodic_zero_mode_eval.f90->sourcefile~bem_constants.f90 sourcefile~bem_periodic_zero_mode_eval.f90->sourcefile~bem_periodic_zero_mode_plan.f90 sourcefile~bem_periodic_zero_mode_plan.f90->sourcefile~bem_kinds.f90 sourcefile~bem_periodic_zero_mode_plan.f90->sourcefile~bem_types.f90 sourcefile~bem_periodic_zero_mode_plan.f90->sourcefile~bem_constants.f90 sourcefile~bem_physics_config_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_physics_config_types.f90->sourcefile~bem_types.f90 sourcefile~bem_physics_config_types.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_coulomb_fmm_core.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_types.f90 bem_coulomb_fmm_types.f90 sourcefile~bem_coulomb_fmm_core.f90->sourcefile~bem_coulomb_fmm_types.f90 sourcefile~bem_panel_self_terms.f90->sourcefile~bem_kinds.f90 sourcefile~bem_panel_self_terms.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_triangle_quadrature.f90->sourcefile~bem_kinds.f90 sourcefile~bem_triangle_quadrature.f90->sourcefile~bem_constants.f90 sourcefile~bem_triangle_quadrature.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_coulomb_fmm_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_types.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_coulomb_fmm_types.f90->sourcefile~bem_periodic_zero_mode_plan.f90

Files dependent on this one

sourcefile~~bem_output_writer.f90~~AfferentGraph sourcefile~bem_output_writer.f90 bem_output_writer.f90 sourcefile~bem_output_writer_files.f90 bem_output_writer_files.f90 sourcefile~bem_output_writer_files.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_output_writer_history.f90 bem_output_writer_history.f90 sourcefile~bem_output_writer_history.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_output_writer_summary.f90 bem_output_writer_summary.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_periodic_checkpoint.f90 bem_periodic_checkpoint.f90 sourcefile~bem_periodic_checkpoint.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_simulator.f90 bem_simulator.f90 sourcefile~bem_simulator.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_simulator_io.f90 bem_simulator_io.f90 sourcefile~bem_simulator_io.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_simulator_io.f90->sourcefile~bem_simulator.f90 sourcefile~main.f90 main.f90 sourcefile~main.f90->sourcefile~bem_output_writer.f90 sourcefile~main.f90->sourcefile~bem_periodic_checkpoint.f90 sourcefile~main.f90->sourcefile~bem_simulator.f90 sourcefile~bem_simulator_charge.f90 bem_simulator_charge.f90 sourcefile~bem_simulator_charge.f90->sourcefile~bem_simulator.f90 sourcefile~bem_simulator_loop.f90 bem_simulator_loop.f90 sourcefile~bem_simulator_loop.f90->sourcefile~bem_periodic_checkpoint.f90 sourcefile~bem_simulator_loop.f90->sourcefile~bem_simulator.f90 sourcefile~bem_simulator_particles.f90 bem_simulator_particles.f90 sourcefile~bem_simulator_particles.f90->sourcefile~bem_simulator.f90 sourcefile~bem_simulator_stats.f90 bem_simulator_stats.f90 sourcefile~bem_simulator_stats.f90->sourcefile~bem_simulator.f90

Source Code

!> 実行サマリ・最終CSV・履歴CSVの出力を担当するモジュール。
module bem_output_writer
  use bem_kinds, only: dp, i32
  use bem_types, only: mesh_type, sim_stats
  use bem_app_config_types, only: app_config
  use bem_charge_ledger, only: charge_ledger_type
  use bem_checkpoint_contract, only: begin_checkpoint_publish
  use bem_electrostatic_snapshot, only: electrostatic_diagnostics_type
  use bem_filesystem, only: &
    create_directories, &
    filesystem_empty_path, &
    filesystem_not_directory, &
    filesystem_os_error, &
    filesystem_success
  implicit none
  private

  public :: open_history_writer
  public :: open_potential_history_writer
  public :: open_top_reference_history_writer
  public :: open_matching_plane_history_writer
  public :: write_top_reference_history_snapshot
  public :: write_matching_plane_history_snapshot
  public :: print_run_summary
  public :: write_result_files
  public :: write_checkpoint_state_files
  public :: ensure_output_dir

  interface
    module subroutine open_history_writer(app, resumed, history_opened, history_unit)
      type(app_config), intent(in) :: app
      logical, intent(in) :: resumed
      logical, intent(out) :: history_opened
      integer, intent(out) :: history_unit
    end subroutine open_history_writer

    module subroutine open_potential_history_writer(app, resumed, potential_history_opened, potential_history_unit)
      type(app_config), intent(in) :: app
      logical, intent(in) :: resumed
      logical, intent(out) :: potential_history_opened
      integer, intent(out) :: potential_history_unit
    end subroutine open_potential_history_writer

    module subroutine open_top_reference_history_writer(app, resumed, history_opened, history_unit)
      type(app_config), intent(in) :: app
      logical, intent(in) :: resumed
      logical, intent(out) :: history_opened
      integer, intent(out) :: history_unit
    end subroutine open_top_reference_history_writer

    module subroutine write_top_reference_history_snapshot( &
      unit_id, batch_idx, simulated_time_s, z_high_m, sample_n, &
      potential_mean_v, potential_std_v, potential_min_v, potential_max_v &
      )
      integer, intent(in) :: unit_id
      integer(i32), intent(in) :: batch_idx, sample_n
      real(dp), intent(in) :: simulated_time_s, z_high_m
      real(dp), intent(in) :: potential_mean_v, potential_std_v, potential_min_v, potential_max_v
    end subroutine write_top_reference_history_snapshot

    module subroutine open_matching_plane_history_writer(app, resumed, history_opened, history_unit)
      type(app_config), intent(in) :: app
      logical, intent(in) :: resumed
      logical, intent(out) :: history_opened
      integer, intent(out) :: history_unit
    end subroutine open_matching_plane_history_writer

    module subroutine write_matching_plane_history_snapshot(unit_id, batch_idx, simulated_time_s, stats)
      integer, intent(in) :: unit_id
      integer(i32), intent(in) :: batch_idx
      real(dp), intent(in) :: simulated_time_s
      type(sim_stats), intent(in) :: stats
    end subroutine write_matching_plane_history_snapshot

    module subroutine write_summary_file( &
      out_dir, mesh, stats, cfg, mpi_world_size, charge_ledger, electrostatic_diagnostics &
      )
      character(len=*), intent(in) :: out_dir
      type(mesh_type), intent(in) :: mesh
      type(sim_stats), intent(in) :: stats
      type(app_config), intent(in) :: cfg
      integer(i32), intent(in), optional :: mpi_world_size
      type(charge_ledger_type), intent(in), optional :: charge_ledger
      type(electrostatic_diagnostics_type), intent(in), optional :: electrostatic_diagnostics
    end subroutine write_summary_file

    module pure real(dp) function soft_discard_fraction(stats) result(fraction)
      type(sim_stats), intent(in) :: stats
    end function soft_discard_fraction

    module integer(i32) function count_dielectric_surfaces(mesh) result(n)
      type(mesh_type), intent(in) :: mesh
    end function count_dielectric_surfaces

    module subroutine write_charge_ledger_file(out_dir, ledger)
      character(len=*), intent(in) :: out_dir
      type(charge_ledger_type), intent(in) :: ledger
    end subroutine write_charge_ledger_file

    module subroutine write_charges_file(out_dir, mesh)
      character(len=*), intent(in) :: out_dir
      type(mesh_type), intent(in) :: mesh
    end subroutine write_charges_file

    module subroutine write_mesh_potential_file(out_dir, mesh, potential_v)
      character(len=*), intent(in) :: out_dir
      type(mesh_type), intent(in) :: mesh
      real(dp), intent(in) :: potential_v(:)
    end subroutine write_mesh_potential_file

    module subroutine write_mesh_file(out_dir, mesh)
      character(len=*), intent(in) :: out_dir
      type(mesh_type), intent(in) :: mesh
    end subroutine write_mesh_file

    module subroutine write_mesh_sources_file(out_dir, mesh, cfg)
      character(len=*), intent(in) :: out_dir
      type(mesh_type), intent(in) :: mesh
      type(app_config), intent(in) :: cfg
    end subroutine write_mesh_sources_file
  end interface

contains

  !> 実行結果の主要統計を標準出力へ表示する。
  !! @param[in] mesh 実行後のメッシュ情報。
  !! @param[in] stats 実行後の統計値。
  subroutine print_run_summary(mesh, stats)
    type(mesh_type), intent(in) :: mesh
    type(sim_stats), intent(in) :: stats
    integer(i32) :: dielectric_count

    print '(a,i0)', 'mesh nelem=', mesh%nelem
    print '(a,i0)', 'processed_particles=', stats%processed_particles
    print '(a,i0)', 'absorbed=', stats%absorbed
    print '(a,i0)', 'escaped=', stats%escaped
    print '(a,i0)', 'batches=', stats%batches
    print '(a,i0)', 'escaped_boundary=', stats%escaped_boundary
    print '(a,i0)', 'survived_max_step=', stats%survived_max_step
    print '(a,i0)', 'multiple_box_events_retry_attempted=', stats%multiple_box_events_retry_attempted
    print '(a,i0)', 'multiple_box_events_retry_resolved=', stats%multiple_box_events_retry_resolved
    print '(a,i0)', 'multiple_box_events_soft_discarded=', stats%multiple_box_events_soft_discarded
    print '(a,es12.4)', 'multiple_box_events_soft_discard_fraction=', soft_discard_fraction(stats)
    print '(a,es12.4)', 'multiple_box_events_soft_discarded_abs_charge_C=', &
      stats%multiple_box_events_soft_discarded_abs_charge
    print '(a,es12.4)', 'last_rel_change=', stats%last_rel_change
    print '(a,es12.4)', 'simulated_time_s=', stats%simulated_time
    print '(a,i0)', 'adaptive_nonzero_mode_rejected_trials=', &
      stats%adaptive_nonzero_mode_rejected_trials
    print '(a,es12.4)', 'adaptive_nonzero_mode_last_batch_duration_s=', &
      stats%adaptive_nonzero_mode_last_batch_duration
    print '(a,es12.4)', 'adaptive_nonzero_mode_last_potential_step_V=', &
      stats%adaptive_nonzero_mode_last_potential_step
    print '(a,i0)', 'adaptive_nonzero_mode_omp_threads=', &
      stats%adaptive_nonzero_mode_omp_threads
    print '(a,l1)', 'matching_plane_state_valid=', stats%matching_plane_state_valid
    if (stats%matching_plane_state_valid) then
      print '(a,es12.4)', 'matching_plane_displacement_C_m2=', stats%matching_plane_displacement_c_m2
      print '(a,es12.4)', 'matching_plane_phi_V=', stats%matching_plane_phi_v
      print '(a,6(1x,es12.4))', 'matching_plane_response=', stats%matching_plane_response
      print '(a,4(1x,es12.4))', 'matching_plane_feedback=', stats%matching_plane_feedback
      print '(a,es12.4)', 'matching_plane_photoelectron_return_flux_m2_s=', &
        stats%matching_plane_photoelectron_return_flux_m2_s
      print '(a,es12.4)', 'matching_plane_photoelectron_escape_flux_m2_s=', &
        stats%matching_plane_photoelectron_escape_flux_m2_s
      print '(a,i0)', 'matching_plane_iterations=', stats%matching_plane_iterations
      print '(a,es12.4)', 'matching_plane_residual=', stats%matching_plane_residual
    end if
    print '(a,*(es12.4,1x))', 'mesh charges=', mesh%q_elem
    dielectric_count = count_dielectric_surfaces(mesh)
    if (dielectric_count > 0_i32) then
      print '(a,i0)', 'surface_model_dielectric_elem_count=', dielectric_count
      print '(a)', 'surface_model_note=dielectric surface models are metadata-only in this version.'
    end if
  end subroutine print_run_summary

  !> 解析結果を `summary.txt` / `charges.csv` / `mesh_triangles.csv` などとして保存する。
  !! @param[in] out_dir 出力先ディレクトリ。
  !! @param[in] mesh 書き出し対象のメッシュ。
  !! @param[in] stats 書き出し対象の統計値。
  !! @param[in] cfg 出力設定を含むアプリ設定。
  subroutine write_result_files( &
    out_dir, mesh, stats, cfg, mpi_world_size, mesh_potential_v, charge_ledger, electrostatic_diagnostics &
    )
    character(len=*), intent(in) :: out_dir
    type(mesh_type), intent(in) :: mesh
    type(sim_stats), intent(in) :: stats
    type(app_config), intent(in) :: cfg
    integer(i32), intent(in), optional :: mpi_world_size
    real(dp), intent(in), optional :: mesh_potential_v(:)
    type(charge_ledger_type), intent(in), optional :: charge_ledger
    type(electrostatic_diagnostics_type), intent(in), optional :: electrostatic_diagnostics
    call ensure_output_dir(out_dir)
    call begin_checkpoint_publish(out_dir)
    call write_summary_file( &
      out_dir, mesh, stats, cfg, mpi_world_size=mpi_world_size, charge_ledger=charge_ledger, &
      electrostatic_diagnostics=electrostatic_diagnostics &
      )
    call write_charges_file(out_dir, mesh)
    if (cfg%write_mesh_potential) then
      if (.not. present(mesh_potential_v)) then
        error stop 'write_result_files: mesh_potential_v is required when write_mesh_potential is enabled.'
      end if
      call write_mesh_potential_file(out_dir, mesh, mesh_potential_v)
    end if
    call write_mesh_file(out_dir, mesh)
    call write_mesh_sources_file(out_dir, mesh, cfg)
    if (present(charge_ledger)) call write_charge_ledger_file(out_dir, charge_ledger)
  end subroutine write_result_files

  !> 再開に必要な root-rank 共通状態だけをチェックポイントへ保存する。
  subroutine write_checkpoint_state_files(out_dir, mesh, stats, cfg, mpi_world_size, charge_ledger)
    character(len=*), intent(in) :: out_dir
    type(mesh_type), intent(in) :: mesh
    type(sim_stats), intent(in) :: stats
    type(app_config), intent(in) :: cfg
    integer(i32), intent(in), optional :: mpi_world_size
    type(charge_ledger_type), intent(in), optional :: charge_ledger

    call ensure_output_dir(out_dir)
    call begin_checkpoint_publish(out_dir)
    call write_summary_file( &
      out_dir, mesh, stats, cfg, mpi_world_size=mpi_world_size, charge_ledger=charge_ledger &
      )
    call write_charges_file(out_dir, mesh)
    if (present(charge_ledger)) call write_charge_ledger_file(out_dir, charge_ledger)
  end subroutine write_checkpoint_state_files

  !> 出力ディレクトリを作成する。
  !! @param[in] out_dir 作成対象ディレクトリのパス。
  subroutine ensure_output_dir(out_dir)
    character(len=*), intent(in) :: out_dir
    integer :: status

    call create_directories(out_dir, status)
    select case (status)
    case (filesystem_success)
      return
    case (filesystem_empty_path)
      error stop 'Failed to create output directory: output path is empty.'
    case (filesystem_not_directory)
      error stop 'Failed to create output directory: a path component is not an accessible directory.'
    case (filesystem_os_error)
      error stop 'Failed to create output directory: operating-system directory creation failed.'
    case default
      error stop 'Failed to create output directory: unexpected filesystem status.'
    end select
  end subroutine ensure_output_dir

end module bem_output_writer