19 real(kind=kreal),
intent(in) :: xyz(3)
20 integer,
intent(in) :: etype
21 integer,
intent(in) :: nn
22 real(kind=kreal),
intent(in) :: elemt(:,:)
23 real(kind=kreal),
intent(in) :: reflen
25 logical,
intent(out) :: isin
26 real(kind=kreal),
intent(in) :: distclr
27 real(kind=kreal),
optional :: ctpos(2)
28 real(kind=kreal),
optional :: localclr
30 integer :: count,order, initstate
31 real(kind=kreal) :: determ, inverse(2,2)
32 real(kind=kreal) :: sfunc(nn), curv(3,2,2)
33 real(kind=kreal) :: r(2), dr(2), r_tmp(2)
34 real(kind=kreal) :: xyz_out(3)
35 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
36 real(kind=kreal) :: tangent(3,2)
37 real(kind=kreal) :: df(2),d2f(2,2),normal(3)
38 real(kind=kreal),
parameter :: eps = 1.0d-8
39 real(kind=kreal) :: clr, tol, factor
41 initstate = cstate%state
43 if(
present( localclr ) ) clr=localclr
44 if(
present( ctpos ) )
then
53 xyz_out = matmul( elemt(1:3,1:nn), sfunc )
54 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
55 dist_last = dot_product( dxyz, dxyz(:) )
57 call tangentbase( etype, nn, r, elemt(1:3,1:nn), tangent )
58 call curvature( etype, nn, r, elemt(1:3,1:nn), curv )
61 df(1:2) = -matmul( dxyz(:), tangent(:,:) )
63 d2f(1,1)= dot_product( tangent(:,1), tangent(:,1) ) - dot_product( dxyz, curv(:,1,1) )
64 d2f(1,2)= dot_product( tangent(:,1), tangent(:,2) ) - dot_product( dxyz, curv(:,1,2) )
65 d2f(2,1)= dot_product( tangent(:,2), tangent(:,1) ) - dot_product( dxyz, curv(:,2,1) )
66 d2f(2,2)= dot_product( tangent(:,2), tangent(:,2) ) - dot_product( dxyz, curv(:,2,2) )
69 determ = d2f(1,1)*d2f(2,2) - d2f(1,2)*d2f(2,1)
70 if( determ==0.d0 ) stop
"Math error in contact searching"
71 inverse(1,1) = d2f(2,2) / determ
72 inverse(2,2) = d2f(1,1) / determ
73 inverse(1,2) = -d2f(1,2) / determ
74 inverse(2,1) = -d2f(2,1) / determ
77 tol=dot_product(dr,dr)
78 if( dsqrt(tol)> 3.d0 )
then
84 r_tmp(1:2) = r(1:2) + factor*dr(1:2)
86 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(:) )
87 dxyz(1:3) = xyz(1:3)-xyz_out(:)
88 dist_now = dot_product( dxyz, dxyz )
89 if(dist_now <= dist_last)
exit
100 dxyz(:)=xyz_out(:)-xyz(:)
102 normal(:) = normal(:)/dsqrt( dot_product(normal, normal) )
104 if( dabs(normal(count))<1.d-10 ) normal(count) =0.d0
105 if( dabs(1.d0-dabs(normal(count)))<1.d-10 ) normal(count) =sign(1.d0, normal(count))
107 cstate%distance = dot_product( dxyz, normal )
109 if( cstate%interference_flag ==
c_if_slave)
then
110 if( cstate%init_pos == 0.d0 .and. cstate%distance < cstate%end_pos)
then
111 cstate%init_pos = cstate%distance
112 cstate%time_factor = (cstate%end_pos - cstate%distance) / cstate%time_factor
113 cstate%shrink_factor = cstate%distance
117 if( cstate%interference_flag == 0)
then
118 if( cstate%distance < distclr*reflen .and. cstate%distance > -5.0d-01*reflen ) isin = .true.
120 if( cstate%distance < cstate%shrink_factor + distclr*reflen ) isin = .true.
127 cstate%state = initstate
129 cstate%gpos(:)=xyz_out(:)
130 cstate%lpos(1:2)=r(:)
131 cstate%direction(:) = normal(:)
132 cstate%wkdist = cstate%distance
140 real(kind=kreal),
intent(in) :: xyz(3)
141 integer,
intent(in) :: etype
142 integer,
intent(in) :: nn
143 real(kind=kreal),
intent(in) :: elemt(:,:)
144 real(kind=kreal),
intent(in) :: reflen
146 logical,
intent(out) :: isin
147 real(kind=kreal),
intent(in) :: distclr
148 real(kind=kreal),
optional :: ctpos(3)
149 real(kind=kreal),
optional :: localclr
151 integer :: count,order, initstate
152 real(kind=kreal) :: inverse(3,3)
153 real(kind=kreal) :: sfunc(nn), deriv(nn,3)
154 real(kind=kreal) :: r(3), dr(3), r_tmp(3)
155 real(kind=kreal) :: xyz_out(3)
156 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
157 real(kind=kreal),
parameter :: eps = 1.0d-8
158 real(kind=kreal) :: clr, tol, factor
160 initstate = cstate%state
162 if(
present( localclr ) ) clr=localclr
163 if(
present( ctpos ) )
then
172 xyz_out = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
173 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
174 dist_last = dot_product( dxyz, dxyz(:) )
177 inverse(1:3,1:3) = matmul(elemt(1:3,1:nn),deriv(1:nn,1:3))
179 dr(1:3) = -matmul(inverse(1:3,1:3),dxyz(1:3))
181 tol=dot_product(dr,dr)
182 if( count > 1 .and. dsqrt(tol)> 3.d0 )
then
188 r_tmp(1:3) = r(1:3) + factor*dr(1:3)
190 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
191 dxyz(1:3) = xyz(1:3)-xyz_out(1:3)
192 dist_now = dot_product( dxyz, dxyz )
193 if(dist_now <= dist_last)
exit
194 factor = factor*0.7d0
204 dxyz(:)=xyz_out(:)-xyz(:)
205 cstate%distance = dsqrt(dot_product( dxyz, dxyz ))
207 if( cstate%distance < distclr ) isin = .true.
213 cstate%state = initstate
215 cstate%gpos(:)=xyz_out(:)
216 cstate%direction(:) = (/1.d0,0.d0,0.d0/)
217 cstate%lpos(1:3)=r(:)
225 real(kind=kreal),
intent(in) :: xyz(3)
226 type(tsurfelement),
intent(in) :: surf
227 real(kind=kreal),
intent(in) :: currpos(:)
229 logical,
intent(out) :: isin
230 real(kind=kreal),
intent(in) :: distclr
231 real(kind=kreal),
optional,
intent(in) :: ctpos(2)
232 real(kind=kreal),
optional,
intent(in) :: localclr
234 integer(kind=kint) :: nn, j, iss
235 real(kind=kreal) :: elem(3, l_max_elem_node)
238 nn =
size(surf%nodes)
241 elem(1:3, j) = currpos(3*iss-2:3*iss)
245 isin, distclr, ctpos, localclr)
251 real(kind=kreal),
intent(in) :: pos(2)
252 integer,
intent(in) :: etype
253 real(kind=kreal),
intent(in) :: ele(:,:)
254 real(kind=kreal),
intent(out) :: tensor(2,2)
257 real(kind=kreal) :: tangent(3,2)
260 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
261 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
262 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
263 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
269 real(kind=kreal),
intent(in) :: pos(2)
270 integer,
intent(in) :: etype
271 integer,
intent(in) :: nnode
272 real(kind=kreal),
intent(in) :: ele(3,nnode)
273 real(kind=kreal),
intent(out) :: tangent(3,2)
274 real(kind=kreal),
intent(out) :: tensor(2,2)
275 real(kind=kreal),
intent(out) :: matrix(2,nnode*3+3)
278 real(kind=kreal) :: det
279 real(kind=kreal) :: shapefunc(nnode), t1(nnode*3+3), t2(nnode*3+3)
280 call tangentbase( etype, nnode, pos, ele, tangent )
281 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
282 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
283 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
284 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
285 det = tensor(1,1)*tensor(2,2)-tensor(1,2)*tensor(2,1)
286 if( det==0.d0 ) stop
"Error in calculate DispIncreMatrix"
294 t1( j ) = tangent(j,1)
295 t2( j ) = tangent(j,2)
297 forall( i=1:nnode, j=1:3 )
298 t1( i*3+j ) = -tangent(j,1)*shapefunc(i)
299 t2( i*3+j ) = -tangent(j,2)*shapefunc(i)
302 matrix(1,:) = (tensor(2,2)*t1(:)-tensor(1,2)*t2(:))/det
303 matrix(2,:) = (tensor(1,1)*t2(:)-tensor(2,1)*t1(:))/det
304 tangent(:,1) = tangent(:,1)/dsqrt(dot_product(tangent(:,1),tangent(:,1)))
305 tangent(:,2) = tangent(:,2)/dsqrt(dot_product(tangent(:,2),tangent(:,2)))
310 integer,
intent(in) :: nslave
311 type(
tcontact ),
intent(inout) :: contact
312 real(kind=kreal),
intent(in) :: currpos(:)
314 integer(kind=kint) :: slave, sid0, etype, iSS
315 real(kind=kreal) :: coord(3)
317 real(kind=kreal) :: opos(2), odirec(3)
320 slave = contact%slave(nslave)
321 coord(:) = currpos(3*slave-2:3*slave)
323 sid0 = contact%states(nslave)%surface
324 opos = contact%states(nslave)%lpos(1:2)
325 odirec = contact%states(nslave)%direction
327 cstate_tmp%state = contact%states(nslave)%state
328 cstate_tmp%surface = sid0
330 cstate_tmp, isin, contact%cparam%DISTCLR_NOCHECK, &
331 contact%states(nslave)%lpos, contact%cparam%CLR_SAME_ELEM )
334 etype = contact%master(sid0)%etype
335 iss =
isinsideelement( etype, cstate_tmp%lpos, contact%cparam%CLR_CAL_NORM )
337 call cal_node_normal( cstate_tmp%surface, iss, contact%master, currpos, &
338 cstate_tmp%lpos, cstate_tmp%direction(:) )
341 contact%states(nslave)%direction = cstate_tmp%direction
348 integer,
intent(in) :: csurf
349 integer,
intent(in) :: isin
350 type(tsurfelement),
intent(in) :: surf(:)
351 real(kind=kreal),
intent(in) :: currpos(:)
352 real(kind=kreal),
intent(in) :: lpos(:)
353 real(kind=kreal),
intent(out) :: normal(3)
354 integer(kind=kint) :: cnode, i, j, cnt, nd1, gn, etype, iss, nn,
cgn
355 real(kind=kreal) :: cnpos(2), elem(3, l_max_elem_node)
356 integer(kind=kint) :: cnode1, cnode2, gn1, gn2, nsurf, cgn1, cgn2, isin_n
357 real(kind=kreal) :: x=0, normal_n(3), lpos_n(2)
359 if( 1 <= isin .and. isin <= 4 )
then
361 gn = surf(csurf)%nodes(cnode)
362 etype = surf(csurf)%etype
364 nn =
size( surf(csurf)%nodes )
366 iss = surf(csurf)%nodes(j)
367 elem(1:3,j)=currpos(3*iss-2:3*iss)
371 do i=1,surf(csurf)%n_neighbor
372 nd1 = surf(csurf)%neighbor(i)
373 nn =
size( surf(nd1)%nodes )
374 etype = surf(nd1)%etype
377 iss = surf(nd1)%nodes(j)
378 elem(1:3,j)=currpos(3*iss-2:3*iss)
385 normal = normal+normal_n
390 elseif( 12 <= isin .and. isin <= 41 )
then
392 cnode2 = mod(isin, 10)
393 gn1 = surf(csurf)%nodes(cnode1)
394 gn2 = surf(csurf)%nodes(cnode2)
395 etype = surf(csurf)%etype
396 nn =
size( surf(csurf)%nodes )
398 iss = surf(csurf)%nodes(j)
399 elem(1:3,j)=currpos(3*iss-2:3*iss)
403 case (fe_tri3n, fe_tri6n, fe_tri6nc)
404 if ( isin==12 ) then; x=lpos(2)-lpos(1)
405 elseif( isin==23 ) then; x=1.d0-2.d0*lpos(2)
406 elseif( isin==31 ) then; x=2.d0*lpos(1)-1.d0
407 else; stop
"Error: cal_node_normal: invalid isin"
409 case (fe_quad4n, fe_quad8n)
410 if ( isin==12 ) then; x=lpos(1)
411 elseif( isin==23 ) then; x=lpos(2)
412 elseif( isin==34 ) then; x=-lpos(1)
413 elseif( isin==41 ) then; x=-lpos(2)
414 else; stop
"Error: cal_node_normal: invalid isin"
419 neib_loop:
do i=1, surf(csurf)%n_neighbor
420 nd1 = surf(csurf)%neighbor(i)
421 nn =
size( surf(nd1)%nodes )
422 etype = surf(nd1)%etype
426 iss = surf(nd1)%nodes(j)
427 elem(1:3,j)=currpos(3*iss-2:3*iss)
428 if( iss==gn1 ) cgn1=j
429 if( iss==gn2 ) cgn2=j
431 if( cgn1>0 .and. cgn2>0 )
then
433 isin_n = 10*cgn2 + cgn1
436 case (fe_tri3n, fe_tri6n, fe_tri6nc)
437 if ( isin_n==12 ) then; lpos_n(1)=0.5d0*(1.d0-x); lpos_n(2)=0.5d0*(1.d0+x)
438 elseif( isin_n==23 ) then; lpos_n(1)=0.d0; lpos_n(2)=0.5d0*(1.d0-x)
439 elseif( isin_n==31 ) then; lpos_n(1)=0.5d0*(1.d0+x); lpos_n(2)=0.d0
440 else; stop
"Error: cal_node_normal: invalid isin_n"
442 case (fe_quad4n, fe_quad8n)
443 if ( isin_n==12 ) then; lpos_n(1)= x; lpos_n(2)=-1.d0
444 elseif( isin_n==23 ) then; lpos_n(1)= 1.d0; lpos_n(2)= x
445 elseif( isin_n==34 ) then; lpos_n(1)=-x; lpos_n(2)= 1.d0
446 elseif( isin_n==41 ) then; lpos_n(1)=-1.d0; lpos_n(2)=-x
447 else; stop
"Error: cal_node_normal: invalid isin_n"
452 normal = normal+normal_n
459 normal = normal/ dsqrt( dot_product( normal, normal ) )
This module encapsulate the basic functions of all elements provide by this software.
subroutine getshapefunc(fetype, localcoord, func)
Calculate the shape function in natural coordinate system.
integer(kind=kind(2)) function getnumberofnodes(etype)
Obtain number of nodes of the element.
integer function isinside3delement(fetype, localcoord, clearance)
if a point is inside a surface element -1: No; 0: Yes; >0: Node's (vertex) number
subroutine getelementcenter(fetype, localcoord)
Return natural coordinate of the center of element.
subroutine getshapederiv(fetype, localcoord, shapederiv)
Calculate derivatives of shape function in natural coordinate system.
subroutine getvertexcoord(fetype, cnode, localcoord)
Get the natural coord of a vertex node.
subroutine tangentbase(fetype, nn, localcoord, elecoord, tangent)
Calculate base vector of tangent space of 3d surface.
integer function isinsideelement(fetype, localcoord, clearance)
if a point is inside a surface element -1: No; 0: Yes; >0: Node's (vertex) number
real(kind=kreal) function, dimension(3) surfacenormal(fetype, nn, localcoord, elecoord)
Calculate normal of 3d-surface.
subroutine curvature(fetype, nn, localcoord, elecoord, l2ndderiv, normal, curv)
Calculate curvature tensor at a point along 3d surface.
This module provides aux functions.
subroutine calinverse(NN, A)
calculate inverse of matrix a