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(:,:)
144 logical,
intent(out) :: isin
145 real(kind=kreal),
intent(in) :: distclr
146 real(kind=kreal),
optional :: ctpos(3)
147 real(kind=kreal),
optional :: localclr
149 integer :: count,order
150 real(kind=kreal) :: inverse(3,3)
151 real(kind=kreal) :: sfunc(nn), deriv(nn,3)
152 real(kind=kreal) :: r(3), dr(3), r_tmp(3)
153 real(kind=kreal) :: xyz_out(3)
154 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
155 real(kind=kreal),
parameter :: eps = 1.0d-8
156 real(kind=kreal) :: clr, tol, factor
159 if(
present( localclr ) ) clr=localclr
160 if(
present( ctpos ) )
then
169 xyz_out = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
170 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
171 dist_last = dot_product( dxyz, dxyz(:) )
174 inverse(1:3,1:3) = matmul(elemt(1:3,1:nn),deriv(1:nn,1:3))
176 dr(1:3) = -matmul(inverse(1:3,1:3),dxyz(1:3))
178 tol=dot_product(dr,dr)
179 if( count > 1 .and. dsqrt(tol)> 3.d0 )
then
185 r_tmp(1:3) = r(1:3) + factor*dr(1:3)
187 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
188 dxyz(1:3) = xyz(1:3)-xyz_out(1:3)
189 dist_now = dot_product( dxyz, dxyz )
190 if(dist_now <= dist_last)
exit
191 factor = factor*0.7d0
200 dxyz(:)=xyz_out(:)-xyz(:)
201 cstate%distance = dsqrt(dot_product( dxyz, dxyz ))
203 if( cstate%distance < distclr ) isin = .true.
207 cstate%gpos(:)=xyz_out(:)
208 cstate%direction(:) = (/1.d0,0.d0,0.d0/)
209 cstate%lpos(1:3)=r(:)
217 real(kind=kreal),
intent(in) :: xyz(3)
218 type(tsurfelement),
intent(in) :: surf
219 real(kind=kreal),
intent(in) :: currpos(:)
221 logical,
intent(out) :: isin
222 real(kind=kreal),
intent(in) :: distclr
223 real(kind=kreal),
intent(in) :: penclr
224 real(kind=kreal),
optional,
intent(in) :: ctpos(2)
225 real(kind=kreal),
optional,
intent(in) :: localclr
226 integer(kind=kint),
intent(in) :: smoothing
228 integer(kind=kint) :: nn, j, iss, etype_use, nn_use
229 real(kind=kreal) :: elem(3, l_max_elem_node)
230 real(kind=kreal) :: elem_tri3n(3, 3)
233 nn =
size(surf%nodes)
236 elem(1:3, j) = currpos(3*iss-2:3*iss)
241 elem_tri3n = elem(1:3, 1:3)
247 elem(1:3, nn+j) = surf%intermediate_points(1:3, j)
252 etype_use = surf%etype
256 etype_use = surf%etype
261 isin, distclr, penclr, ctpos, localclr)
273 cstate, isin, distclr, penclr, ctpos, localclr )
274 real(kind=kreal),
intent(in) :: coord(3)
275 type(tsurfelement),
intent(in) :: master_surf
277 real(kind=kreal),
intent(in) :: ncoord(2)
278 real(kind=kreal),
intent(in) :: currpos(:)
280 logical,
intent(out) :: isin
281 real(kind=kreal),
intent(in) :: distclr
282 real(kind=kreal),
intent(in) :: penclr
283 real(kind=kreal),
optional,
intent(in) :: ctpos(2)
284 real(kind=kreal),
optional,
intent(in) :: localclr
286 integer(kind=kint) :: nnode_s, j, islave
287 real(kind=kreal) :: slave_pos(3, l_max_elem_node), normal(3)
292 if( .not. isin )
return
294 nnode_s =
size(ssurf%nodes)
296 islave = ssurf%nodes(j)
297 slave_pos(:,j) = currpos(3*islave-2:3*islave)
299 normal(:) = -
surfacenormal( ssurf%etype, nnode_s, ncoord, slave_pos )
300 cstate%direction(:) = normal(:) / dsqrt( dot_product(normal, normal) )
305 real(kind=kreal),
intent(in) :: pos(2)
306 integer,
intent(in) :: etype
307 real(kind=kreal),
intent(in) :: ele(:,:)
308 real(kind=kreal),
intent(out) :: tensor(2,2)
311 real(kind=kreal) :: tangent(3,2)
314 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
315 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
316 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
317 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
323 real(kind=kreal),
intent(in) :: pos(2)
324 integer,
intent(in) :: etype
325 integer,
intent(in) :: nnode
326 real(kind=kreal),
intent(in) :: ele(3,nnode)
327 real(kind=kreal),
intent(out) :: tangent(3,2)
328 real(kind=kreal),
intent(out) :: tensor(2,2)
329 real(kind=kreal),
intent(out) :: matrix(2,nnode*3+3)
332 real(kind=kreal) :: det
333 real(kind=kreal) :: shapefunc(nnode), t1(nnode*3+3), t2(nnode*3+3)
334 call tangentbase( etype, nnode, pos, ele, tangent )
335 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
336 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
337 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
338 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
339 det = tensor(1,1)*tensor(2,2)-tensor(1,2)*tensor(2,1)
340 if( det==0.d0 ) stop
"Error in calculate DispIncreMatrix"
348 t1( j ) = tangent(j,1)
349 t2( j ) = tangent(j,2)
351 forall( i=1:nnode, j=1:3 )
352 t1( i*3+j ) = -tangent(j,1)*shapefunc(i)
353 t2( i*3+j ) = -tangent(j,2)*shapefunc(i)
356 matrix(1,:) = (tensor(2,2)*t1(:)-tensor(1,2)*t2(:))/det
357 matrix(2,:) = (tensor(1,1)*t2(:)-tensor(2,1)*t1(:))/det
358 tangent(:,1) = tangent(:,1)/dsqrt(dot_product(tangent(:,1),tangent(:,1)))
359 tangent(:,2) = tangent(:,2)/dsqrt(dot_product(tangent(:,2),tangent(:,2)))
364 integer,
intent(in) :: nslave
365 type(
tcontact ),
intent(inout) :: contact
366 real(kind=kreal),
intent(in) :: currpos(:)
368 integer(kind=kint) :: slave, sid0, etype, iSS
369 real(kind=kreal) :: coord(3)
373 slave = contact%slave(nslave)
374 coord(:) = currpos(3*slave-2:3*slave)
376 sid0 = contact%states(nslave)%surface
378 cstate_tmp = contact%states(nslave)
380 cstate_tmp, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
381 contact%states(nslave)%lpos, contact%cparam%CLR_SAME_ELEM, &
382 smoothing=contact%smoothing )
385 etype = contact%master(sid0)%etype
386 iss =
isinsideelement( etype, cstate_tmp%lpos, contact%cparam%CLR_CAL_NORM )
387 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
388 call cal_node_normal( cstate_tmp%surface, iss, contact%master, currpos, &
389 cstate_tmp%lpos, cstate_tmp%direction(:) )
392 contact%states(nslave)%direction = cstate_tmp%direction
399 integer,
intent(in) :: csurf
400 integer,
intent(in) :: isin
401 type(tsurfelement),
intent(in) :: surf(:)
402 real(kind=kreal),
intent(in) :: currpos(:)
403 real(kind=kreal),
intent(in) :: lpos(:)
404 real(kind=kreal),
intent(out) :: normal(3)
405 integer(kind=kint) :: cnode, i, j, cnt, nd1, gn, etype, iss, nn,
cgn
406 real(kind=kreal) :: cnpos(2), elem(3, l_max_elem_node)
407 integer(kind=kint) :: cnode1, cnode2, gn1, gn2, nsurf, cgn1, cgn2, isin_n
408 real(kind=kreal) :: x, normal_n(3), lpos_n(2)
410 if( 1 <= isin .and. isin <= 4 )
then
412 gn = surf(csurf)%nodes(cnode)
413 etype = surf(csurf)%etype
415 nn =
size( surf(csurf)%nodes )
417 iss = surf(csurf)%nodes(j)
418 elem(1:3,j)=currpos(3*iss-2:3*iss)
422 do i=1,surf(csurf)%n_neighbor
423 nd1 = surf(csurf)%neighbor(i)
424 nn =
size( surf(nd1)%nodes )
425 etype = surf(nd1)%etype
428 iss = surf(nd1)%nodes(j)
429 elem(1:3,j)=currpos(3*iss-2:3*iss)
436 normal = normal+normal_n
441 elseif( 12 <= isin .and. isin <= 41 )
then
443 cnode2 = mod(isin, 10)
444 gn1 = surf(csurf)%nodes(cnode1)
445 gn2 = surf(csurf)%nodes(cnode2)
446 etype = surf(csurf)%etype
447 nn =
size( surf(csurf)%nodes )
449 iss = surf(csurf)%nodes(j)
450 elem(1:3,j)=currpos(3*iss-2:3*iss)
454 case (fe_tri3n, fe_tri6n, fe_tri6nc)
455 if ( isin==12 ) then; x=lpos(2)-lpos(1)
456 elseif( isin==23 ) then; x=1.d0-2.d0*lpos(2)
457 elseif( isin==31 ) then; x=2.d0*lpos(1)-1.d0
458 else; stop
"Error: cal_node_normal: invalid isin"
460 case (fe_quad4n, fe_quad8n)
461 if ( isin==12 ) then; x=lpos(1)
462 elseif( isin==23 ) then; x=lpos(2)
463 elseif( isin==34 ) then; x=-lpos(1)
464 elseif( isin==41 ) then; x=-lpos(2)
465 else; stop
"Error: cal_node_normal: invalid isin"
470 neib_loop:
do i=1, surf(csurf)%n_neighbor
471 nd1 = surf(csurf)%neighbor(i)
472 nn =
size( surf(nd1)%nodes )
473 etype = surf(nd1)%etype
477 iss = surf(nd1)%nodes(j)
478 elem(1:3,j)=currpos(3*iss-2:3*iss)
479 if( iss==gn1 ) cgn1=j
480 if( iss==gn2 ) cgn2=j
482 if( cgn1>0 .and. cgn2>0 )
then
484 isin_n = 10*cgn2 + cgn1
487 case (fe_tri3n, fe_tri6n, fe_tri6nc)
488 if ( isin_n==12 ) then; lpos_n(1)=0.5d0*(1.d0-x); lpos_n(2)=0.5d0*(1.d0+x)
489 elseif( isin_n==23 ) then; lpos_n(1)=0.d0; lpos_n(2)=0.5d0*(1.d0-x)
490 elseif( isin_n==31 ) then; lpos_n(1)=0.5d0*(1.d0+x); lpos_n(2)=0.d0
491 else; stop
"Error: cal_node_normal: invalid isin_n"
493 case (fe_quad4n, fe_quad8n)
494 if ( isin_n==12 ) then; lpos_n(1)= x; lpos_n(2)=-1.d0
495 elseif( isin_n==23 ) then; lpos_n(1)= 1.d0; lpos_n(2)= x
496 elseif( isin_n==34 ) then; lpos_n(1)=-x; lpos_n(2)= 1.d0
497 elseif( isin_n==41 ) then; lpos_n(1)=-1.d0; lpos_n(2)=-x
498 else; stop
"Error: cal_node_normal: invalid isin_n"
503 normal = normal+normal_n
510 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