apply_ray_box_boundary Subroutine

public subroutine apply_ray_box_boundary(cfg, x, dir, alive)

photo raycast の ray が box 面を越えた点に反射・周期境界を適用する。粒子の境界処理は event API (find_first_boundary_event / apply_escape_reflect_periodic_event)が担い、これは ray 専用。 ray は面内再配置の乱数を持たないので、流出面と再配置反射の面では ray を止める(alive=.false.)。 box が無効なら何もせず、幅 0 の軸があれば ray を止める。

Arguments

Type IntentOptional Attributes Name
class(particle_domain_config), intent(in) :: cfg
real(kind=dp), intent(inout) :: x(3)
real(kind=dp), intent(inout) :: dir(3)
logical, intent(inout) :: alive

Called by

proc~~apply_ray_box_boundary~~CalledByGraph proc~apply_ray_box_boundary apply_ray_box_boundary proc~cast_photo_ray cast_photo_ray proc~cast_photo_ray->proc~apply_ray_box_boundary proc~sample_photo_ray_slot sample_photo_ray_slot proc~sample_photo_ray_slot->proc~cast_photo_ray

Source Code

  subroutine apply_ray_box_boundary(cfg, x, dir, alive)
    class(particle_domain_config), intent(in) :: cfg
    real(dp), intent(inout) :: x(3), dir(3)
    logical, intent(inout) :: alive

    real(dp), parameter :: eps = 1.0d-12
    integer(i32) :: axis
    real(dp) :: span

    if (.not. cfg%use_box) return
    if (.not. alive) return

    do axis = 1, 3
      span = cfg%box_max(axis) - cfg%box_min(axis)
      if (span <= 0.0_dp) then
        alive = .false.
        return
      end if

      do while (x(axis) < cfg%box_min(axis))
        call apply_ray_face(cfg%bc_low(axis))
        if ((.not. alive) .or. x(axis) >= cfg%box_min(axis)) exit
      end do
      if (.not. alive) return

      do while (x(axis) > cfg%box_max(axis))
        call apply_ray_face(cfg%bc_high(axis))
        if ((.not. alive) .or. x(axis) <= cfg%box_max(axis)) exit
      end do
      if (.not. alive) return
    end do

  contains

    subroutine apply_ray_face(bc)
      integer(i32), intent(in) :: bc

      select case (bc)
      case (bc_reflect)
        call reflect_one_side(axis, cfg%box_min(axis), cfg%box_max(axis), eps, x, dir)
      case (bc_periodic)
        x(axis) = modulo(x(axis) - cfg%box_min(axis), span) + cfg%box_min(axis)
        x(axis) = min(cfg%box_max(axis) - eps, max(cfg%box_min(axis) + eps, x(axis)))
      case default
        alive = .false.
      end select
    end subroutine apply_ray_face
  end subroutine apply_ray_box_boundary