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