FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
surf_ele.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
9  use hecmw_util
10  use elementinfo
11  use m_utilities
12  use bucket_search
13 
14  implicit none
15 
16  integer(kind=kint), parameter :: l_max_surface_node =20
17  integer(kind=kint), parameter :: l_max_elem_node = 100
18  integer(kind=kint), parameter :: l_max_elem_surf = 6
19 
20  integer(kind=kint), parameter :: n_neighbor_max_init = 8
21 
24  integer(kind=kint) :: eid
25  integer(kind=kint) :: etype
26  integer(kind=kint), pointer :: nodes(:)=>null()
27  integer(kind=kint) :: n_neighbor
28  integer(kind=kint) :: n_neighbor_max
29  integer(kind=kint), pointer :: neighbor(:)=>null()
30  real(kind=kreal) :: reflen
31  real(kind=kreal) :: xavg(3)
32  real(kind=kreal) :: dmax
33  integer(kind=kint) :: bktid
34  real(kind=kreal), pointer :: vertex_normals(:,:)=>null()
35  real(kind=kreal), pointer :: intermediate_points(:,:)=>null()
36  end type tsurfelement
37 
38  integer(kind=kint), parameter, private :: debug = 0
39 
40 contains
41 
43  subroutine initialize_surf( eid, etype, nsurf, surf )
44  integer(kind=kint), intent(in) :: eid
45  integer(kind=kint), intent(in) :: etype
46  integer(kind=kint), intent(in) :: nsurf
47  type(tsurfelement), intent(inout) :: surf
48  integer(kind=kint) :: i, n, outtype, nodes(100)
49  surf%eid = eid
50 
51  if( nsurf > 0 ) then
52  call getsubface( etype, nsurf, outtype, nodes )
53  surf%etype = outtype
54  n=getnumberofnodes( outtype )
55  else !treat 3d master element as it is
56  surf%etype = etype
57  n=getnumberofnodes( etype )
58  do i=1,n
59  nodes(i) = i
60  enddo
61  endif
62  allocate( surf%nodes(n) )
63  surf%nodes(1:n)=nodes(1:n)
64  surf%n_neighbor = 0
65  surf%n_neighbor_max = 0
66  surf%reflen = -1.d0
67  surf%xavg(:) = 0.d0
68  surf%dmax = -1.d0
69  surf%bktID = -1
70  allocate( surf%vertex_normals(3,n) )
71  surf%vertex_normals(:,:) = 0.d0
72  end subroutine
73 
75  subroutine finalize_surf( surf )
76  type(tsurfelement), intent(inout) :: surf
77  if( associated(surf%nodes) ) deallocate( surf%nodes )
78  if( associated(surf%neighbor) ) deallocate( surf%neighbor )
79  if( associated(surf%vertex_normals) ) deallocate( surf%vertex_normals )
80  if( associated(surf%intermediate_points) ) deallocate( surf%intermediate_points )
81  end subroutine
82 
84  subroutine find_surface_neighbor( surf, bktDB )
85  type(tsurfelement), intent(inout) :: surf(:)
86  type(bucketdb), intent(in) :: bktDB
87  integer(kind=kint) :: i, j, ii,jj, nd1, nd2, nsurf
88  integer(kind=kint) :: k, oldsize, newsize
89  integer(kind=kint), pointer :: dumarray(:) => null()
90  integer(kind=kint) :: bktID, ncand, js
91  integer(kind=kint), allocatable :: indexSurf(:)
92  if (debug >= 1) write(0,*) 'DEBUG: find_surface_neighbor: start'
93 
94  nsurf = size(surf)
95 
96  !$omp parallel do default(none), &
97  !$omp&private(i,ii,nd1,j,jj,nd2,oldsize,newsize,dumarray,k,bktID,ncand,indexSurf,js), &
98  !$omp&shared(nsurf,surf,bktDB)
99  do i=1,nsurf
100  bktid = bucketdb_getbucketid(bktdb, surf(i)%xavg)
101  ncand = bucketdb_getnumcand(bktdb, bktid)
102  if (ncand == 0) cycle
103  allocate(indexsurf(ncand))
104  call bucketdb_getcand(bktdb, bktid, ncand, indexsurf)
105  jloop: do js=1,ncand
106  j = indexsurf(js)
107  if( i==j ) cycle
108  if( associated(surf(i)%neighbor) ) then
109  if ( any( surf(i)%neighbor(1:surf(i)%n_neighbor)==j ) ) cycle
110  endif
111  do ii=1, size(surf(i)%nodes)
112  nd1 = surf(i)%nodes(ii)
113  do jj=1, size(surf(j)%nodes)
114  nd2 = surf(j)%nodes(jj)
115  if( nd1==nd2 ) then
116  surf(i)%n_neighbor = surf(i)%n_neighbor+1
117 
118  if( .not. associated(surf(i)%neighbor) ) then
119  allocate( surf(i)%neighbor(n_neighbor_max_init) )
120  surf(i)%n_neighbor_max = n_neighbor_max_init
121  surf(i)%neighbor(1) = j
122  else if( surf(i)%n_neighbor > surf(i)%n_neighbor_max ) then
123  oldsize = surf(i)%n_neighbor_max
124  newsize = oldsize * 2
125  dumarray => surf(i)%neighbor
126  allocate( surf(i)%neighbor(newsize) )
127  surf(i)%n_neighbor_max = newsize
128  do k=1,oldsize
129  surf(i)%neighbor(k) = dumarray(k)
130  enddo
131  surf(i)%neighbor(oldsize+1) = j
132  deallocate( dumarray )
133  else
134  surf(i)%neighbor(surf(i)%n_neighbor) = j
135  endif
136 
137  cycle jloop
138  endif
139  enddo
140  enddo
141  enddo jloop
142  deallocate(indexsurf)
143  enddo
144  !$omp end parallel do
145 
146  if (debug >= 1) write(0,*) 'DEBUG: find_surface_neighbor: end'
147  end subroutine
148 
150  subroutine update_surface_reflen( surf, coord )
151  type(tsurfelement), intent(inout) :: surf(:)
152  real(kind=kreal), intent(in) :: coord(:)
153  real(kind=kreal) :: elem(3, l_max_surface_node), r0(2)
154  integer(kind=kint) :: nn, i, j, iss
155  !$omp parallel do default(none) private(j,nn,i,iss,elem,r0) shared(surf,coord)
156  do j=1,size(surf)
157  nn = size(surf(j)%nodes)
158  do i=1,nn
159  iss = surf(j)%nodes(i)
160  elem(1:3,i) = coord(3*iss-2:3*iss)
161  enddo
162  call getelementcenter( surf(j)%etype, r0 )
163  surf(j)%reflen = getreferencelength( surf(j)%etype, nn, r0, elem )
164  enddo
165  !$omp end parallel do
166  end subroutine update_surface_reflen
167 
169  subroutine update_surface_box_info( surf, currpos )
170  type(tsurfelement), intent(inout) :: surf(:)
171  real(kind=kreal), intent(in) :: currpos(:)
172  integer(kind=kint) :: nn, i, j, iss
173  real(kind=kreal) :: elem(3,l_max_surface_node),xmin(3), xmax(3), xsum(3), lx(3)
174  !$omp parallel do default(none) private(i,nn,iss,elem,xmin,xmax,xsum,lx) shared(surf,currpos)
175  do j=1, size(surf)
176  nn = size(surf(j)%nodes)
177  do i=1,nn
178  iss = surf(j)%nodes(i)
179  elem(1:3,i) = currpos(3*iss-2:3*iss)
180  enddo
181  do i=1,3
182  xmin(i) = minval(elem(i,1:nn))
183  xmax(i) = maxval(elem(i,1:nn))
184  xsum(i) = sum(elem(i,1:nn))
185  enddo
186  surf(j)%xavg(:) = xsum(:) / nn
187  lx(:) = xmax(:) - xmin(:)
188  surf(j)%dmax = maxval(lx) * 0.5d0
189  enddo
190  !$omp end parallel do
191  end subroutine update_surface_box_info
192 
194  subroutine update_surface_bucket_info(surf, bktDB)
195  type(tsurfelement), intent(inout) :: surf(:)
196  type(bucketdb), intent(inout) :: bktDB
197  real(kind=kreal) :: x_min(3), x_max(3), d_max
198  integer(kind=kint) :: nsurf, i, j
199  if (debug >= 1) write(0,*) 'DEBUG: update_surface_bucket_info: start'
200  nsurf = size(surf)
201  if (nsurf == 0) return
202  x_min(:) = surf(1)%xavg(:)
203  x_max(:) = surf(1)%xavg(:)
204  d_max = surf(1)%dmax*2.d0
205  do i = 2, nsurf
206  do j = 1, 3
207  if (surf(i)%xavg(j) < x_min(j)) x_min(j) = surf(i)%xavg(j)
208  if (surf(i)%xavg(j) > x_max(j)) x_max(j) = surf(i)%xavg(j)
209  if (surf(i)%dmax > d_max) d_max = surf(i)%dmax
210  enddo
211  enddo
212  do j = 1, 3
213  x_min(j) = x_min(j) - d_max
214  x_max(j) = x_max(j) + d_max
215  enddo
216  call bucketdb_setup(bktdb, x_min, x_max, d_max, nsurf)
217  !$omp parallel do default(none) private(i) shared(nsurf,surf,bktDB)
218  do i = 1, nsurf
219  surf(i)%bktID = bucketdb_getbucketid(bktdb, surf(i)%xavg)
220  call bucketdb_registerpre(bktdb, surf(i)%bktID)
221  enddo
222  !$omp end parallel do
223  call bucketdb_allocate(bktdb)
224  do i = 1, nsurf
225  call bucketdb_register(bktdb, surf(i)%bktID, i)
226  enddo
227  if (debug >= 1) write(0,*) 'DEBUG: update_surface_bucket_info: end'
228  end subroutine update_surface_bucket_info
229 
231  subroutine calc_surf_vertex_normals( surf, elem )
233  type(tsurfelement), intent(inout) :: surf
234  real(kind=kreal), intent(in) :: elem(3,*)
235 
236  integer(kind=kint) :: j, nn, etype
237  real(kind=kreal) :: cnpos(2), normal(3)
238 
239  etype = surf%etype
240  nn = size(surf%nodes)
241 
242  do j = 1, nn
243  call getvertexcoord(etype, j, cnpos)
244  normal = surfacenormal(etype, nn, cnpos, elem)
245  normal = normal / dsqrt(dot_product(normal, normal))
246  surf%vertex_normals(:, j) = normal
247  enddo
248 
249  end subroutine calc_surf_vertex_normals
250 
252  subroutine calc_all_surf_vertex_normals( surf, currpos )
253  type(tsurfelement), intent(inout) :: surf(:)
254  real(kind=kreal), intent(in) :: currpos(:)
255 
256  integer(kind=kint) :: i, j, nn, iss
257  real(kind=kreal) :: elem(3, l_max_elem_node)
258 
259  !$omp parallel do default(none) private(i,j,nn,iSS,elem) shared(surf,currpos)
260  do i = 1, size(surf)
261  nn = size(surf(i)%nodes)
262  do j = 1, nn
263  iss = surf(i)%nodes(j)
264  elem(1:3, j) = currpos(3*iss-2:3*iss)
265  enddo
266  call calc_surf_vertex_normals(surf(i), elem(1:3,1:nn))
267  enddo
268  !$omp end parallel do
269 
270  end subroutine calc_all_surf_vertex_normals
271 
272 end module msurfelement
This module provides bucket-search functionality It provides definition of bucket info and its access...
subroutine, public bucketdb_allocate(bktdb)
Allocate memory before actually registering members Before allocating memory, bucketDB_registerPre ha...
subroutine, public bucketdb_registerpre(bktdb, bid)
Pre-register for just counting members to be actually registered Bucket ID has to be obtained with bu...
integer(kind=kint) function, public bucketdb_getbucketid(bktdb, x)
Get bucket ID that includes given point.
subroutine, public bucketdb_register(bktdb, bid, sid)
Register member Before actually register, bucketDB_allocate has to be called.
integer(kind=kint) function, public bucketdb_getnumcand(bktdb, bid)
Get number of candidates within neighboring buckets of a given bucket Bucket ID has to be obtained wi...
subroutine, public bucketdb_getcand(bktdb, bid, ncand, cand)
Get candidates within neighboring buckets of a given bucket Number of candidates has to be obtained w...
subroutine, public bucketdb_setup(bktdb, x_min, x_max, dmin, n_tot)
Setup basic info of buckets.
This module encapsulate the basic functions of all elements provide by this software.
Definition: element.f90:43
integer(kind=kind(2)) function getnumberofnodes(etype)
Obtain number of nodes of the element.
Definition: element.f90:131
subroutine getelementcenter(fetype, localcoord)
Return natural coordinate of the center of element.
Definition: element.f90:1061
subroutine getsubface(intype, innumber, outtype, nodes)
Find the definition of surface of the element.
Definition: element.f90:193
subroutine getvertexcoord(fetype, cnode, localcoord)
Get the natural coord of a vertex node.
Definition: element.f90:1192
real(kind=kreal) function, dimension(3) surfacenormal(fetype, nn, localcoord, elecoord)
Calculate normal of 3d-surface.
Definition: element.f90:919
real(kind=kreal) function getreferencelength(fetype, nn, localcoord, elecoord)
This function calculates reference length at a point in surface.
Definition: element.f90:1315
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=4), parameter kreal
This module provides aux functions.
Definition: utilities.f90:6
This module manages surface elements in 3D It provides basic definition of surface elements (triangla...
Definition: surf_ele.f90:8
subroutine initialize_surf(eid, etype, nsurf, surf)
Initializer.
Definition: surf_ele.f90:44
integer(kind=kint), parameter l_max_elem_node
Definition: surf_ele.f90:17
subroutine calc_surf_vertex_normals(surf, elem)
Compute vertex normals for a single surface element (geometric calculation only)
Definition: surf_ele.f90:232
subroutine update_surface_reflen(surf, coord)
Compute reference length of surface elements.
Definition: surf_ele.f90:151
subroutine update_surface_box_info(surf, currpos)
Update info of cubic box including surface elements.
Definition: surf_ele.f90:170
integer(kind=kint), parameter l_max_elem_surf
Definition: surf_ele.f90:18
subroutine find_surface_neighbor(surf, bktDB)
Find neighboring surface elements.
Definition: surf_ele.f90:85
integer(kind=kint), parameter n_neighbor_max_init
Definition: surf_ele.f90:20
subroutine update_surface_bucket_info(surf, bktDB)
Update bucket info for searching surface elements.
Definition: surf_ele.f90:195
integer(kind=kint), parameter l_max_surface_node
Definition: surf_ele.f90:16
subroutine finalize_surf(surf)
Memory management subroutine.
Definition: surf_ele.f90:76
subroutine calc_all_surf_vertex_normals(surf, currpos)
Calculate vertex normals for all surface elements (geometric calculation only)
Definition: surf_ele.f90:253
Structure to define surface group.
Definition: surf_ele.f90:23