778 type(
t_model),
intent(in) :: model
779 real(wp),
dimension(1:3),
intent(in) :: point
780 real(wp),
dimension(1:3),
intent(in) :: spacing
781 integer,
intent(in) :: spc
786 integer :: i,
j, ninorout, nhits
788 real(wp),
dimension(1:spc, 1:3) :: ray_origins, ray_dirs
800 call random_number(ray_origins(i, :))
801 ray_origins(i, :) = point + (ray_origins(i, :) - 0.5_wp)*spacing(:)
803 call random_number(ray_dirs(i, :))
804 ray_dirs(i, :) = ray_dirs(i, :) - 0.5_wp
805 ray_dirs(i, :) = ray_dirs(i, :)/sqrt(sum(ray_dirs(i, :)*ray_dirs(i, :)))
810 ray%o = ray_origins(i, :)
811 ray%d = ray_dirs(i, :)
820 ninorout = ninorout + mod(nhits, 2)
823 fraction = real(ninorout)/real(spc)
834 type(
t_ray),
intent(in) :: ray
837 logical :: intersects
839 real(wp) :: n(3), p(3), c(3), edge(3), vp(3)
840 real(wp) :: area2, d, t, ndotraydirection
845 area2 = sqrt(sum(n(:)*n(:)))
847 ndotraydirection = sum(n(:)*ray%d(:))
849 if (abs(ndotraydirection) < 0.0000001_wp)
then
853 d = -sum(n(:)*triangle%v(1, :))
854 t = -(sum(n(:)*ray%o(:)) + d)/ndotraydirection
862 edge = triangle%v(2, :) - triangle%v(1, :)
863 vp = p - triangle%v(1, :)
865 if (sum(n(:)*c(:)) < 0)
then
869 edge = triangle%v(3, :) - triangle%v(2, :)
870 vp = p - triangle%v(2, :)
872 if (sum(n(:)*c(:)) < 0)
then
876 edge = triangle%v(1, :) - triangle%v(3, :)
877 vp = p - triangle%v(3, :)
879 if (sum(n(:)*c(:)) < 0)
then
892 type(
t_model),
intent(in) :: model
893 real(wp),
allocatable,
intent(out),
dimension(:, :, :) :: boundary_v
894 integer,
intent(out) :: boundary_vertex_count, boundary_edge_count
897 integer :: edge_count, edge_index, store_index
898 real(wp),
dimension(1:2, 1:2) :: edge
899 real(wp),
dimension(1:2) :: boundary_edge
900 real(wp),
dimension(1:(3*model%ntrs), 1:2, 1:2) :: temp_boundary_v
901 integer,
dimension(1:(3*model%ntrs)) :: edge_occurrence
902 real(wp) :: edgetan, initial, v_norm, xnormal, ynormal
905 edge_count = 3*model%ntrs
914 edge(1, 1:2) = model%trs(i)%v(1, 1:2)
915 edge(2, 1:2) = model%trs(i)%v(2, 1:2)
919 edge(1, 1:2) = model%trs(i)%v(2, 1:2)
920 edge(2, 1:2) = model%trs(i)%v(3, 1:2)
924 edge(1, 1:2) = model%trs(i)%v(3, 1:2)
925 edge(2, 1:2) = model%trs(i)%v(1, 1:2)
933 if (((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(
j, 1, 1)) < threshold_edge_zero) .and. &
934 (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(
j, 1, 2)) < threshold_edge_zero) .and. &
935 (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(
j, 2, 1)) < threshold_edge_zero) .and. &
936 (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(
j, 2, 2)) < threshold_edge_zero)) .or. &
937 ((abs(temp_boundary_v(i, 1, 1) - temp_boundary_v(
j, 2, 1)) < threshold_edge_zero) .and. &
938 (abs(temp_boundary_v(i, 1, 2) - temp_boundary_v(
j, 2, 2)) < threshold_edge_zero) .and. &
939 (abs(temp_boundary_v(i, 2, 1) - temp_boundary_v(
j, 1, 1)) < threshold_edge_zero) .and. &
940 (abs(temp_boundary_v(i, 2, 2) - temp_boundary_v(
j, 1, 2)) < threshold_edge_zero)))
then
942 edge_occurrence(i) = edge_occurrence(i) + 1
949 boundary_vertex_count = 0
950 boundary_edge_count = 0
953 if (edge_occurrence(i) == 0)
then
954 boundary_vertex_count = boundary_vertex_count + 2
955 boundary_edge_count = boundary_edge_count + 1
960 allocate (boundary_v(boundary_edge_count, 1:3, 1:2))
965 if (edge_occurrence(i) == 0)
then
966 store_index = store_index + 1
967 boundary_v(store_index, 1, 1:2) = temp_boundary_v(i, 1, 1:2)
968 boundary_v(store_index, 2, 1:2) = temp_boundary_v(i, 2, 1:2)
973 do i = 1, boundary_edge_count
974 boundary_edge(1) = boundary_v(i, 2, 1) - boundary_v(i, 1, 1)
975 boundary_edge(2) = boundary_v(i, 2, 2) - boundary_v(i, 1, 2)
976 edgetan = boundary_edge(1)/sign(max(sgm_eps, abs(boundary_edge(2))), boundary_edge(2))
978 if (abs(boundary_edge(2)) < threshold_vector_zero)
then
979 if (edgetan > 0._wp)
then
987 initial = boundary_edge(2)
988 ynormal = -edgetan*initial
992 v_norm = sqrt(xnormal**2 + ynormal**2)
993 boundary_v(i, 3, 1) = xnormal/v_norm
994 boundary_v(i, 3, 2) = ynormal/v_norm
1049 logical,
intent(inout) :: interpolate
1050 type(
t_model),
intent(in) :: model
1051 real(wp),
dimension(1:3),
intent(in) :: spacing
1052 real(wp),
dimension(1:3) :: edge_l
1053 real(wp) :: cell_width
1054 real(wp),
dimension(1:3, 1:3) :: tri_v
1057 cell_width = minval(spacing)
1058 interpolate = .false.
1060 do i = 1, model%ntrs
1062 tri_v(1,
j) = model%trs(i)%v(1,
j)
1063 tri_v(2,
j) = model%trs(i)%v(2,
j)
1064 tri_v(3,
j) = model%trs(i)%v(3,
j)
1067 edge_l(1) = sqrt((tri_v(1, 2) - tri_v(1, 1))**2 + &
1068 (tri_v(2, 2) - tri_v(2, 1))**2 + &
1069 (tri_v(3, 2) - tri_v(3, 1))**2)
1070 edge_l(2) = sqrt((tri_v(1, 3) - tri_v(1, 2))**2 + &
1071 (tri_v(2, 3) - tri_v(2, 2))**2 + &
1072 (tri_v(3, 3) - tri_v(3, 2))**2)
1073 edge_l(3) = sqrt((tri_v(1, 1) - tri_v(1, 3))**2 + &
1074 (tri_v(2, 1) - tri_v(2, 3))**2 + &
1075 (tri_v(3, 1) - tri_v(3, 3))**2)
1077 if ((edge_l(1) > cell_width) .or. &
1078 (edge_l(2) > cell_width) .or. &
1079 (edge_l(3) > cell_width))
then
1080 interpolate = .true.
1082 interpolate = .false.
1094 subroutine f_interpolate_2d(boundary_v, boundary_edge_count, spacing, interpolated_boundary_v, total_vertices)
1096 real(wp),
intent(in),
dimension(:, :, :) :: boundary_v
1097 real(wp),
dimension(1:3),
intent(in) :: spacing
1098 real(wp),
allocatable,
intent(inout),
dimension(:, :) :: interpolated_boundary_v
1100 integer,
intent(inout) :: total_vertices, boundary_edge_count
1101 integer :: num_segments
1104 real(wp) :: edge_length, cell_width
1105 real(wp),
dimension(1:2) :: edge_x, edge_y, edge_del
1108 cell_width = minval(spacing(1:2))
1113 do i = 1, boundary_edge_count
1115 edge_x(1) = boundary_v(i, 1, 1)
1116 edge_y(1) = boundary_v(i, 1, 2)
1117 edge_x(2) = boundary_v(i, 2, 1)
1118 edge_y(2) = boundary_v(i, 2, 2)
1121 edge_length = sqrt((edge_x(2) - edge_x(1))**2 + &
1122 (edge_y(2) - edge_y(1))**2)
1125 if (edge_length > cell_width)
then
1126 num_segments = ifactor_2d*ceiling(edge_length/cell_width)
1132 total_vertices = total_vertices + num_segments
1136 allocate (interpolated_boundary_v(1:total_vertices, 1:3))
1140 do i = 1, boundary_edge_count
1142 edge_x(1) = boundary_v(i, 1, 1)
1143 edge_y(1) = boundary_v(i, 1, 2)
1144 edge_x(2) = boundary_v(i, 2, 1)
1145 edge_y(2) = boundary_v(i, 2, 2)
1148 edge_length = sqrt((edge_x(2) - edge_x(1))**2 + &
1149 (edge_y(2) - edge_y(1))**2)
1152 if (edge_length > cell_width)
then
1153 num_segments = ifactor_2d*ceiling(edge_length/cell_width)
1154 edge_del(1) = (edge_x(2) - edge_x(1))/num_segments
1155 edge_del(2) = (edge_y(2) - edge_y(1))/num_segments
1162 interpolated_boundary_v(1, 1) = edge_x(1)
1163 interpolated_boundary_v(1, 2) = edge_y(1)
1164 interpolated_boundary_v(1, 3) = 0._wp
1167 do j = 1, num_segments - 1
1168 total_vertices = total_vertices + 1
1169 interpolated_boundary_v(total_vertices, 1) = edge_x(1) +
j*edge_del(1)
1170 interpolated_boundary_v(total_vertices, 2) = edge_y(1) +
j*edge_del(2)
1174 if (num_segments > 0)
then
1175 total_vertices = total_vertices + 1
1176 interpolated_boundary_v(total_vertices, 1) = edge_x(2)
1177 interpolated_boundary_v(total_vertices, 2) = edge_y(2)
1189 real(wp),
dimension(1:3),
intent(in) :: spacing
1190 type(
t_model),
intent(in) :: model
1191 real(wp),
allocatable,
intent(inout),
dimension(:, :) :: interpolated_boundary_v
1192 integer,
intent(out) :: total_vertices
1194 integer :: i,
j,
k, num_triangles, num_segments, num_inner_vertices
1195 real(wp),
dimension(1:3, 1:3) :: tri
1196 real(wp),
dimension(1:3) :: edge_del, cell_area
1197 real(wp),
dimension(1:3) :: bary_coord
1198 real(wp) :: edge_length, cell_width, cell_area_min, tri_area
1201 num_triangles = model%ntrs
1202 cell_width = minval(spacing)
1205 cell_area(1) = spacing(1)*spacing(2)
1206 cell_area(2) = spacing(1)*spacing(3)
1207 cell_area(3) = spacing(2)*spacing(3)
1208 cell_area_min = minval(cell_area)
1209 num_inner_vertices = 0
1213 do i = 1, num_triangles
1216 tri(1, 1) = model%trs(i)%v(
j, 1)
1217 tri(1, 2) = model%trs(i)%v(
j, 2)
1218 tri(1, 3) = model%trs(i)%v(
j, 3)
1220 tri(2, 1) = model%trs(i)%v(mod(
j, 3) + 1, 1)
1221 tri(2, 2) = model%trs(i)%v(mod(
j, 3) + 1, 2)
1222 tri(2, 3) = model%trs(i)%v(mod(
j, 3) + 1, 3)
1225 edge_length = sqrt((tri(2, 1) - tri(1, 1))**2 + &
1226 (tri(2, 2) - tri(1, 2))**2 + &
1227 (tri(2, 3) - tri(1, 3))**2)
1230 if (edge_length > cell_width)
then
1231 num_segments = ifactor_3d*ceiling(edge_length/cell_width)
1237 total_vertices = total_vertices + num_segments + 1
1242 tri(
k, 1) = model%trs(i)%v(
k, 1)
1243 tri(
k, 2) = model%trs(i)%v(
k, 2)
1244 tri(
k, 3) = model%trs(i)%v(
k, 3)
1248 if (tri_area > threshold_bary*cell_area_min)
then
1249 num_inner_vertices = ifactor_bary_3d*ceiling(tri_area/cell_area_min)
1250 total_vertices = total_vertices + num_inner_vertices
1255 allocate (interpolated_boundary_v(1:total_vertices, 1:3))
1259 do i = 1, num_triangles
1263 tri(1, 1) = model%trs(i)%v(
j, 1)
1264 tri(1, 2) = model%trs(i)%v(
j, 2)
1265 tri(1, 3) = model%trs(i)%v(
j, 3)
1267 tri(2, 1) = model%trs(i)%v(mod(
j, 3) + 1, 1)
1268 tri(2, 2) = model%trs(i)%v(mod(
j, 3) + 1, 2)
1269 tri(2, 3) = model%trs(i)%v(mod(
j, 3) + 1, 3)
1272 edge_length = sqrt((tri(2, 1) - tri(1, 1))**2 + &
1273 (tri(2, 2) - tri(1, 2))**2 + &
1274 (tri(2, 3) - tri(1, 3))**2)
1277 if (edge_length > cell_width)
then
1278 num_segments = ifactor_3d*ceiling(edge_length/cell_width)
1279 edge_del(1) = (tri(2, 1) - tri(1, 1))/num_segments
1280 edge_del(2) = (tri(2, 2) - tri(1, 2))/num_segments
1281 edge_del(3) = (tri(2, 3) - tri(1, 3))/num_segments
1288 do k = 0, num_segments - 1
1289 total_vertices = total_vertices + 1
1290 interpolated_boundary_v(total_vertices, 1) = tri(1, 1) +
k*edge_del(1)
1291 interpolated_boundary_v(total_vertices, 2) = tri(1, 2) +
k*edge_del(2)
1292 interpolated_boundary_v(total_vertices, 3) = tri(1, 3) +
k*edge_del(3)
1296 total_vertices = total_vertices + 1
1297 interpolated_boundary_v(total_vertices, 1) = tri(2, 1)
1298 interpolated_boundary_v(total_vertices, 2) = tri(2, 2)
1299 interpolated_boundary_v(total_vertices, 3) = tri(2, 3)
1304 tri(
k, 1) = model%trs(i)%v(
k, 1)
1305 tri(
k, 2) = model%trs(i)%v(
k, 2)
1306 tri(
k, 3) = model%trs(i)%v(
k, 3)
1310 if (tri_area > threshold_bary*cell_area_min)
then
1311 num_inner_vertices = ifactor_bary_3d*ceiling(tri_area/cell_area_min)
1313 do k = 1, num_inner_vertices
1314 call random_number(bary_coord(1))
1315 call random_number(bary_coord(2))
1317 if ((bary_coord(1) + bary_coord(2)) >= 1._wp)
then
1318 bary_coord(1) = 1._wp - bary_coord(1)
1319 bary_coord(2) = 1._wp - bary_coord(2)
1321 bary_coord(3) = 1._wp - bary_coord(1) - bary_coord(2)
1323 total_vertices = total_vertices + 1
1324 interpolated_boundary_v(total_vertices, 1) = dot_product(bary_coord, tri(1:3, 1))
1325 interpolated_boundary_v(total_vertices, 2) = dot_product(bary_coord, tri(1:3, 2))
1326 interpolated_boundary_v(total_vertices, 3) = dot_product(bary_coord, tri(1:3, 3))
1341# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1343# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1345# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1347# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1349# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1351# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1353# 1056 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1356 type(
t_model),
intent(IN) :: model
1357 real(wp),
dimension(1:3),
intent(in) :: point
1358 real(wp),
dimension(1:3),
intent(out) :: normals
1359 real(wp),
intent(out) :: distance
1361 real(wp),
dimension(1:3, 1:3) :: tri
1362 real(wp) :: dist_min, dist_t_min
1363 real(wp) :: dist_min_normal, dist_buffer_normal
1364 real(wp),
dimension(1:3) :: midp
1365 real(wp),
dimension(1:3) :: dist_buffer
1366 integer :: i,
j, tri_idx
1369 dist_min_normal = 1.e12_wp
1373 do i = 1, model%ntrs
1375 tri(
j, 1) = model%trs(i)%v(
j, 1)
1376 tri(
j, 2) = model%trs(i)%v(
j, 2)
1377 tri(
j, 3) = model%trs(i)%v(
j, 3)
1378 dist_buffer(
j) = sqrt((point(1) - tri(
j, 1))**2 + &
1379 (point(2) - tri(
j, 2))**2 + &
1380 (point(3) - tri(
j, 3))**2)
1385 midp(
j) = (tri(1,
j) + tri(2,
j) + tri(3,
j))/3
1388 dist_t_min = minval(dist_buffer(1:3))
1389 dist_buffer_normal = sqrt((point(1) - midp(1))**2 + &
1390 (point(2) - midp(2))**2 + &
1391 (point(3) - midp(3))**2)
1393 if (dist_t_min < dist_min)
then
1394 dist_min = dist_t_min
1397 if (dist_buffer_normal < dist_min_normal)
then
1398 dist_min_normal = dist_buffer_normal
1403 normals(1) = model%trs(tri_idx)%n(1)
1404 normals(2) = model%trs(tri_idx)%n(2)
1405 normals(3) = model%trs(tri_idx)%n(3)
1415 function f_distance(boundary_v, boundary_edge_count, point)
result(distance)
1418# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1420# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1422# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1424# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1426# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1428# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1430# 1119 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1433 integer,
intent(in) :: boundary_edge_count
1434 real(wp),
intent(in),
dimension(:, :, :) :: boundary_v
1436 real(wp),
dimension(1:3),
intent(in) :: point
1439 real(wp) :: dist_buffer1, dist_buffer2
1440 real(wp),
dimension(1:boundary_edge_count) :: dist_buffer
1441 real(wp) :: distance
1444 do i = 1, boundary_edge_count
1445 dist_buffer1 = sqrt((point(1) - boundary_v(i, 1, 1))**2 + &
1446 & (point(2) - boundary_v(i, 1, 2))**2)
1448 dist_buffer2 = sqrt((point(1) - boundary_v(i, 2, 1))**2 + &
1449 & (point(2) - boundary_v(i, 2, 2))**2)
1451 dist_buffer(i) = minval((/dist_buffer1, dist_buffer2/))
1454 distance = minval(dist_buffer)
1463 subroutine f_normals(boundary_v, boundary_edge_count, point, normals)
1466# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1468# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1470# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1472# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1474# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1476# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1478# 1153 "/home/runner/work/MFC/MFC/src/common/m_model.fpp"
1481 integer,
intent(in) :: boundary_edge_count
1482 real(wp),
intent(in),
dimension(:, :, :) :: boundary_v
1483 real(wp),
dimension(1:3),
intent(in) :: point
1484 real(wp),
dimension(1:3),
intent(out) :: normals
1486 integer :: i, idx_buffer
1487 real(wp) :: dist_min, dist_buffer
1488 real(wp) :: midp(1:3)
1491 dist_min = initial_distance_buffer
1494 do i = 1, boundary_edge_count
1495 midp(1) = (boundary_v(i, 2, 1) + boundary_v(i, 1, 1))/2
1496 midp(2) = (boundary_v(i, 2, 2) + boundary_v(i, 1, 2))/2
1499 dist_buffer = sqrt((point(1) - midp(1))**2 + &
1500 & (point(2) - midp(2))**2)
1502 if (dist_buffer < dist_min)
then
1503 dist_min = dist_buffer
1508 normals(1) = boundary_v(idx_buffer, 3, 1)
1509 normals(2) = boundary_v(idx_buffer, 3, 2)