!> lint 済み設定の基本的な計算条件を確認し、時間と外部場を確定する。 submodule(bem_app_config_parser) bem_app_config_parser_preflight_sim implicit none contains module procedure validate_simulation_config integer :: axis character(len=6), parameter :: low_faces(3) = ['x_low ', 'y_low ', 'z_low '] character(len=6), parameter :: high_faces(3) = ['x_high', 'y_high', 'z_high'] if (cfg%sim%dt <= 0.0_dp) error stop 'particles.tracking.dt_s must be > 0.' if (cfg%sim%batch_count <= 0_i32) error stop 'run.batch_count must be > 0.' if (cfg%sim%max_step < 1_i32) error stop 'particles.tracking.max_steps_per_particle must be >= 1.' ! 再開は checkpoint を読み、新しい checkpoint と出力を output.dir へ書く前提なので、ファイル出力を止められない。 if (cfg%resume_output .and. .not. cfg%write_output) error stop 'run.restart requires output.enabled=true.' if (trim(cfg%sim%particle_distribution) /= 'static' .and. trim(cfg%sim%particle_distribution) /= 'shared') then error stop 'run.batch.particle_distribution must be "static" or "shared".' end if if (cfg%sim%particle_pool_chunk < 1_i32) error stop 'run.batch.particle_pool_chunk must be >= 1.' if (.not. ieee_is_finite(cfg%sim%substep_field_change_max) .or. cfg%sim%substep_field_change_max < 0.0_dp) then error stop 'particles.tracking.substep_field_change_max must be finite and >= 0.' end if if (cfg%sim%substep_max_halvings < 0_i32 .or. cfg%sim%substep_max_halvings > 16_i32) then error stop 'particles.tracking.substep_max_halvings must be between 0 and 16.' end if if (cfg%sim%step_growth_max < 1_i32 .or. cfg%sim%step_growth_max > 16_i32) then error stop 'particles.tracking.step_growth_max must be between 1 and 16.' end if if (.not. ieee_is_finite(cfg%sim%step_growth_energy_fraction) .or. cfg%sim%step_growth_energy_fraction <= 0.0_dp .or. & cfg%sim%step_growth_energy_fraction > 1.0_dp) then error stop 'particles.tracking.step_growth_energy_fraction must be in (0, 1].' end if ! Step growth reuses the sub-step criterion; without an explicit threshold use a conservative default. if (cfg%sim%step_growth .and. cfg%sim%substep_field_change_max <= 0.0_dp) cfg%sim%substep_field_change_max = 0.05_dp if (cfg%sim%q_floor <= 0.0_dp) error stop 'output.diagnostics.charge_floor_c must be > 0.' if (cfg%sim%use_box) then if (.not. all(ieee_is_finite(cfg%sim%box_min)) .or. .not. all(ieee_is_finite(cfg%sim%box_max)) .or. & any(cfg%sim%box_max <= cfg%sim%box_min)) then error stop '[domain] must resolve to finite bounds with positive dimensions.' end if else if (any(cfg%particle_boundary_low /= particle_bc_inherit) .or. & any(cfg%particle_boundary_high /= particle_bc_inherit)) then error stop '[particles.boundary] requires a finite [domain].' end if ! 周期軸の面は domain.periodic_axes が決める。粒子境界の上書きは面の意味を変えるので拒否する。 do axis = 1, 3 if (cfg%sim%bc_low(axis) /= bc_periodic) cycle if (cfg%particle_boundary_low(axis) /= particle_bc_inherit) then error stop 'particles.boundary.'//trim(low_faces(axis))//' cannot override a periodic domain face.' end if if (cfg%particle_boundary_high(axis) /= particle_bc_inherit) then error stop 'particles.boundary.'//trim(high_faces(axis))//' cannot override a periodic domain face.' end if end do if (cfg%n_particle_species <= 0_i32) error stop 'At least one [[particles.species]] entry is required.' if (cfg%sim%injection_face_phi_grid_n < 1_i32) error stop 'particles.reservoir.face_potential_grid_n must be >= 1.' call resolve_external_e_field(cfg) call resolve_batch_duration(cfg) ! 注入の macro 粒子数と位置の jitter はバッチごとにこの値を使う。 if (cfg%sim%batch_duration < 0.0_dp) error stop "run.batch.duration_s must be >= 0" end procedure validate_simulation_config end submodule bem_app_config_parser_preflight_sim