apply_escape_reflect_periodic_event Subroutine

public subroutine apply_escape_reflect_periodic_event(cfg, event, x, v, alive, escaped, status, redistribution_uniform)

最初のbox eventへescape/reflect/redistributed-reflect/periodicを軸順序に依存せず適用する。

Arguments

Type IntentOptional Attributes Name
type(sim_config), intent(in) :: cfg
type(boundary_event_type), intent(in) :: event
real(kind=dp), intent(inout) :: x(3)
real(kind=dp), intent(inout) :: v(3)
logical, intent(inout) :: alive
logical, intent(out) :: escaped
integer(kind=i32), intent(out) :: status
real(kind=dp), intent(in), optional :: redistribution_uniform(3)

Called by

proc~~apply_escape_reflect_periodic_event~~CalledByGraph proc~apply_escape_reflect_periodic_event apply_escape_reflect_periodic_event proc~advance_particle_step advance_particle_step proc~advance_particle_step->proc~apply_escape_reflect_periodic_event proc~advance_particle_step_upper_panel_fourier advance_particle_step_upper_panel_fourier proc~advance_particle_step_upper_panel_fourier->proc~apply_escape_reflect_periodic_event proc~resolve_particle_boundary_candidate resolve_particle_boundary_candidate proc~resolve_particle_boundary_candidate->proc~apply_escape_reflect_periodic_event

Source Code

  subroutine apply_escape_reflect_periodic_event( &
    cfg, event, x, v, alive, escaped, status, redistribution_uniform &
    )
    type(sim_config), intent(in) :: cfg
    type(boundary_event_type), intent(in) :: event
    real(dp), intent(inout) :: x(3), v(3)
    logical, intent(inout) :: alive
    logical, intent(out) :: escaped
    integer(i32), intent(out) :: status
    real(dp), intent(in), optional :: redistribution_uniform(3)

    real(dp) :: x_work(3), v_work(3)
    integer(i32) :: axis, low_face, high_face, low_bc, high_bc
    logical :: alive_work, has_open, has_redistributed_reflect

    escaped = .false.
    status = boundary_event_ok
    if (.not. cfg%use_box .or. .not. valid_event_box(cfg)) then
      status = boundary_event_invalid_geometry
      return
    end if
    if (trim(cfg%open_boundary_model) /= 'escape') then
      status = boundary_event_invalid_geometry
      return
    end if
    if (.not. all(ieee_is_finite(x)) .or. .not. all(ieee_is_finite(v))) then
      status = boundary_event_invalid_geometry
      return
    end if
    if (.not. event%has_event) then
      if (event%face_mask /= 0_i32 .or. event%fraction /= 0.0_dp) status = boundary_event_invalid_geometry
      return
    end if
    if (.not. ieee_is_finite(event%fraction) .or. event%fraction < 0.0_dp .or. event%fraction > 1.0_dp) then
      status = boundary_event_invalid_geometry
      return
    end if
    if (event%face_mask <= 0_i32 .or. iand(event%face_mask, boundary_face_all) /= event%face_mask) then
      status = boundary_event_invalid_geometry
      return
    end if
    if (any(event%face_bc /= boundary_face_conditions(cfg))) then
      status = boundary_event_invalid_geometry
      return
    end if
    do axis = 1_i32, 3_i32
      low_face = 2_i32*axis - 1_i32
      high_face = 2_i32*axis
      if (btest(event%face_mask, low_face - 1_i32) .and. btest(event%face_mask, high_face - 1_i32)) then
        status = boundary_event_invalid_geometry
        return
      end if
    end do

    x_work = x
    v_work = v
    alive_work = alive
    has_open = .false.
    has_redistributed_reflect = .false.
    do axis = 1_i32, 3_i32
      low_face = 2_i32*axis - 1_i32
      high_face = 2_i32*axis
      low_bc = event%face_bc(low_face)
      high_bc = event%face_bc(high_face)
      if (btest(event%face_mask, low_face - 1_i32)) has_open = has_open .or. low_bc == bc_open
      if (btest(event%face_mask, high_face - 1_i32)) has_open = has_open .or. high_bc == bc_open
      if (btest(event%face_mask, low_face - 1_i32)) then
        has_redistributed_reflect = has_redistributed_reflect .or. low_bc == bc_redistributed_reflect
      end if
      if (btest(event%face_mask, high_face - 1_i32)) then
        has_redistributed_reflect = has_redistributed_reflect .or. high_bc == bc_redistributed_reflect
      end if
    end do
    if (has_redistributed_reflect .and. .not. has_open) then
      if (.not. present(redistribution_uniform)) then
        status = boundary_event_invalid_geometry
        return
      end if
      if (.not. valid_redistribution_uniform(redistribution_uniform)) then
        status = boundary_event_invalid_geometry
        return
      end if
    end if

    if (has_open) then
      alive_work = .false.
      escaped = .true.
    else
      do axis = 1_i32, 3_i32
        low_face = 2_i32*axis - 1_i32
        high_face = 2_i32*axis
        low_bc = event%face_bc(low_face)
        high_bc = event%face_bc(high_face)
        if (btest(event%face_mask, low_face - 1_i32)) then
          call apply_surviving_event_axis( &
            axis, low_bc, .false., cfg%box_min(axis), cfg%box_max(axis), x_work, v_work, status &
            )
        else if (btest(event%face_mask, high_face - 1_i32)) then
          call apply_surviving_event_axis( &
            axis, high_bc, .true., cfg%box_min(axis), cfg%box_max(axis), x_work, v_work, status &
            )
        end if
        if (status /= boundary_event_ok) return
      end do
      if (has_redistributed_reflect) then
        call redistribute_event_position(cfg, event%face_mask, redistribution_uniform, x_work)
      end if
    end if
    if (.not. all(ieee_is_finite(x_work)) .or. .not. all(ieee_is_finite(v_work))) then
      escaped = .false.
      status = boundary_event_invalid_geometry
      return
    end if

    x = x_work
    v = v_work
    alive = alive_work
  end subroutine apply_escape_reflect_periodic_event