build_particle_source_plan Subroutine

public subroutine build_particle_source_plan(cfg, plan, mpi_rank, mpi_size, mpi, kinetic_inflow_active, kinetic_reservoir_potential_v, kinetic_access_potential_v, kinetic_inflow_face, number_flux_override_active, number_flux_override_m2_s, kinetic_reservoir_density_m3)

設定とMPI配置だけに依存する粒子 source の導出値を構築する。 乱数、残差、mesh/snapshot依存の障壁は扱わず、run中に不変な値だけを保持する。

Arguments

Type IntentOptional Attributes Name
type(app_config), intent(in) :: cfg
type(particle_source_plan_type), intent(out) :: plan
integer(kind=i32), intent(in), optional :: mpi_rank
integer(kind=i32), intent(in), optional :: mpi_size
type(mpi_context), intent(in), optional :: mpi
logical, intent(in), optional :: kinetic_inflow_active(:)
real(kind=dp), intent(in), optional :: kinetic_reservoir_potential_v(:)
real(kind=dp), intent(in), optional :: kinetic_access_potential_v(:)
integer(kind=i32), intent(in), optional :: kinetic_inflow_face(:)
logical, intent(in), optional :: number_flux_override_active(:)
real(kind=dp), intent(in), optional :: number_flux_override_m2_s(:)
real(kind=dp), intent(in), optional :: kinetic_reservoir_density_m3(:)

流入写像の面だけで使う貯留部密度。0以下の要素は species 設定の密度を使う。


Calls

proc~~build_particle_source_plan~~CallsGraph proc~build_particle_source_plan build_particle_source_plan proc~apply_kinetic_map_arguments apply_kinetic_map_arguments proc~build_particle_source_plan->proc~apply_kinetic_map_arguments proc~apply_number_flux_override_arguments apply_number_flux_override_arguments proc~build_particle_source_plan->proc~apply_number_flux_override_arguments proc~has_boundary_inflow has_boundary_inflow proc~build_particle_source_plan->proc~has_boundary_inflow proc~lower_ascii lower_ascii proc~build_particle_source_plan->proc~lower_ascii proc~resolve_parallel_rank_size resolve_parallel_rank_size proc~build_particle_source_plan->proc~resolve_parallel_rank_size proc~species_config_path species_config_path proc~build_particle_source_plan->proc~species_config_path proc~species_number_density_m3 species_number_density_m3 proc~build_particle_source_plan->proc~species_number_density_m3 proc~species_temperature_k species_temperature_k proc~build_particle_source_plan->proc~species_temperature_k proc~mpi_get_rank_size mpi_get_rank_size proc~resolve_parallel_rank_size->proc~mpi_get_rank_size

