bem_output_writer_summary.f90 Source File


This file depends on

sourcefile~~bem_output_writer_summary.f90~~EfferentGraph sourcefile~bem_output_writer_summary.f90 bem_output_writer_summary.f90 sourcefile~bem_charge_ledger.f90 bem_charge_ledger.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_charge_ledger.f90 sourcefile~bem_checkpoint_contract.f90 bem_checkpoint_contract.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_checkpoint_contract.f90 sourcefile~bem_external_boundary_contract.f90 bem_external_boundary_contract.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_external_boundary_contract.f90 sourcefile~bem_field_solver.f90 bem_field_solver.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_field_solver.f90 sourcefile~bem_filesystem.f90 bem_filesystem.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_filesystem.f90 sourcefile~bem_irradiation_cell_contract.f90 bem_irradiation_cell_contract.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_irradiation_cell_contract.f90 sourcefile~bem_matching_plane_summary.f90 bem_matching_plane_summary.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_matching_plane_summary.f90 sourcefile~bem_mesh_identity.f90 bem_mesh_identity.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_mesh_identity.f90 sourcefile~bem_output_writer.f90 bem_output_writer.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_output_writer.f90 sourcefile~bem_physics_config_types.f90 bem_physics_config_types.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_string_utils.f90 bem_string_utils.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_surface_current_model.f90 bem_surface_current_model.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_surface_current_model.f90 sourcefile~bem_types.f90 bem_types.f90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_types.f90 sourcefile~bem_version.f90 bem_version.F90 sourcefile~bem_output_writer_summary.f90->sourcefile~bem_version.f90 sourcefile~bem_kinds.f90 bem_kinds.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_external_boundary_contract.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_external_boundary_contract.f90->sourcefile~bem_kinds.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_types.f90 sourcefile~bem_constants.f90 bem_constants.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_constants.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_field_solver.f90->sourcefile~bem_kinds.f90 sourcefile~bem_mpi.f90 bem_mpi.F90 sourcefile~bem_field_solver.f90->sourcefile~bem_mpi.f90 sourcefile~bem_runtime_modes.f90 bem_runtime_modes.f90 sourcefile~bem_field_solver.f90->sourcefile~bem_runtime_modes.f90 sourcefile~bem_irradiation_cell_contract.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_irradiation_cell_contract.f90->sourcefile~bem_types.f90 sourcefile~bem_app_config_types.f90 bem_app_config_types.f90 sourcefile~bem_irradiation_cell_contract.f90->sourcefile~bem_app_config_types.f90 sourcefile~bem_irradiation_cell_contract.f90->sourcefile~bem_kinds.f90 sourcefile~bem_matching_plane_summary.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_matching_plane_summary.f90->sourcefile~bem_types.f90 sourcefile~bem_matching_plane_summary.f90->sourcefile~bem_kinds.f90 sourcefile~bem_mesh_identity.f90->sourcefile~bem_types.f90 sourcefile~bem_mesh_identity.f90->sourcefile~bem_kinds.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_charge_ledger.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_checkpoint_contract.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_filesystem.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_surface_current_model.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_types.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_app_config_types.f90 sourcefile~bem_electrostatic_snapshot.f90 bem_electrostatic_snapshot.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_electrostatic_snapshot.f90 sourcefile~bem_output_writer.f90->sourcefile~bem_kinds.f90 sourcefile~bem_physics_config_types.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_physics_config_types.f90->sourcefile~bem_types.f90 sourcefile~bem_physics_config_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_irradiation_cell_contract.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_app_config_types.f90 sourcefile~bem_config_helpers.f90 bem_config_helpers.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_config_helpers.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_constants.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_kinds.f90 sourcefile~bem_outflow_spectrum.f90 bem_outflow_spectrum.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_outflow_spectrum.f90 sourcefile~bem_surface_closure_contract.f90 bem_surface_closure_contract.f90 sourcefile~bem_surface_current_model.f90->sourcefile~bem_surface_closure_contract.f90 sourcefile~bem_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_types.f90->sourcefile~bem_outflow_spectrum.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_external_boundary_contract.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_filesystem.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_types.f90 sourcefile~bem_app_config_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_config_helpers.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_config_helpers.f90->sourcefile~bem_types.f90 sourcefile~bem_config_helpers.f90->sourcefile~bem_app_config_types.f90 sourcefile~bem_config_helpers.f90->sourcefile~bem_kinds.f90 sourcefile~bem_constants.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_core.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_core.f90->sourcefile~bem_mpi.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_electrostatic_snapshot.f90->sourcefile~bem_field_solver.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_physics_config_types.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_types.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_constants.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_kinds.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_mpi.f90 sourcefile~bem_electrostatic_snapshot.f90->sourcefile~bem_runtime_modes.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_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_mpi.f90->sourcefile~bem_kinds.f90 sourcefile~bem_outflow_spectrum.f90->sourcefile~bem_kinds.f90 sourcefile~bem_runtime_modes.f90->sourcefile~bem_string_utils.f90 sourcefile~bem_runtime_modes.f90->sourcefile~bem_kinds.f90 sourcefile~bem_surface_closure_contract.f90->sourcefile~bem_kinds.f90 sourcefile~bem_surface_closure_contract.f90->sourcefile~bem_runtime_modes.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_kinds.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_types.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90->sourcefile~bem_constants.f90 sourcefile~bem_coulomb_fmm_periodic_nonzero_upper_vacuum.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_types.f90->sourcefile~bem_kinds.f90 sourcefile~bem_coulomb_fmm_types.f90->sourcefile~bem_mpi.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 sourcefile~bem_periodic_shell_mean.f90 bem_periodic_shell_mean.f90 sourcefile~bem_coulomb_fmm_types.f90->sourcefile~bem_periodic_shell_mean.f90 sourcefile~bem_panel_geometry.f90->sourcefile~bem_kinds.f90 sourcefile~bem_panel_kernel.f90->sourcefile~bem_constants.f90 sourcefile~bem_panel_kernel.f90->sourcefile~bem_kinds.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_constants.f90 sourcefile~bem_periodic_zero_mode_eval.f90->sourcefile~bem_kinds.f90 sourcefile~bem_periodic_zero_mode_eval.f90->sourcefile~bem_periodic_zero_mode_plan.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_periodic_zero_mode_plan.f90->sourcefile~bem_kinds.f90 sourcefile~bem_sorting.f90 bem_sorting.f90 sourcefile~bem_periodic_zero_mode_plan.f90->sourcefile~bem_sorting.f90 sourcefile~bem_panel_self_terms.f90->sourcefile~bem_kinds.f90 sourcefile~bem_panel_self_terms.f90->sourcefile~bem_panel_geometry.f90 sourcefile~bem_periodic_shell_mean.f90->sourcefile~bem_kinds.f90 sourcefile~bem_sorting.f90->sourcefile~bem_kinds.f90 sourcefile~bem_triangle_quadrature.f90->sourcefile~bem_constants.f90 sourcefile~bem_triangle_quadrature.f90->sourcefile~bem_kinds.f90 sourcefile~bem_triangle_quadrature.f90->sourcefile~bem_panel_geometry.f90

