19 subroutine project_point2element(xyz,etype,nn,elemt,reflen,cstate,isin,distclr,penclr,ctpos,localclr)
20 real(kind=kreal),
intent(in) :: xyz(3)
21 integer,
intent(in) :: etype
22 integer,
intent(in) :: nn
23 real(kind=kreal),
intent(in) :: elemt(:,:)
24 real(kind=kreal),
intent(in) :: reflen
26 logical,
intent(out) :: isin
27 real(kind=kreal),
intent(in) :: distclr
28 real(kind=kreal),
intent(in) :: penclr
29 real(kind=kreal),
optional :: ctpos(2)
30 real(kind=kreal),
optional :: localclr
32 integer :: count,order
33 real(kind=kreal) :: determ, inverse(2,2)
34 real(kind=kreal) :: sfunc(nn), curv(3,2,2)
35 real(kind=kreal) :: r(2), dr(2), r_tmp(2)
36 real(kind=kreal) :: xyz_out(3)
37 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
38 real(kind=kreal) :: tangent(3,2)
39 real(kind=kreal) :: df(2),d2f(2,2),normal(3)
40 real(kind=kreal),
parameter :: eps = 1.0d-8
41 real(kind=kreal) :: clr, tol, factor
44 if(
present( localclr ) ) clr=localclr
45 if(
present( ctpos ) )
then
54 xyz_out = matmul( elemt(1:3,1:nn), sfunc )
55 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
56 dist_last = dot_product( dxyz, dxyz(:) )
58 call tangentbase( etype, nn, r, elemt(1:3,1:nn), tangent )
59 call curvature( etype, nn, r, elemt(1:3,1:nn), curv )
62 df(1:2) = -matmul( dxyz(:), tangent(:,:) )
64 d2f(1,1)= dot_product( tangent(:,1), tangent(:,1) ) - dot_product( dxyz, curv(:,1,1) )
65 d2f(1,2)= dot_product( tangent(:,1), tangent(:,2) ) - dot_product( dxyz, curv(:,1,2) )
66 d2f(2,1)= dot_product( tangent(:,2), tangent(:,1) ) - dot_product( dxyz, curv(:,2,1) )
67 d2f(2,2)= dot_product( tangent(:,2), tangent(:,2) ) - dot_product( dxyz, curv(:,2,2) )
70 determ = d2f(1,1)*d2f(2,2) - d2f(1,2)*d2f(2,1)
71 if( determ==0.d0 ) stop
"Math error in contact searching"
72 inverse(1,1) = d2f(2,2) / determ
73 inverse(2,2) = d2f(1,1) / determ
74 inverse(1,2) = -d2f(1,2) / determ
75 inverse(2,1) = -d2f(2,1) / determ
78 tol=dot_product(dr,dr)
79 if( dsqrt(tol)> 3.d0 )
then
85 r_tmp(1:2) = r(1:2) + factor*dr(1:2)
87 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(:) )
88 dxyz(1:3) = xyz(1:3)-xyz_out(:)
89 dist_now = dot_product( dxyz, dxyz )
90 if(dist_now <= dist_last)
exit
103 dxyz(:)=xyz_out(:)-xyz(:)
105 normal(:) = normal(:)/dsqrt( dot_product(normal, normal) )
107 if( dabs(normal(count))<1.d-10 ) normal(count) =0.d0
108 if( dabs(1.d0-dabs(normal(count)))<1.d-10 ) normal(count) =sign(1.d0, normal(count))
110 cstate%distance = dot_product( dxyz, normal )
112 if( cstate%interference_flag ==
c_if_slave)
then
113 if( cstate%init_pos == 0.d0 .and. cstate%distance < cstate%end_pos)
then
114 cstate%init_pos = cstate%distance
115 cstate%time_factor = (cstate%end_pos - cstate%distance) / cstate%time_factor
116 cstate%shrink_factor = cstate%distance
120 if( cstate%interference_flag == 0)
then
121 if( cstate%distance < distclr*reflen .and. cstate%distance > -penclr*reflen ) isin = .true.
123 if( cstate%distance < cstate%shrink_factor + distclr*reflen ) isin = .true.
128 cstate%gpos(:)=xyz_out(:)
129 cstate%lpos(1:2)=r(:)
130 cstate%direction(:) = normal(:)
131 cstate%wkdist = cstate%distance
139 real(kind=kreal),
intent(in) :: xyz(3)
140 integer,
intent(in) :: etype
141 integer,
intent(in) :: nn
142 real(kind=kreal),
intent(in) :: elemt(:,:)
143 real(kind=kreal),
intent(in) :: reflen
145 logical,
intent(out) :: isin
146 real(kind=kreal),
intent(in) :: distclr
147 real(kind=kreal),
optional :: ctpos(3)
148 real(kind=kreal),
optional :: localclr
150 integer :: count,order
151 real(kind=kreal) :: inverse(3,3)
152 real(kind=kreal) :: sfunc(nn), deriv(nn,3)
153 real(kind=kreal) :: r(3), dr(3), r_tmp(3)
154 real(kind=kreal) :: xyz_out(3)
155 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
156 real(kind=kreal),
parameter :: eps = 1.0d-8
157 real(kind=kreal) :: clr, tol, factor
160 if(
present( localclr ) ) clr=localclr
161 if(
present( ctpos ) )
then
170 xyz_out = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
171 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
172 dist_last = dot_product( dxyz, dxyz(:) )
175 inverse(1:3,1:3) = matmul(elemt(1:3,1:nn),deriv(1:nn,1:3))
177 dr(1:3) = -matmul(inverse(1:3,1:3),dxyz(1:3))
179 tol=dot_product(dr,dr)
180 if( count > 1 .and. dsqrt(tol)> 3.d0 )
then
186 r_tmp(1:3) = r(1:3) + factor*dr(1:3)
188 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
189 dxyz(1:3) = xyz(1:3)-xyz_out(1:3)
190 dist_now = dot_product( dxyz, dxyz )
191 if(dist_now <= dist_last)
exit
192 factor = factor*0.7d0
201 dxyz(:)=xyz_out(:)-xyz(:)
202 cstate%distance = dsqrt(dot_product( dxyz, dxyz ))
204 if( cstate%distance < distclr ) isin = .true.
208 cstate%gpos(:)=xyz_out(:)
209 cstate%direction(:) = (/1.d0,0.d0,0.d0/)
210 cstate%lpos(1:3)=r(:)
218 real(kind=kreal),
intent(in) :: xyz(3)
219 type(tsurfelement),
intent(in) :: surf
220 real(kind=kreal),
intent(in) :: currpos(:)
222 logical,
intent(out) :: isin
223 real(kind=kreal),
intent(in) :: distclr
224 real(kind=kreal),
intent(in) :: penclr
225 real(kind=kreal),
optional,
intent(in) :: ctpos(2)
226 real(kind=kreal),
optional,
intent(in) :: localclr
227 integer(kind=kint),
intent(in) :: smoothing
229 integer(kind=kint) :: nn, j, iss, etype_use, nn_use
230 real(kind=kreal) :: elem(3, l_max_elem_node)
231 real(kind=kreal) :: elem_tri3n(3, 3)
234 nn =
size(surf%nodes)
237 elem(1:3, j) = currpos(3*iss-2:3*iss)
242 elem_tri3n = elem(1:3, 1:3)
248 elem(1:3, nn+j) = surf%intermediate_points(1:3, j)
253 etype_use = surf%etype
257 etype_use = surf%etype
262 isin, distclr, penclr, ctpos, localclr)
274 cstate, isin, distclr, penclr, ctpos, localclr )
275 real(kind=kreal),
intent(in) :: coord(3)
276 type(tsurfelement),
intent(in) :: master_surf
278 real(kind=kreal),
intent(in) :: ncoord(2)
279 real(kind=kreal),
intent(in) :: currpos(:)
281 logical,
intent(out) :: isin
282 real(kind=kreal),
intent(in) :: distclr
283 real(kind=kreal),
intent(in) :: penclr
284 real(kind=kreal),
optional,
intent(in) :: ctpos(2)
285 real(kind=kreal),
optional,
intent(in) :: localclr
287 integer(kind=kint) :: nnode_s, j, islave
288 real(kind=kreal) :: slave_pos(3, l_max_elem_node), normal(3)
293 if( .not. isin )
return
295 nnode_s =
size(ssurf%nodes)
297 islave = ssurf%nodes(j)
298 slave_pos(:,j) = currpos(3*islave-2:3*islave)
300 normal(:) = -
surfacenormal( ssurf%etype, nnode_s, ncoord, slave_pos )
301 cstate%direction(:) = normal(:) / dsqrt( dot_product(normal, normal) )
306 real(kind=kreal),
intent(in) :: pos(2)
307 integer,
intent(in) :: etype
308 real(kind=kreal),
intent(in) :: ele(:,:)
309 real(kind=kreal),
intent(out) :: tensor(2,2)
312 real(kind=kreal) :: tangent(3,2)
315 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
316 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
317 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
318 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
324 real(kind=kreal),
intent(in) :: pos(2)
325 integer,
intent(in) :: etype
326 integer,
intent(in) :: nnode
327 real(kind=kreal),
intent(in) :: ele(3,nnode)
328 real(kind=kreal),
intent(out) :: tangent(3,2)
329 real(kind=kreal),
intent(out) :: tensor(2,2)
330 real(kind=kreal),
intent(out) :: matrix(2,nnode*3+3)
333 real(kind=kreal) :: det
334 real(kind=kreal) :: shapefunc(nnode), t1(nnode*3+3), t2(nnode*3+3)
335 call tangentbase( etype, nnode, pos, ele, tangent )
336 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
337 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
338 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
339 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
340 det = tensor(1,1)*tensor(2,2)-tensor(1,2)*tensor(2,1)
341 if( det==0.d0 ) stop
"Error in calculate DispIncreMatrix"
349 t1( j ) = tangent(j,1)
350 t2( j ) = tangent(j,2)
352 forall( i=1:nnode, j=1:3 )
353 t1( i*3+j ) = -tangent(j,1)*shapefunc(i)
354 t2( i*3+j ) = -tangent(j,2)*shapefunc(i)
357 matrix(1,:) = (tensor(2,2)*t1(:)-tensor(1,2)*t2(:))/det
358 matrix(2,:) = (tensor(1,1)*t2(:)-tensor(2,1)*t1(:))/det
359 tangent(:,1) = tangent(:,1)/dsqrt(dot_product(tangent(:,1),tangent(:,1)))
360 tangent(:,2) = tangent(:,2)/dsqrt(dot_product(tangent(:,2),tangent(:,2)))
365 integer,
intent(in) :: nslave
366 type(
tcontact ),
intent(inout) :: contact
367 real(kind=kreal),
intent(in) :: currpos(:)
369 integer(kind=kint) :: slave, sid0, etype, iSS
370 real(kind=kreal) :: coord(3)
374 slave = contact%slave(nslave)
375 coord(:) = currpos(3*slave-2:3*slave)
377 sid0 = contact%states(nslave)%surface
379 cstate_tmp = contact%states(nslave)
381 cstate_tmp, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
382 contact%states(nslave)%lpos, contact%cparam%CLR_SAME_ELEM, &
383 smoothing=contact%smoothing )
386 etype = contact%master(sid0)%etype
387 iss =
isinsideelement( etype, cstate_tmp%lpos, contact%cparam%CLR_CAL_NORM )
388 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
389 call cal_node_normal( cstate_tmp%surface, iss, contact%master, currpos, &
390 cstate_tmp%lpos, cstate_tmp%direction(:) )
393 contact%states(nslave)%direction = cstate_tmp%direction
400 integer,
intent(in) :: csurf
401 integer,
intent(in) :: isin
402 type(tsurfelement),
intent(in) :: surf(:)
403 real(kind=kreal),
intent(in) :: currpos(:)
404 real(kind=kreal),
intent(in) :: lpos(:)
405 real(kind=kreal),
intent(out) :: normal(3)
406 integer(kind=kint) :: cnode, i, j, cnt, nd1, gn, etype, iss, nn,
cgn
407 real(kind=kreal) :: cnpos(2), elem(3, l_max_elem_node)
408 integer(kind=kint) :: cnode1, cnode2, gn1, gn2, nsurf, cgn1, cgn2, isin_n
409 real(kind=kreal) :: x, normal_n(3), lpos_n(2)
411 if( 1 <= isin .and. isin <= 4 )
then
413 gn = surf(csurf)%nodes(cnode)
414 etype = surf(csurf)%etype
416 nn =
size( surf(csurf)%nodes )
418 iss = surf(csurf)%nodes(j)
419 elem(1:3,j)=currpos(3*iss-2:3*iss)
423 do i=1,surf(csurf)%n_neighbor
424 nd1 = surf(csurf)%neighbor(i)
425 nn =
size( surf(nd1)%nodes )
426 etype = surf(nd1)%etype
429 iss = surf(nd1)%nodes(j)
430 elem(1:3,j)=currpos(3*iss-2:3*iss)
437 normal = normal+normal_n
442 elseif( 12 <= isin .and. isin <= 41 )
then
444 cnode2 = mod(isin, 10)
445 gn1 = surf(csurf)%nodes(cnode1)
446 gn2 = surf(csurf)%nodes(cnode2)
447 etype = surf(csurf)%etype
448 nn =
size( surf(csurf)%nodes )
450 iss = surf(csurf)%nodes(j)
451 elem(1:3,j)=currpos(3*iss-2:3*iss)
455 case (fe_tri3n, fe_tri6n, fe_tri6nc)
456 if ( isin==12 ) then; x=lpos(2)-lpos(1)
457 elseif( isin==23 ) then; x=1.d0-2.d0*lpos(2)
458 elseif( isin==31 ) then; x=2.d0*lpos(1)-1.d0
459 else; stop
"Error: cal_node_normal: invalid isin"
461 case (fe_quad4n, fe_quad8n)
462 if ( isin==12 ) then; x=lpos(1)
463 elseif( isin==23 ) then; x=lpos(2)
464 elseif( isin==34 ) then; x=-lpos(1)
465 elseif( isin==41 ) then; x=-lpos(2)
466 else; stop
"Error: cal_node_normal: invalid isin"
471 neib_loop:
do i=1, surf(csurf)%n_neighbor
472 nd1 = surf(csurf)%neighbor(i)
473 nn =
size( surf(nd1)%nodes )
474 etype = surf(nd1)%etype
478 iss = surf(nd1)%nodes(j)
479 elem(1:3,j)=currpos(3*iss-2:3*iss)
480 if( iss==gn1 ) cgn1=j
481 if( iss==gn2 ) cgn2=j
483 if( cgn1>0 .and. cgn2>0 )
then
485 isin_n = 10*cgn2 + cgn1
488 case (fe_tri3n, fe_tri6n, fe_tri6nc)
489 if ( isin_n==12 ) then; lpos_n(1)=0.5d0*(1.d0-x); lpos_n(2)=0.5d0*(1.d0+x)
490 elseif( isin_n==23 ) then; lpos_n(1)=0.d0; lpos_n(2)=0.5d0*(1.d0-x)
491 elseif( isin_n==31 ) then; lpos_n(1)=0.5d0*(1.d0+x); lpos_n(2)=0.d0
492 else; stop
"Error: cal_node_normal: invalid isin_n"
494 case (fe_quad4n, fe_quad8n)
495 if ( isin_n==12 ) then; lpos_n(1)= x; lpos_n(2)=-1.d0
496 elseif( isin_n==23 ) then; lpos_n(1)= 1.d0; lpos_n(2)= x
497 elseif( isin_n==34 ) then; lpos_n(1)=-x; lpos_n(2)= 1.d0
498 elseif( isin_n==41 ) then; lpos_n(1)=-1.d0; lpos_n(2)=-x
499 else; stop
"Error: cal_node_normal: invalid isin_n"
504 normal = normal+normal_n
511 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.
integer, parameter fe_tri6n
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.
integer, parameter fe_tri3n
subroutine tangentbase(fetype, nn, localcoord, elecoord, tangent)
Calculate base vector of tangent space of 3d surface.
integer, parameter fe_quad4n
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.
integer, parameter fe_quad8n
This module provides aux functions.
subroutine calinverse(NN, A)
calculate inverse of matrix a