Source Code

  subroutine build_particle_source_plan( &
    cfg, plan, mpi_rank, mpi_size, mpi, kinetic_inflow_active, kinetic_reservoir_potential_v, &
    kinetic_access_potential_v, kinetic_inflow_face, number_flux_override_active, number_flux_override_m2_s, &
    kinetic_reservoir_density_m3 &
    )
    type(app_config), intent(in) :: cfg
    type(particle_source_plan_type), intent(out) :: plan
    integer(i32), intent(in), optional :: mpi_rank, mpi_size
    type(mpi_context), intent(in), optional :: mpi
    logical, intent(in), optional :: kinetic_inflow_active(:)
    real(dp), intent(in), optional :: kinetic_reservoir_potential_v(:), kinetic_access_potential_v(:)
    integer(i32), intent(in), optional :: kinetic_inflow_face(:)
    logical, intent(in), optional :: number_flux_override_active(:)
    real(dp), intent(in), optional :: number_flux_override_m2_s(:)
    !> 流入写像の面だけで使う貯留部密度。0以下の要素は species 設定の密度を使う。
    real(dp), intent(in), optional :: kinetic_reservoir_density_m3(:)

    integer(i32) :: s, local_rank, n_ranks
    logical :: has_enabled_reservoir

    call resolve_parallel_rank_size(local_rank, n_ranks, mpi_rank, mpi_size, mpi, 'build_particle_source_plan')
    plan%nspecies = cfg%n_particle_species
    plan%mpi_rank = local_rank
    plan%mpi_size = n_ranks
    plan%mpi_argument_present = present(mpi)
    has_enabled_reservoir = .false.
    do s = 1, cfg%n_particle_species
      if (.not. cfg%particle_species(s)%enabled) cycle
      has_enabled_reservoir = has_enabled_reservoir .or. &
                              has_boundary_inflow(cfg%particle_species(s))
    end do
    plan%use_collective_reservoir_count = present(mpi) .and. has_enabled_reservoir

    allocate (plan%source_kind(cfg%n_particle_species))
    plan%source_kind = slot_kind_none
    allocate (plan%effective_density_m3(cfg%n_particle_species))
    allocate (plan%effective_particle_flux_m2_s(cfg%n_particle_species))
    allocate (plan%number_flux_override_active(cfg%n_particle_species))
    allocate (plan%effective_temperature_k(cfg%n_particle_species))
    allocate (plan%effective_drift_velocity(3, cfg%n_particle_species))
    allocate (plan%effective_weight(cfg%n_particle_species))
    allocate (plan%photo_emit_current_density(cfg%n_particle_species))
    allocate (plan%photo_normal_drift_speed(cfg%n_particle_species))
    allocate (plan%kinetic_inflow_active(cfg%n_particle_species))
    allocate (plan%kinetic_reservoir_potential_v(cfg%n_particle_species))
    allocate (plan%kinetic_access_potential_v(cfg%n_particle_species))
    allocate (plan%kinetic_reservoir_density_m3(cfg%n_particle_species))
    allocate (plan%kinetic_inflow_face(cfg%n_particle_species))
    plan%effective_density_m3 = 0.0_dp
    plan%effective_particle_flux_m2_s = 0.0_dp
    plan%number_flux_override_active = .false.
    plan%effective_temperature_k = 0.0_dp
    plan%effective_drift_velocity = 0.0_dp
    plan%effective_weight = 0.0_dp
    plan%photo_emit_current_density = 0.0_dp
    plan%photo_normal_drift_speed = 0.0_dp
    plan%kinetic_inflow_active = .false.
    plan%kinetic_reservoir_potential_v = 0.0_dp
    plan%kinetic_access_potential_v = 0.0_dp
    plan%kinetic_reservoir_density_m3 = 0.0_dp
    plan%kinetic_inflow_face = 0_i32

    ! Runtime callers hand over the closure's kinetic map and number-flux override; their shapes and values are
    ! checked here, while the TOML physics conditions belong to the parser preflight.
    call apply_kinetic_map_arguments( &
      plan, cfg%n_particle_species, kinetic_inflow_active, kinetic_reservoir_potential_v, kinetic_access_potential_v, &
      kinetic_inflow_face, kinetic_reservoir_density_m3 &
      )
    call apply_number_flux_override_arguments( &
      plan, cfg%n_particle_species, number_flux_override_active, number_flux_override_m2_s &
      )

    do s = 1, cfg%n_particle_species
      if (.not. cfg%particle_species(s)%enabled) cycle
      select case (trim(lower_ascii(cfg%particle_species(s)%source_mode)))
      case ('volume_seed')
        plan%source_kind(s) = slot_kind_volume
        plan%effective_weight(s) = cfg%particle_species(s)%w_particle
        plan%effective_temperature_k(s) = species_temperature_k(cfg%particle_species(s))
        plan%effective_drift_velocity(:, s) = cfg%particle_species(s)%drift_velocity
        if (has_boundary_inflow(cfg%particle_species(s))) then
          plan%effective_density_m3(s) = species_number_density_m3(cfg%particle_species(s))
        end if
      case ('photo_raycast')
        plan%source_kind(s) = slot_kind_photo_ray
        plan%photo_emit_current_density(s) = cfg%particle_species(s)%emit_current_density_a_m2
        plan%photo_normal_drift_speed(s) = cfg%particle_species(s)%normal_drift_speed
      case ('secondary_emission')
        continue
      case default
        error stop 'Unknown '//species_config_path(int(s))//'.source.mode.'
      end select
      if (plan%number_flux_override_active(s)) then
        plan%effective_particle_flux_m2_s(s) = number_flux_override_m2_s(s)
      end if
    end do

    plan%ready = .true.
  end subroutine build_particle_source_plan