compute_periodic_shift_bounds Subroutine

public subroutine compute_periodic_shift_bounds(mesh, p0, p1, axis, period_len, nmin, nmax, status)

線分 AABB と canonical mesh AABB の重なりから必要な image shift 範囲を決める。

Arguments

Type IntentOptional Attributes Name
type(mesh_type), intent(in) :: mesh
real(kind=dp), intent(in) :: p0(3)
real(kind=dp), intent(in) :: p1(3)
integer(kind=i32), intent(in) :: axis
real(kind=dp), intent(in) :: period_len
integer(kind=i32), intent(out) :: nmin
integer(kind=i32), intent(out) :: nmax
integer(kind=i32), intent(out), optional :: status

Called by

proc~~compute_periodic_shift_bounds~~CalledByGraph proc~compute_periodic_shift_bounds compute_periodic_shift_bounds proc~find_first_hit_periodic2 find_first_hit_periodic2 proc~find_first_hit_periodic2->proc~compute_periodic_shift_bounds proc~find_first_hit find_first_hit proc~find_first_hit->proc~find_first_hit_periodic2 proc~advance_particle_step advance_particle_step proc~advance_particle_step->proc~find_first_hit proc~advance_particle_step_upper_panel_fourier advance_particle_step_upper_panel_fourier proc~advance_particle_step_upper_panel_fourier->proc~find_first_hit proc~resolve_particle_boundary_candidate resolve_particle_boundary_candidate proc~resolve_particle_boundary_candidate->proc~find_first_hit proc~sample_photo_raycast_particles sample_photo_raycast_particles proc~sample_photo_raycast_particles->proc~find_first_hit

Source Code

  subroutine compute_periodic_shift_bounds(mesh, p0, p1, axis, period_len, nmin, nmax, status)
    type(mesh_type), intent(in) :: mesh
    real(dp), intent(in) :: p0(3), p1(3)
    integer(i32), intent(in) :: axis
    real(dp), intent(in) :: period_len
    integer(i32), intent(out) :: nmin, nmax
    integer(i32), intent(out), optional :: status

    integer(i32) :: query_status
    integer(i64) :: nmin_i64, nmax_i64, i32_min_i64, i32_max_i64
    real(dp) :: seg_min, seg_max, mesh_min, mesh_max, tol, lower_bound, upper_bound, i64_limit

    nmin = 0_i32
    nmax = -1_i32
    query_status = collision_query_ok
    seg_min = min(p0(axis), p1(axis))
    seg_max = max(p0(axis), p1(axis))
    mesh_min = mesh%grid_bb_min(axis)
    mesh_max = mesh%grid_bb_max(axis)
    tol = 1.0d-12*max(1.0d0, abs(seg_min), abs(seg_max), abs(mesh_min), abs(mesh_max), period_len)

    lower_bound = (seg_min - mesh_max - tol)/period_len
    upper_bound = (seg_max - mesh_min + tol)/period_len
    if (.not. ieee_is_finite(lower_bound) .or. .not. ieee_is_finite(upper_bound)) then
      call finalize_collision_query(collision_query_index_range, status)
      return
    end if

    i64_limit = real(huge(0_i64), dp)
    if (lower_bound <= -i64_limit .or. lower_bound >= i64_limit .or. &
        upper_bound <= -i64_limit .or. upper_bound >= i64_limit) then
      call finalize_collision_query(collision_query_index_range, status)
      return
    end if

    nmin_i64 = ceiling(lower_bound, kind=i64)
    nmax_i64 = floor(upper_bound, kind=i64)
    i32_max_i64 = int(huge(0_i32), i64)
    i32_min_i64 = -i32_max_i64 - 1_i64
    if (nmin_i64 < i32_min_i64 .or. nmin_i64 > i32_max_i64 .or. &
        nmax_i64 < i32_min_i64 .or. nmax_i64 > i32_max_i64) then
      call finalize_collision_query(collision_query_index_range, status)
      return
    end if

    nmin = int(nmin_i64, i32)
    nmax = int(nmax_i64, i32)
    call finalize_collision_query(query_status, status)
  end subroutine compute_periodic_shift_bounds