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()
38 integer(kind=kint),
parameter,
private :: debug = 0
44 integer(kind=kint),
intent(in) :: eid
45 integer(kind=kint),
intent(in) :: etype
46 integer(kind=kint),
intent(in) :: nsurf
48 integer(kind=kint) :: i, n, outtype, nodes(100)
52 call getsubface( etype, nsurf, outtype, nodes )
62 allocate( surf%nodes(n) )
63 surf%nodes(1:n)=nodes(1:n)
65 surf%n_neighbor_max = 0
70 allocate( surf%vertex_normals(3,n) )
71 surf%vertex_normals(:,:) = 0.d0
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 )
85 integer(kind=kint),
intent(in) :: file
87 integer(kind=kint) :: i
88 write(file,*)
"Element:",surf%eid,
"Surface type=",surf%etype
89 if(
associated( surf%nodes ) ) &
90 write(file,*) ( surf%nodes(i),i=1,
size(surf%nodes) )
91 if(
associated( surf%neighbor ) ) &
92 write(file,*) ( surf%neighbor(i),i=1,surf%n_neighbor )
98 type(bucketdb),
intent(in) :: bktDB
99 integer(kind=kint) :: i, j, ii,jj, nd1, nd2, nsurf
100 integer(kind=kint) :: k, oldsize, newsize
101 integer(kind=kint),
pointer :: dumarray(:) => null()
102 integer(kind=kint) :: bktID, ncand, js
103 integer(kind=kint),
allocatable :: indexSurf(:)
104 if (debug >= 1)
write(0,*)
'DEBUG: find_surface_neighbor: start'
114 if (ncand == 0) cycle
115 allocate(indexsurf(ncand))
120 if(
associated(surf(i)%neighbor) )
then
121 if ( any( surf(i)%neighbor(1:surf(i)%n_neighbor)==j ) ) cycle
123 do ii=1,
size(surf(i)%nodes)
124 nd1 = surf(i)%nodes(ii)
125 do jj=1,
size(surf(j)%nodes)
126 nd2 = surf(j)%nodes(jj)
128 surf(i)%n_neighbor = surf(i)%n_neighbor+1
130 if( .not.
associated(surf(i)%neighbor) )
then
133 surf(i)%neighbor(1) = j
134 else if( surf(i)%n_neighbor > surf(i)%n_neighbor_max )
then
135 oldsize = surf(i)%n_neighbor_max
136 newsize = oldsize * 2
137 dumarray => surf(i)%neighbor
138 allocate( surf(i)%neighbor(newsize) )
139 surf(i)%n_neighbor_max = newsize
141 surf(i)%neighbor(k) = dumarray(k)
143 surf(i)%neighbor(oldsize+1) = j
144 deallocate( dumarray )
146 surf(i)%neighbor(surf(i)%n_neighbor) = j
154 deallocate(indexsurf)
158 if (debug >= 1)
write(0,*)
'DEBUG: find_surface_neighbor: end'
164 real(kind=kreal),
intent(in) :: cpos(2)
166 integer(kind=kint) :: i
167 real(kind=kreal) :: maxv(3)
169 if( .not.
associated(surf%neighbor) )
return
171 select case(surf%etype)
173 if( all(cpos>0.d0) .and. all(cpos<1.d0) )
return
174 if(
size(surf%neighbor)<3 )
return
175 if( all(cpos(:)>0.d0) )
return
177 if( cpos(i)< 0.d0 ) maxv(i) = -cpos(i)
181 if( all(cpos>-1.d0) .and. all(cpos<1.d0) )
return
182 if(
size(surf%neighbor)<4 )
return
183 if( cpos(1)<-1.d0 .and. dabs(cpos(2))<1.d0 )
then
185 elseif( cpos(1)>1.d0 .and. dabs(cpos(2))<1.d0 )
then
187 elseif( dabs(cpos(1))<1.d0 .and. cpos(2)<-1.d0 )
then
189 elseif( dabs(cpos(1))<1.d0 .and. cpos(2)>1.d0 )
then
191 elseif( cpos(1)<-1.d0 .and. cpos(2)<-1.d0 )
then
192 if( cpos(1)>cpos(2) )
then
197 elseif( cpos(1)<-1.d0 .and. cpos(2)>1.d0 )
then
198 if( dabs(cpos(1))>cpos(2) )
then
203 elseif( cpos(1)>1.d0 .and. cpos(2)<-1.d0 )
then
204 if( cpos(1)>dabs(cpos(2)) )
then
209 elseif( cpos(1)>1.d0 .and. cpos(2)>1.d0 )
then
210 if( cpos(1)>cpos(2) )
then
217 stop
"type of surface element not defined"
226 real(kind=kreal),
intent(in) :: coord(:)
228 integer(kind=kint) :: nn, i, j, iss
231 nn =
size(surf(j)%nodes)
233 iss = surf(j)%nodes(i)
234 elem(1:3,i) = coord(3*iss-2:3*iss)
245 real(kind=kreal),
intent(in) :: currpos(:)
246 integer(kind=kint) :: nn, i, j, iss
250 nn =
size(surf(j)%nodes)
252 iss = surf(j)%nodes(i)
253 elem(1:3,i) = currpos(3*iss-2:3*iss)
256 xmin(i) = minval(elem(i,1:nn))
257 xmax(i) = maxval(elem(i,1:nn))
258 xsum(i) = sum(elem(i,1:nn))
260 surf(j)%xavg(:) = xsum(:) / nn
261 lx(:) = xmax(:) - xmin(:)
262 surf(j)%dmax = maxval(lx) * 0.5d0
270 real(kind=kreal),
intent(in) :: x0(3)
271 real(kind=kreal),
intent(in) :: exp_rate
272 real(kind=kreal) :: dist(3), er
273 er = max(exp_rate, 1.d0)
274 dist(:) = abs(x0(:) - surf%xavg(:))
275 if ( maxval(dist(:)) < surf%dmax * er )
then
285 type(bucketdb),
intent(inout) :: bktDB
286 real(kind=kreal) :: x_min(3), x_max(3), d_max
287 integer(kind=kint) :: nsurf, i, j
288 if (debug >= 1)
write(0,*)
'DEBUG: update_surface_bucket_info: start'
290 if (nsurf == 0)
return
291 x_min(:) = surf(1)%xavg(:)
292 x_max(:) = surf(1)%xavg(:)
293 d_max = surf(1)%dmax*2.d0
296 if (surf(i)%xavg(j) < x_min(j)) x_min(j) = surf(i)%xavg(j)
297 if (surf(i)%xavg(j) > x_max(j)) x_max(j) = surf(i)%xavg(j)
298 if (surf(i)%dmax > d_max) d_max = surf(i)%dmax
302 x_min(j) = x_min(j) - d_max
303 x_max(j) = x_max(j) + d_max
316 if (debug >= 1)
write(0,*)
'DEBUG: update_surface_bucket_info: end'
323 real(kind=
kreal),
intent(in) :: elem(3,*)
325 integer(kind=kint) :: j, nn, etype
326 real(kind=
kreal) :: cnpos(2), normal(3)
329 nn =
size(surf%nodes)
334 normal = normal / dsqrt(dot_product(normal, normal))
335 surf%vertex_normals(:, j) = normal
343 real(kind=kreal),
intent(in) :: currpos(:)
345 integer(kind=kint) :: i, j, nn, iss
350 nn =
size(surf(i)%nodes)
352 iss = surf(i)%nodes(j)
353 elem(1:3, j) = currpos(3*iss-2:3*iss)
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.
integer(kind=kind(2)) function getnumberofnodes(etype)
Obtain number of nodes of the element.
subroutine getelementcenter(fetype, localcoord)
Return natural coordinate of the center of element.
integer, parameter fe_tri6n
subroutine getsubface(intype, innumber, outtype, nodes)
Find the definition of surface of the element.
subroutine getvertexcoord(fetype, cnode, localcoord)
Get the natural coord of a vertex node.
integer, parameter fe_tri3n
integer, parameter fe_quad4n
real(kind=kreal) function, dimension(3) surfacenormal(fetype, nn, localcoord, elecoord)
Calculate normal of 3d-surface.
real(kind=kreal) function getreferencelength(fetype, nn, localcoord, elecoord)
This function calculates reference length at a point in surface.
integer, parameter fe_quad8n
integer(kind=4), parameter kreal
This module provides aux functions.
This module manages surface elements in 3D It provides basic definition of surface elements (triangla...
subroutine initialize_surf(eid, etype, nsurf, surf)
Initializer.
integer(kind=kint), parameter l_max_elem_node
subroutine calc_surf_vertex_normals(surf, elem)
Compute vertex normals for a single surface element (geometric calculation only)
subroutine update_surface_reflen(surf, coord)
Compute reference length of surface elements.
subroutine write_surf(file, surf)
Write out elemental surface.
subroutine update_surface_box_info(surf, currpos)
Update info of cubic box including surface elements.
integer(kind=kint), parameter l_max_elem_surf
subroutine find_surface_neighbor(surf, bktDB)
Find neighboring surface elements.
integer(kind=kint), parameter n_neighbor_max_init
subroutine update_surface_bucket_info(surf, bktDB)
Update bucket info for searching surface elements.
integer(kind=kint), parameter l_max_surface_node
subroutine finalize_surf(surf)
Memory management subroutine.
logical function is_in_surface_box(surf, x0, exp_rate)
Check if given point is within cubic box including surface element.
subroutine calc_all_surf_vertex_normals(surf, currpos)
Calculate vertex normals for all surface elements (geometric calculation only)
integer(kind=kint) function next_position(surf, cpos)
Tracing next contact position.
Structure to define surface group.