94    type(
field_t), 
intent(inout) :: field_data
 
   96    real(kind=
dp), 
intent(in) :: max_distance
 
  101    real(kind=
dp), 
dimension(3) :: p
 
  102    real(kind=
dp) :: distance
 
  105    field_data%x = 0.0_dp
 
  106    total_size = field_data%dof%size()
 
  108    call search_tree%init(
mesh%nelv)
 
  109    call search_tree%build(
mesh%el)
 
  111    if (search_tree%get_size() .ne. 
mesh%nelv) 
then 
  112       call neko_error(
"signed_distance_field_tri_mesh: & 
  113       & Error building the search tree.")
 
  116    do id = 1, total_size
 
  117       p(1) = field_data%dof%x(id, 1, 1, 1)
 
  118       p(2) = field_data%dof%y(id, 1, 1, 1)
 
  119       p(3) = field_data%dof%z(id, 1, 1, 1)
 
  123       field_data%x(id, 1, 1, 1) = 
real(distance, kind=
rp)
 
  128       & Device version not implemented.")
 
  129       call device_memcpy(field_data%x, field_data%x_d, field_data%size(), &
 
 
  153    real(kind=
dp), 
intent(in) :: p(3)
 
  154    real(kind=
dp), 
intent(in) :: max_distance
 
  157    real(kind=
dp) :: distance, weighted_sign
 
  158    real(kind=
dp) :: cd, cs
 
  159    real(kind=
dp) :: tol = 1e-6_dp
 
  162    weighted_sign = 0.0_dp
 
  168       if (abs(cd - distance) / distance .lt. tol) 
then 
  169          weighted_sign = weighted_sign + cs
 
  170       else if (cd .lt. distance) 
then 
  174       distance = min(cd, distance)
 
  177    distance = sign(min(distance, max_distance), weighted_sign)
 
 
  201    class(tri_t), 
contiguous, 
dimension(:), 
intent(in) :: object_list
 
  202    real(kind=dp), 
dimension(3), 
intent(in) :: p
 
  203    real(kind=dp), 
intent(in) :: max_distance
 
  205    real(kind=dp) :: distance
 
  206    real(kind=dp) :: weighted_sign
 
  208    real(kind=dp), 
parameter :: tol = 1.0e-6_dp
 
  211    integer :: current_index
 
  214    type(
aabb_t) :: current_aabb
 
  215    integer :: current_object_index
 
  216    real(kind=dp) :: current_distance
 
  217    real(kind=dp) :: current_sign
 
  223    type(
aabb_t) :: search_box
 
  225    integer :: root_index, left_index, right_index
 
  226    real(kind=dp) :: random_value
 
  229    call simple_stack%init(
size(object_list) * 2)
 
  230    call search_box%init(p - max_distance, p + max_distance)
 
  234    root_index = tree%get_root_index()
 
  235    root_box = tree%get_aabb(root_index)
 
  237    if (.not. root_box%overlaps(search_box)) 
then 
  238       distance = max_distance
 
  239       weighted_sign = 1.0_dp
 
  244    call random_number(random_value)
 
  245    current_object_index = floor(random_value * 
size(object_list) + 1)
 
  246    call element_distance(object_list(current_object_index), p, distance, weighted_sign)
 
  247    distance = distance + object_list(current_object_index)%diameter()
 
  250    call search_box%init(p - distance, p + distance)
 
  251    call simple_stack%push(root_index)
 
  254    do while (.not. simple_stack%is_empty())
 
  255       current_index = simple_stack%pop()
 
  258       current_node = tree%get_node(current_index)
 
  259       current_aabb = current_node%get_aabb()
 
  261       if (current_node%is_leaf()) 
then 
  262          if (distance .lt. current_node%min_distance(p)) 
then 
  266          current_object_index = current_node%get_object_index()
 
  267          call element_distance(object_list(current_object_index), p, current_distance, current_sign)
 
  270          if (abs(current_distance - distance) / distance .lt. tol) 
then 
  271             weighted_sign = weighted_sign + current_sign
 
  272          else if (current_distance .lt. distance) 
then 
  273             weighted_sign = current_sign
 
  276          distance = min(distance, current_distance)
 
  279          if (distance .gt. current_aabb%get_diameter()) 
then 
  280             call search_box%init(p - distance, p + distance)
 
  284          left_index = tree%get_left_index(current_index)
 
  286             left_node = tree%get_left_node(current_index)
 
  287             if (left_node%aabb%overlaps(search_box)) 
then 
  288                call simple_stack%push(left_index)
 
  292          right_index = tree%get_right_index(current_index)
 
  294             right_node = tree%get_right_node(current_index)
 
  295             if (right_node%aabb%overlaps(search_box)) 
then 
  296                call simple_stack%push(right_index)
 
  302    if (distance .gt. max_distance) 
then 
  303       distance = max_distance
 
  305    distance = sign(distance, weighted_sign)
 
 
  351    type(tri_t), 
intent(in) :: triangle
 
  352    real(kind=dp), 
dimension(3), 
intent(in) :: p
 
  354    real(kind=dp), 
intent(out) :: distance
 
  355    real(kind=dp), 
intent(out), 
optional :: weighted_sign
 
  357    real(kind=dp), 
dimension(3) :: v1, v2, v3
 
  358    real(kind=dp), 
dimension(3) :: normal
 
  359    real(kind=dp) :: normal_length
 
  360    real(kind=dp) :: b1, b2, b3
 
  363    real(kind=dp), 
dimension(3) :: edge
 
  364    real(kind=dp) :: tol = 1e-10_dp
 
  366    real(kind=dp) :: face_distance
 
  370    v1 = triangle%pts(1)%p%x
 
  371    v2 = triangle%pts(2)%p%x
 
  372    v3 = triangle%pts(3)%p%x
 
  374    normal = 
cross(v2 - v1, v3 - v1)
 
  375    normal_length = norm2(normal)
 
  377    if (normal_length .lt. tol) 
then 
  378       distance = huge(1.0_dp)
 
  379       weighted_sign = 0.0_dp
 
  382    normal = normal / normal_length
 
  386    face_distance = dot_product(p - v1, normal)
 
  389    b1 = dot_product(normal, 
cross(v2 - v1, 
projection - v1)) / normal_length
 
  390    b2 = dot_product(normal, 
cross(v3 - v2, 
projection - v2)) / normal_length
 
  391    b3 = dot_product(normal, 
cross(v1 - v3, 
projection - v3)) / normal_length
 
  393    if (b1 .le. tol) 
then 
  395       t = dot_product(p - v1, edge) / norm2(edge)
 
  396       t = 
max(0.0_dp, min(1.0_dp, t))
 
  399    else if (b2 .le. tol) 
then 
  401       t = dot_product(p - v2, edge) / norm2(edge)
 
  402       t = 
max(0.0_dp, min(1.0_dp, t))
 
  405    else if (b3 .le. tol) 
then 
  407       t = dot_product(p - v3, edge) / norm2(edge)
 
  408       t = 
max(0.0_dp, min(1.0_dp, t))
 
  414    if (
present(weighted_sign)) 
then 
  415       weighted_sign = face_distance / distance
 
  417       distance = sign(distance, face_distance)