Source Code

!> 実行サマリと再構築用メタデータの出力。
submodule(bem_output_writer) bem_output_writer_summary
  use bem_irradiation_cell_contract, only: &
    irradiation_cell_contract_type, resolve_irradiation_cell_contract, irradiation_cell_ok
  use bem_types, only: surface_model_dielectric
  use bem_charge_ledger, only: finite_charge_sum
  use bem_matching_plane_summary, only: write_matching_plane_summary
  use bem_checkpoint_contract, only: checkpoint_schema_version_current
  use bem_field_solver, only: &
    field_solver_fmm_expansion_order, &
    resolve_field_solver_mode, &
    resolve_field_solver_tree_params
  use bem_external_boundary_contract, only: &
    external_inflow_none, &
    external_inflow_scalar_barrier
  use bem_mesh_identity, only: mesh_fingerprint
  use bem_physics_config_types, only: field_physics_config, panel_kernel_config, derive_field_panel_config
  use bem_surface_current_model, only: surface_current_model_result_type, evaluate_surface_current_model
  use bem_version, only: beach_build_id, beach_source_commit, beach_version, beach_version_mode
  use bem_filesystem, only: default_periodic_cache_directory
  use bem_string_utils, only: lower_ascii
  implicit none
contains

  !> 実行統計を `summary.txt` に書き出す。
  !! @param[in] out_dir 出力先ディレクトリ。
  !! @param[in] mesh メッシュ情報(要素数を書き出す)。
  !! @param[in] stats 実行統計。
  module procedure write_summary_file
  type(irradiation_cell_contract_type) :: cell
  type(surface_current_model_result_type) :: current_model
  character(len=16) :: fingerprint
  logical :: use_identity
  type(field_physics_config) :: field_config
  type(panel_kernel_config) :: panel_config
  character(len=1024) :: summary_path
  character(len=256) :: periodic_cache_dir
  character(len=256) :: boundary_message
  character(len=16) :: resolved_field_solver
  integer :: u, ios, s
  integer(i32) :: world_size, boundary_status, resolved_tree_leaf_max
  real(dp) :: resolved_tree_theta

  call resolve_irradiation_cell_contract(cfg, cell, boundary_status, boundary_message)
  if (boundary_status /= irradiation_cell_ok) error stop trim(boundary_message)
  use_identity = .false.
  if (present(identity)) use_identity = identity%ready
  if (use_identity) then
    current_model = identity%initial_model
    fingerprint = identity%mesh_fingerprint
  else
    call evaluate_surface_current_model(cfg, current_model, cell)
    fingerprint = mesh_fingerprint(mesh)
  end if
  call derive_field_panel_config(cfg%sim, field_config, panel_config)
  call resolve_field_solver_tree_params( &
    mesh%nelem, cfg%sim, resolved_tree_theta, resolved_tree_leaf_max &
    )
  resolved_field_solver = resolve_field_solver_mode(mesh%nelem, cfg%sim)
  summary_path = trim(out_dir)//'/summary.txt'
  open (newunit=u, file=trim(summary_path), status='replace', action='write', iostat=ios)
  if (ios /= 0) error stop 'Failed to open summary file.'
  world_size = 1_i32
  if (present(mpi_world_size)) world_size = max(1_i32, mpi_world_size)
  write (u, '(a,i0)') 'checkpoint_schema_version=', checkpoint_schema_version_current
  write (u, '(a)') 'build_info_schema_version=1'
  write (u, '(a,a)') 'build_version=', beach_version
  write (u, '(a,a)') 'build_version_mode=', beach_version_mode
  write (u, '(a,a)') 'build_source_commit=', beach_source_commit
  write (u, '(a,a)') 'build_id=', beach_build_id
  write (u, '(a,a)') 'mesh_fingerprint=', fingerprint
  write (u, '(a,i0)') 'mesh_nelem=', mesh%nelem
  write (u, '(a,i0)') 'mesh_count=', max(1_i32, maxval(mesh%elem_mesh_id))
  write (u, '(a,i0)') 'mpi_world_size=', world_size
  write (u, '(a,i0)') 'processed_particles=', stats%processed_particles
  write (u, '(a,i0)') 'absorbed=', stats%absorbed
  write (u, '(a,i0)') 'escaped=', stats%escaped
  write (u, '(a,i0)') 'batches=', stats%batches
  write (u, '(a,i0)') 'checkpoint_stride=', cfg%checkpoint_stride
  write (u, '(a,i0)') 'escaped_boundary=', stats%escaped_boundary
  write (u, '(a,i0)') 'survived_max_step=', stats%survived_max_step
  write (u, '(a,i0)') 'multiple_box_events_retry_attempted=', stats%multiple_box_events_retry_attempted
  write (u, '(a,i0)') 'multiple_box_events_retry_resolved=', stats%multiple_box_events_retry_resolved
  write (u, '(a,i0)') 'adaptive_substep_halved_steps=', stats%adaptive_substep_halved_steps
  write (u, '(a,i0)') 'adaptive_substeps=', stats%adaptive_substeps
  write (u, '(a,i0)') 'adaptive_substep_depth_limited_steps=', stats%adaptive_substep_depth_limited_steps
  write (u, '(a,i0)') 'adaptive_grown_steps=', stats%adaptive_grown_steps
  write (u, '(a,i0)') 'adaptive_step_growth_max=', merge(cfg%sim%step_growth_max, 0_i32, cfg%sim%step_growth)
  write (u, '(a,a)') 'particle_distribution=', trim(cfg%sim%particle_distribution)
  write (u, '(a,i0)') 'particle_pool_claims=', stats%particle_pool_claims
  write (u, '(a,es24.16)') 'particle_pool_claim_seconds=', stats%particle_pool_claim_seconds
  write (u, '(a,i0)') 'multiple_box_events_soft_discarded=', stats%multiple_box_events_soft_discarded
  write (u, '(a,es24.16)') 'multiple_box_events_soft_discard_fraction=', soft_discard_fraction(stats)
  write (u, '(a,es24.16)') 'multiple_box_events_soft_discarded_abs_charge_C=', &
    stats%multiple_box_events_soft_discarded_abs_charge
  write (u, '(a,es24.16)') 'last_rel_change=', stats%last_rel_change
  write (u, '(a,es24.16)') 'simulated_time_s=', stats%simulated_time
  write (u, '(a,i0)') 'adaptive_nonzero_mode_rejected_trials=', &
    stats%adaptive_nonzero_mode%rejected_trials
  write (u, '(a,es24.16)') 'adaptive_nonzero_mode_last_batch_duration_s=', &
    stats%adaptive_nonzero_mode%last_batch_duration
  write (u, '(a,es24.16)') 'adaptive_nonzero_mode_last_potential_step_V=', &
    stats%adaptive_nonzero_mode%last_potential_step
  write (u, '(a,i0)') 'adaptive_nonzero_mode_omp_threads=', &
    stats%adaptive_nonzero_mode%omp_threads
  write (u, '(a,i0)') 'secondary_emission_hits=', stats%secondary_emission_hits
  write (u, '(a,i0)') 'secondary_emission_count=', stats%secondary_emission_count
  write (u, '(a,es24.16)') 'secondary_emitted_charge_C=', stats%secondary_emitted_charge_c
  write (u, '(a,es24.16)') 'secondary_yield_sum=', stats%secondary_yield_sum
  write (u, '(a,es24.16)') 'secondary_mean_yield=', &
    stats%secondary_yield_sum/real(max(1_i64, stats%secondary_emission_hits), dp)
  write (u, '(a,i0)') 'secondary_generation_capped_count=', stats%secondary_generation_capped_count
  write (u, '(a,i0)') 'secondary_emission_max_generations=', cfg%secondary_emission_max_generations
  do s = 1, cfg%n_particle_species
    if (.not. cfg%particle_species(s)%enabled .or. .not. cfg%particle_species(s)%secondary_emission_enabled) cycle
    write (u, '(a,i0,a,a)') 'secondary_incident_species_', s, '=', trim(cfg%particle_species(s)%species_key)
  end do
  call write_matching_plane_summary(u, stats%matching_plane)
  write (u, '(a)') 'particle_time_centering=same_time_midpoint_boris'
  write (u, '(a,a)') 'field_backend=', trim(field_config%backend)
  write (u, '(a,a)') 'field_normalization=', trim(field_config%normalization)
  write (u, '(a)') 'field_source_model=triangle_p0'
  write (u, '(a,a)') 'field_kernel_id=', trim(panel_config%kernel_id)
  write (u, '(a)') 'field_reconstruction_schema_version=2'
  write (u, '(a,a)') 'field_reconstruction_resolved_field_solver=', trim(resolved_field_solver)
  write (u, '(a,i0)') 'field_reconstruction_fmm_expansion_order=', field_solver_fmm_expansion_order
  write (u, '(a,a)') 'field_near_field_precision=', trim(cfg%sim%near_field_precision)
  write (u, '(a,a)') 'field_reconstruction_field_bc_mode=', trim(cfg%sim%field_bc_mode)
  write (u, '(a,es24.16)') 'field_reconstruction_tree_theta=', resolved_tree_theta
  write (u, '(a,i0)') 'field_reconstruction_tree_leaf_max=', resolved_tree_leaf_max
  write (u, '(a,3(1x,es24.16))') 'field_reconstruction_e0_V_m=', cfg%sim%e0
  write (u, '(a,l1)') 'field_reconstruction_use_box=', cfg%sim%use_box
  write (u, '(a,3(1x,es24.16))') 'field_reconstruction_box_min_m=', cfg%sim%box_min
  write (u, '(a,3(1x,es24.16))') 'field_reconstruction_box_max_m=', cfg%sim%box_max
  write (u, '(a,3(1x,i0))') 'field_reconstruction_boundary_low=', cfg%sim%bc_low
  write (u, '(a,3(1x,i0))') 'field_reconstruction_boundary_high=', cfg%sim%bc_high
  write (u, '(a,i0)') 'field_reconstruction_periodic_image_layers=', cfg%sim%field_periodic_image_layers
  write (u, '(a,a)') 'field_reconstruction_periodic_far_correction=', &
    trim(cfg%sim%field_periodic_far_correction)
  write (u, '(a,a)') 'field_reconstruction_periodic_nonzero_mode_backend=', &
    trim(cfg%periodic2%nonzero_mode_backend)
  write (u, '(a,a)') 'field_reconstruction_periodic_zero_mode_policy=', &
    trim(cfg%periodic2%zero_mode_policy)
  write (u, '(a,a)') 'field_reconstruction_periodic_lower_boundary_model=', &
    trim(cell%lower_boundary_model)
  write (u, '(a,i0)') 'field_reconstruction_periodic_reference_mode_layers=', &
    cfg%periodic2%reference_mode_layers
  write (u, '(a,i0)') 'field_reconstruction_periodic_panel_quadrature_order=', &
    cfg%periodic2%panel_quadrature_order
  write (u, '(a,es24.16)') 'field_reconstruction_periodic_ewald_alpha=', cfg%sim%field_periodic_ewald_alpha
  write (u, '(a,i0)') 'field_reconstruction_periodic_ewald_layers=', cfg%sim%field_periodic_ewald_layers
  periodic_cache_dir = cfg%sim%field_periodic_cache_dir
  if (len_trim(periodic_cache_dir) == 0) periodic_cache_dir = default_periodic_cache_directory(missing_ok=.true.)
  write (u, '(a,a)') 'field_reconstruction_periodic_cache_dir=', trim(periodic_cache_dir)
  write (u, '(a,es24.16)') 'field_reconstruction_periodic_generation_tolerance=', &
    cfg%sim%field_periodic_generation_tolerance
  write (u, '(a,a)') 'periodic2_nonzero_mode_backend=', trim(cfg%periodic2%nonzero_mode_backend)
  write (u, '(a,a)') 'periodic2_zero_mode_policy=', trim(cfg%periodic2%zero_mode_policy)
  write (u, '(a,a)') 'periodic2_lower_boundary_model=', trim(cell%lower_boundary_model)
  write (u, '(a,es24.16)') 'periodic2_max_nonzero_mode_potential_step_V=', &
    cfg%periodic2%max_nonzero_mode_potential_step
  write (u, '(a,a)') 'periodic2_cache_dir=', trim(periodic_cache_dir)
  write (u, '(a,es24.16)') 'periodic2_generation_tolerance=', &
    cfg%sim%field_periodic_generation_tolerance
  write (u, '(a,a)') 'reservoir_inflow_map=', trim(external_inflow_map_name(cfg%boundary_contract%inflow_map))
  write (u, '(a,a)') 'surface_current_model=', trim(current_model%model)
  write (u, '(a,es24.16)') 'surface_current_model_top_field_V_m=', stats%matching_plane%top_field_v_m
  if (current_model%active) then
    write (u, '(a,a)') 'surface_current_model_kinetic_contract=', trim(current_model%kinetic_contract)
    write (u, '(a,a)') 'surface_current_model_zhao_branch=', current_model%zhao_branch
    write (u, '(a,i0)') 'surface_current_model_outflow_refresh_batches=', &
      cfg%surface_current%outflow_refresh_batches
    if (cfg%surface_current%outflow_refresh_batches > 0_i32) then
      write (u, '(a)') 'surface_current_model_dynamic_state_source=matching_plane_state_outflow_refresh'
    else
      write (u, '(a)') 'surface_current_model_dynamic_state_source=initial_root'
    end if
    if (current_model%outer_return_cell_uniform) then
      write (u, '(a)') 'surface_current_model_outer_return_position=cell_uniform'
    else
      write (u, '(a)') 'surface_current_model_outer_return_position=crossing_point'
    end if
    write (u, '(a,l1)') 'surface_current_model_photoelectron_active=', current_model%photoelectron_active
    write (u, '(a,es24.16)') 'surface_current_model_reference_area_m2=', current_model%reference_area_m2
    write (u, '(a,es24.16)') 'surface_current_model_phi0_V=', current_model%phi0_v
    write (u, '(a,es24.16)') 'surface_current_model_phi_m_V=', current_model%phi_m_v
    write (u, '(a,es24.16)') 'surface_current_model_upstream_negative_band_V=', current_model%upstream_negative_band_v
    write (u, '(a,es24.16)') 'surface_current_model_upstream_field_deficit_V_m=', current_model%upstream_field_deficit_v_m
    write (u, '(a,es24.16)') 'surface_current_model_ambient_electron_density_m3=', &
      current_model%ambient_electron_density_m3
    write (u, '(a,es24.16)') 'surface_current_model_electron_current_density_A_m2=', &
      current_model%electron_current_density_a_m2
    write (u, '(a,es24.16)') 'surface_current_model_ion_current_density_A_m2=', &
      current_model%ion_current_density_a_m2
    write (u, '(a,es24.16)') 'surface_current_model_pe_emission_current_density_A_m2=', &
      current_model%photoelectron_emission_current_density_a_m2
    write (u, '(a,es24.16)') 'surface_current_model_pe_escape_current_density_A_m2=', &
      current_model%photoelectron_escape_current_density_a_m2
    write (u, '(a,es24.16)') 'surface_current_model_pe_return_current_density_A_m2=', &
      current_model%photoelectron_return_current_density_a_m2
    write (u, '(a,es24.16)') 'surface_current_model_net_current_density_A_m2=', &
      current_model%net_current_density_a_m2
    write (u, '(a)') 'surface_current_model_current_budget_contract=surface_targets_plus_external_escape'
    write (u, '(a,es24.16)') 'surface_current_model_pe_budget_residual_current_density_A_m2=', &
      current_model%photoelectron_budget_residual_current_density_a_m2
    write (u, '(a,es24.16)') 'surface_current_model_surface_budget_residual_current_density_A_m2=', &
      current_model%surface_budget_residual_current_density_a_m2
    if (current_model%photoelectron_active) then
      write (u, '(a,es24.16)') 'surface_current_model_pe_escape_particle_current_A=', &
        current_model%escaped_particle_current_a(current_model%photoelectron_species_idx)
    else
      write (u, '(a,es24.16)') 'surface_current_model_pe_escape_particle_current_A=', 0.0_dp
    end if
    write (u, '(a,es24.16)') 'surface_current_model_electron_inflow_reservoir_potential_V=', &
      current_model%inflow_reservoir_potential_v(current_model%electron_species_idx)
    write (u, '(a,es24.16)') 'surface_current_model_electron_inflow_access_potential_V=', &
      current_model%inflow_access_potential_v(current_model%electron_species_idx)
    write (u, '(a,i0)') 'surface_current_model_electron_inflow_face=', &
      current_model%inflow_kinetic_face(current_model%electron_species_idx)
    if (current_model%photoelectron_active) then
      write (u, '(a,es24.16)') 'surface_current_model_pe_outflow_barrier_potential_V=', &
        current_model%outflow_barrier_potential_v(current_model%photoelectron_species_idx)
      write (u, '(a,i0)') 'surface_current_model_pe_outflow_barrier_face=', &
        current_model%outflow_barrier_face(current_model%photoelectron_species_idx)
    else
      write (u, '(a,es24.16)') 'surface_current_model_pe_outflow_barrier_potential_V=', 0.0_dp
      write (u, '(a,i0)') 'surface_current_model_pe_outflow_barrier_face=', 0_i32
    end if
  end if
  if (present(electrostatic_diagnostics)) then
    write (u, '(a,l1)') 'upper_fourier_switch_active=', electrostatic_diagnostics%upper_fourier_switch_active
    write (u, '(a,es24.16)') 'upper_fourier_switch_height_m=', electrostatic_diagnostics%upper_fourier_switch_height_m
    write (u, '(a,i0)') 'upper_fourier_switch_mode_layers=', electrostatic_diagnostics%upper_fourier_switch_mode_layers
    write (u, '(a,es24.16)') 'upper_fourier_switch_selected_mismatch_V=', &
      electrostatic_diagnostics%upper_fourier_switch_selected_mismatch_v
    write (u, '(a,l1)') 'field_reconstruction_upper_fourier_switch_active=', &
      electrostatic_diagnostics%upper_fourier_switch_active
    write (u, '(a,es24.16)') 'field_reconstruction_upper_fourier_switch_height_m=', &
      electrostatic_diagnostics%upper_fourier_switch_height_m
    write (u, '(a,i0)') 'field_reconstruction_upper_fourier_switch_mode_layers=', &
      electrostatic_diagnostics%upper_fourier_switch_mode_layers
    write (u, '(a,es24.16)') 'periodic2_lower_boundary_field_V_m=', electrostatic_diagnostics%lower_boundary_field_v_m
    write (u, '(a,l1)') 'top_reference_available=', electrostatic_diagnostics%top_reference_available
    if (electrostatic_diagnostics%top_reference_available) then
      write (u, '(a)') 'top_reference_definition=box_z_high_plane_mean'
      write (u, '(a,i0)') 'top_reference_last_batch=', electrostatic_diagnostics%top_reference_last_batch
      write (u, '(a,es24.16)') 'top_reference_simulated_time_s=', electrostatic_diagnostics%top_reference_simulated_time
      write (u, '(a,es24.16)') 'top_reference_z_high_m=', electrostatic_diagnostics%top_reference_z_high
      write (u, '(a,i0)') 'top_reference_sample_n=', electrostatic_diagnostics%top_reference_sample_n
      write (u, '(a,es24.16)') 'top_reference_potential_mean_V=', electrostatic_diagnostics%top_reference_potential_mean
      write (u, '(a,es24.16)') 'top_reference_potential_std_V=', electrostatic_diagnostics%top_reference_potential_std
      write (u, '(a,es24.16)') 'top_reference_potential_min_V=', electrostatic_diagnostics%top_reference_potential_min
      write (u, '(a,es24.16)') 'top_reference_potential_max_V=', electrostatic_diagnostics%top_reference_potential_max
    end if
    write (u, '(a,l1)') 'electrostatic_split_periodic_active=', electrostatic_diagnostics%split_periodic_active
    write (u, '(a,a)') 'electrostatic_status=', trim(electrostatic_diagnostics%status)
    write (u, '(a,es24.16)') 'gauss_residual_C=', electrostatic_diagnostics%gauss_residual
    write (u, '(a,l1)') 'periodic2_cache_hit=', electrostatic_diagnostics%periodic_cache_hit
    write (u, '(a,i0)') 'periodic2_operator_build_count=', electrostatic_diagnostics%periodic_operator_build_count
    write (u, '(a,a)') 'periodic2_cache_fingerprint=', trim(electrostatic_diagnostics%periodic_cache_fingerprint)
    write (u, '(a,a)') 'periodic2_cache_path=', trim(electrostatic_diagnostics%periodic_cache_path)
  end if
  if (present(charge_ledger)) then
    write (u, '(a,i0)') 'charge_ledger_nspecies=', charge_ledger%nspecies
    write (u, '(a,i0)') 'charge_ledger_batch_count=', charge_ledger%batch_count
    write (u, '(a,es24.16)') 'charge_ledger_surface_charge_before_C=', charge_ledger%surface_charge_before
    write (u, '(a,es24.16)') 'charge_ledger_surface_charge_after_C=', charge_ledger%surface_charge_after
    write (u, '(a,es24.16)') 'charge_ledger_local_flight_charge_before_C=', &
      charge_ledger%local_flight_charge_before
    write (u, '(a,es24.16)') 'charge_ledger_local_flight_charge_after_C=', &
      charge_ledger%local_flight_charge_after
    write (u, '(a,es24.16)') 'charge_ledger_unresolved_stock_before_C=', &
      charge_ledger%unresolved_stock_before
    write (u, '(a,es24.16)') 'charge_ledger_unresolved_stock_after_C=', &
      charge_ledger%unresolved_stock_after
    write (u, '(a,es24.16)') 'charge_ledger_residual_C=', charge_ledger%residual()
    write (u, '(a,es24.16)') 'charge_ledger_discarded_unresolved_abs_C=', &
      charge_ledger%discarded_unresolved_abs()
    write (u, '(a,es24.16)') 'charge_ledger_neutral_return_correction_C=', &
      finite_charge_sum(charge_ledger%neutral_return_correction, 'summary neutral-return correction')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_current_correction_C=', &
      finite_charge_sum(charge_ledger%fixed_current_correction, 'summary fixed-current correction')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_absorbed_applied_charge_C=', &
      finite_charge_sum(charge_ledger%fixed_absorbed_target_charge, 'summary fixed absorbed applied charge')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_emission_applied_charge_C=', &
      finite_charge_sum(charge_ledger%fixed_emission_target_charge, 'summary fixed emission applied charge')
    write (u, '(a,es24.16)') 'charge_ledger_raw_escape_charge_C=', &
      finite_charge_sum(charge_ledger%escaped_to_infinity, 'summary raw escape charge')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_escape_target_charge_C=', &
      finite_charge_sum(charge_ledger%fixed_escape_target_charge, 'summary fixed escape target charge')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_escape_applied_charge_C=', &
      finite_charge_sum(charge_ledger%fixed_escape_target_charge, 'summary fixed escape applied charge')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_escape_correction_C=', &
      finite_charge_sum(charge_ledger%fixed_escape_correction, 'summary fixed escape correction')
    write (u, '(a,es24.16)') 'charge_ledger_fixed_applied_surface_net_charge_C=', &
      finite_charge_sum( &
      [charge_ledger%fixed_absorbed_target_charge, charge_ledger%fixed_emission_target_charge], &
      'summary fixed applied surface net charge' &
      )
    if (current_model%active .and. current_model%photoelectron_active) then
      write (u, '(a,es24.16)') 'charge_ledger_fixed_pe_continuity_residual_C=', &
        finite_charge_sum( &
        [ &
        charge_ledger%fixed_absorbed_target_charge(current_model%photoelectron_species_idx), &
        charge_ledger%fixed_emission_target_charge(current_model%photoelectron_species_idx), &
        charge_ledger%fixed_escape_target_charge(current_model%photoelectron_species_idx) &
        ], &
        'summary fixed photoelectron continuity residual' &
        )
    end if
  end if
  if (count_dielectric_surfaces(mesh) > 0_i32) then
    write (u, '(a,i0)') 'surface_model_dielectric_elem_count=', count_dielectric_surfaces(mesh)
    write (u, '(a)') 'surface_model_note=metadata_only_dielectric_present'
  end if
  close (u)
  end procedure write_summary_file

  !> 解決済みの流入モデルを summary 用の安定した語彙へ変換する。
  function external_inflow_map_name(inflow_map) result(name)
    integer(i32), intent(in) :: inflow_map
    character(len=32) :: name

    select case (inflow_map)
    case (external_inflow_none)
      name = 'source_vdf'
    case (external_inflow_scalar_barrier)
      name = 'infinity_barrier'
    case default
      error stop 'write_summary_file: unknown resolved external inflow map.'
    end select
  end function external_inflow_map_name

  !> 処理済みmacro particleに対する累積soft-discard率を返す。
  module procedure soft_discard_fraction

  fraction = 0.0_dp
  if (stats%processed_particles <= 0) return
  fraction = real(stats%multiple_box_events_soft_discarded, dp)/real(stats%processed_particles, dp)
  end procedure soft_discard_fraction

  !> 現行物理モデルで未分岐の dielectric 要素数を数える。
  module procedure count_dielectric_surfaces

  n = 0_i32
  if (.not. allocated(mesh%elem_surface_model)) return
  n = int(count(mesh%elem_surface_model == surface_model_dielectric), kind=i32)
  end procedure count_dielectric_surfaces

end submodule bem_output_writer_summary