@@ -846,8 +846,8 @@ contains
846846 real (wp) :: dist_min, dist_proj, dist_v, dist_e, t
847847 real (wp) :: v1(1 :3 ), v2(1 :3 ), v3(1 :3 )
848848 real (wp) :: e0(1 :3 ), e1(1 :3 ), pv(1 :3 )
849- real (wp) :: n(1 :3 ), proj(1 :3 )
850- real (wp) :: d, ndot, denom
849+ real (wp) :: n(1 :3 ), proj(1 :3 ), normals( 1 : 3 ), norm_vec( 1 : 3 )
850+ real (wp) :: d, ndot, denom, norm_mag
851851 real (wp) :: u, v_bary, w
852852 real (wp) :: l00, l01, l11, l20, l21
853853 real (wp) :: edge(1 :3 ), pe(1 :3 )
@@ -897,8 +897,8 @@ contains
897897 ! If projection is inside triangle
898898 if (u >= 0._wp .and. v_bary >= 0._wp .and. w >= 0._wp ) then
899899 dist_proj = sqrt ((point(1 ) - proj(1 ))** 2 + &
900- (point(2 ) - proj(2 ))** 2 + &
901- (point(3 ) - proj(3 ))** 2 )
900+ (point(2 ) - proj(2 ))** 2 + &
901+ (point(3 ) - proj(3 ))** 2 )
902902
903903 if (dist_proj < dist_min) then
904904 dist_min = dist_proj
@@ -925,20 +925,35 @@ contains
925925
926926 if (dist_e < dist_min) then
927927 dist_min = dist_e
928- normals(:) = n(:)
928+ norm_vec(:) = point(:) - verts(:, j)
929+ norm_mag = sqrt (dot_product (norm_vec, norm_vec))
930+ if (norm_mag > 0._wp ) norm_vec = norm_vec / norm_mag
931+ normals(:) = norm_vec(:)
932+ end if
933+ else if (t < 0._wp ) then
934+ dist_v = sqrt ((point(1 ) - verts(1 , j))** 2 + &
935+ (point(2 ) - verts(2 , j))** 2 + &
936+ (point(3 ) - verts(3 , j))** 2 )
937+
938+ if (dist_v < dist_min) then
939+ dist_min = dist_v
940+ norm_vec(:) = point(:) - verts(:, j)
941+ norm_mag = sqrt (dot_product (norm_vec, norm_vec))
942+ if (norm_mag > 0._wp ) norm_vec = norm_vec / norm_mag
943+ normals(:) = norm_vec(:)
944+ end if
945+ else
946+ dist_v = sqrt ((point(1 ) - verts(1 , mod (j, 3 ) + 1 ))** 2 + &
947+ (point(2 ) - verts(2 , mod (j, 3 ) + 1 ))** 2 + &
948+ (point(3 ) - verts(3 , mod (j, 3 ) + 1 ))** 2 )
949+
950+ if (dist_v < dist_min) then
951+ dist_min = dist_v
952+ norm_vec(:) = point(:) - verts(:, mod (j, 3 ) + 1 )
953+ norm_mag = sqrt (dot_product (norm_vec, norm_vec))
954+ if (norm_mag > 0._wp ) norm_vec = norm_vec / norm_mag
955+ normals(:) = norm_vec(:)
929956 end if
930- end if
931- end do
932-
933- ! Check three vertices
934- do j = 1 , 3
935- dist_v = sqrt ((point(1 ) - verts(1 , j))** 2 + &
936- (point(2 ) - verts(2 , j))** 2 + &
937- (point(3 ) - verts(3 , j))** 2 )
938-
939- if (dist_v < dist_min) then
940- dist_min = dist_v
941- normals(:) = n(:)
942957 end if
943958 end do
944959 end if
@@ -967,12 +982,13 @@ contains
967982 real (wp), intent (out ) :: distance
968983
969984 integer :: i
970- real (wp) :: dist_min, dist, t
985+ real (wp) :: dist_min, dist, t, norm_mag
971986 real (wp) :: v1(1 :2 ), v2(1 :2 ), edge(1 :2 ), pv(1 :2 )
972- real (wp) :: edge_len_sq, proj(1 :2 )
987+ real (wp) :: edge_len_sq, proj(1 :2 ), norm( 1 : 2 ), c
973988
974989 dist_min = initial_distance_buffer
975990 normals = 0._wp
991+ norm = 0._wp
976992
977993 do i = 1 , boundary_edge_count
978994 ! Edge endpoints
@@ -998,16 +1014,26 @@ contains
9981014 if (t >= 0._wp .and. t <= 1._wp ) then
9991015 proj = v1 + t* edge
10001016 dist = sqrt ((point(1 ) - proj(1 ))** 2 + (point(2 ) - proj(2 ))** 2 )
1017+ norm(1 ) = boundary_v(i, 3 , 1 , pid)
1018+ norm(2 ) = boundary_v(i, 3 , 2 , pid)
10011019 else if (t < 0._wp ) then ! negative t means that v1 is the closest point on the edge
10021020 dist = sqrt ((point(1 ) - v1(1 ))** 2 + (point(2 ) - v1(2 ))** 2 )
1021+ norm(1 ) = point(1 ) - v1(1 )
1022+ norm(2 ) = point(2 ) - v1(2 )
1023+ norm_mag = sqrt (dot_product (norm, norm))
1024+ norm = norm / norm_mag
10031025 else ! t > 1 means that v2 is the closest point on the line edge
10041026 dist = sqrt ((point(1 ) - v2(1 ))** 2 + (point(2 ) - v2(2 ))** 2 )
1027+ norm(1 ) = point(1 ) - v2(1 )
1028+ norm(2 ) = point(2 ) - v2(2 )
1029+ norm_mag = sqrt (dot_product (norm, norm))
1030+ norm = norm / norm_mag
10051031 end if
10061032
10071033 if (dist < dist_min) then
10081034 dist_min = dist
1009- normals(1 ) = boundary_v(i, 3 , 1 , pid )
1010- normals(2 ) = boundary_v(i, 3 , 2 , pid )
1035+ normals(1 ) = norm( 1 )
1036+ normals(2 ) = norm( 2 )
10111037 end if
10121038 end do
10131039
0 commit comments