OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
find_closest_node.F
Go to the documentation of this file.
1Copyright> OpenRadioss
2Copyright> Copyright (C) 1986-2025 Altair Engineering Inc.
3Copyright>
4Copyright> This program is free software: you can redistribute it and/or modify
5Copyright> it under the terms of the GNU Affero General Public License as published by
6Copyright> the Free Software Foundation, either version 3 of the License, or
7Copyright> (at your option) any later version.
8Copyright>
9Copyright> This program is distributed in the hope that it will be useful,
10Copyright> but WITHOUT ANY WARRANTY; without even the implied warranty of
11Copyright> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12Copyright> GNU Affero General Public License for more details.
13Copyright>
14Copyright> You should have received a copy of the GNU Affero General Public License
15Copyright> along with this program. If not, see <https://www.gnu.org/licenses/>.
16Copyright>
17Copyright>
18Copyright> Commercial Alternative: Altair Radioss Software
19Copyright>
20Copyright> As an alternative to this open-source version, Altair also offers Altair Radioss
21Copyright> software under a commercial license. Contact Altair to discuss further if the
22Copyright> commercial version may interest you: https://www.altair.com/radioss/.
23!||====================================================================
24!|| find_closest_node ../starter/source/initial_conditions/inivol/find_closest_node.F
25!||--- called by ------------------------------------------------------
26!|| phase_detection ../starter/source/initial_conditions/inivol/phase_detection.F
27!||====================================================================
28 SUBROUTINE find_closest_node(LEADING_DIRECTION,N1,N2,N3,
29 . X1,X2,EPS,
30 . KEY1,KEY2,ID_X2,ID_LIST)
31!---
32C Nearest Neighbor search
33C This routines returns ID_LIST and DIST such as
34C ID_LIST(I=1:N2) is the id of the closest node in X1(ID_X2(1:N2))
35C
36C This NNS algorithm is not optimal
37C - worst case O(N1 x N2)
38C - best case O(N1 x LOG(N1)) + O(N1)
39C - Expected in practice: O(N1 log(N1)) + O (N1 x (N2)^(1/3))
40C which is good enough for cases where N2 << N1
41C-----------------------------------------------
42C I m p l i c i t T y p e s
43C-----------------------------------------------
44#include "implicit_f.inc"
45C-----------------------------------------------
46C C o m m o n B l o c k s
47C-----------------------------------------------
48! com04 : numels/numelq/numeltg
49#include "com04_c.inc"
50
51! --------------------------------------
52 INTEGER, INTENT(IN) :: LEADING_DIRECTION
53 INTEGER, INTENT(IN) :: N1,N2,N3 ! N1: number if node
54 ! N2: number of root nodes
55 ! N3 : total number of node
56 my_real, DIMENSION(3,N1), INTENT(IN) :: x1 ! Coordinates
57 my_real, DIMENSION(3,N3), INTENT(IN) :: x2 ! Coordinates
58 my_real, INTENT(IN) :: eps ! Minimum distance between two distinct points
59 INTEGER, DIMENSION(N1), INTENT(IN) :: KEY1
60 INTEGER, DIMENSION(N2), INTENT(IN) :: KEY2
61 INTEGER, DIMENSION(N2), INTENT(IN) :: ID_X2 ! Indexes of 'root' coordinates
62 INTEGER, DIMENSION(N1),INTENT(INOUT) :: ID_LIST! id of the closest root node
63! --------------------------------------
64C LOCAL VARIABLES
65 INTEGER :: I,J,ID,info,JMIN
66 INTEGER :: LAST_POSITION
67 my_real :: leading_size
68 my_real :: delta,dx,dy,dz,dxl,dyl,dzl,dl
69 integer :: ijk
70! --------------------------------------
71 last_position = 1
72 jmin = 1
73 DO i = 1,n1
74 dx =abs(x2(1,id_x2(key2(last_position))) - x1(1,key1(i)))
75 dy =abs(x2(2,id_x2(key2(last_position))) - x1(2,key1(i)))
76 dz =abs(x2(3,id_x2(key2(last_position))) - x1(3,key1(i)))
77 leading_size = abs(x2(leading_direction,id_x2(key2(last_position))) - x1(leading_direction,key1(i)))
78 delta = sqrt(dx*dx+dy*dy+dz*dz)
79
80C Avoid nodes closer than EPS
81 IF (delta < eps) delta = huge(delta)
82
83C Upward search
84 j = last_position + 1
85 jmin = last_position
86 id = key2(last_position)
87 dxl = leading_size
88 DO WHILE (j <= n2 .AND. (dxl <= delta .OR. delta < eps))
89 dxl =abs(x2(1,id_x2(key2(j))) - x1(1,key1(i)))
90 dyl =abs(x2(2,id_x2(key2(j))) - x1(2,key1(i)))
91 dzl =abs(x2(3,id_x2(key2(j))) - x1(3,key1(i)))
92 dl = sqrt(dxl*dxl+dyl*dyl+dzl*dzl)
93 IF (dl < delta .AND. dl > eps) THEN
94 delta = dl
95 id = key2(j)
96 jmin = j
97 ENDIF
98 j = j + 1
99 IF (j <= n2) dxl =abs(x2(leading_direction,id_x2(key2(j)))-x1(leading_direction,key1(i)))
100 ENDDO
101
102C Backward search
103 j = last_position
104 dxl = leading_size
105 DO WHILE (j > 0 .AND. (dxl <= delta .OR. delta < eps))
106 dxl =abs(x2(1,id_x2(key2(j))) - x1(1,key1(i)))
107 dyl =abs(x2(2,id_x2(key2(j))) - x1(2,key1(i)))
108 dzl =abs(x2(3,id_x2(key2(j))) - x1(3,key1(i)))
109 dl = sqrt(dxl*dxl+dyl*dyl+dzl*dzl)
110 IF (dl < delta .AND. dl > eps) THEN
111 delta = dl
112 id = key2(j)
113 jmin = j
114 ENDIF
115 j = j - 1
116 IF (j > 0) dxl =abs(x2(leading_direction,id_x2(key2(j)))-x1(leading_direction,key1(i)))
117 ENDDO
118 last_position = jmin
119 id_list(key1(i)) = id
120 ENDDO
121
122 DO i = 1,n1
123 id_list(i) = id_x2(id_list(i))
124 ENDDO
125
126 RETURN
127!---
128 END SUBROUTINE find_closest_node
#define my_real
Definition cppsort.cpp:32
subroutine find_closest_node(leading_direction, n1, n2, n3, x1, x2, eps, key1, key2, id_x2, id_list)