10 integer,
parameter,
private :: kreal = kind(0.0d0)
11 integer,
parameter,
private :: l_max_surface_node = 20
12 integer,
parameter,
private :: l_max_elem_node = 100
33 real(kind=kreal) :: distance
34 real(kind=kreal) :: wkdist
35 real(kind=kreal) :: lpos(3)
36 real(kind=kreal) :: gpos(3)
37 real(kind=kreal) :: direction(3)
38 real(kind=kreal) :: multiplier(3)
40 real(kind=kreal) :: tangentforce(3)
41 real(kind=kreal) :: tangentforce1(3)
42 real(kind=kreal) :: tangentforce_trial(3)
43 real(kind=kreal) :: tangentforce_final(3)
44 real(kind=kreal) :: reldisp(3)
46 real(kind=kreal) :: shrink_factor
47 real(kind=kreal) :: time_factor
48 real(kind=kreal) :: init_pos
49 real(kind=kreal) :: end_pos
50 integer :: interference_flag
60 cstate%distance = 0.0d0
62 cstate%lpos(:) = 0.0d0
63 cstate%gpos(:) = 0.0d0
64 cstate%direction(:) = 0.0d0
65 cstate%multiplier(:) = 0.0d0
66 cstate%tangentForce(:) = 0.0d0
67 cstate%tangentForce1(:) = 0.0d0
68 cstate%tangentForce_trial(:) = 0.0d0
69 cstate%tangentForce_final(:) = 0.0d0
70 cstate%reldisp(:) = 0.0d0
71 cstate%shrink_factor = 0.0d0
72 cstate%time_factor = 0.0d0
73 cstate%init_pos = 0.0d0
74 cstate%end_pos = 0.0d0
75 cstate%interference_flag = 0
87 integer,
intent(in) :: fnum
89 write(fnum, *)
"--Contact state=",cstate%state
90 write(fnum, *) cstate%surface, cstate%distance
91 write(fnum, *) cstate%lpos
92 write(fnum, *) cstate%direction
93 write(fnum, *) cstate%multiplier
99 integer,
intent(in) :: etype
100 integer,
intent(in) :: nnode
101 real(kind=kreal),
intent(out) :: mpcval(nnode*3 + 4)
104 real(kind=kreal) :: shapefunc(nnode)
107 mpcval(1:3) = cstate%direction(1:3)
110 mpcval( i*3+j ) = -cstate%direction(j)*shapefunc(i)
113 mpcval( 3*nnode+4 )=cstate%distance
118 fcoeff, symm, stiff, force )
119 integer,
intent(in) :: flag
121 integer,
intent(in) :: etype
122 integer,
intent(in) :: nnode
123 real(kind=kreal),
intent(in) :: ele(3,nnode)
124 real(kind=kreal),
intent(in) :: mu
125 real(kind=kreal),
intent(in) :: mut
126 real(kind=kreal),
intent(in) :: fcoeff
127 logical,
intent(in) :: symm
128 real(kind=kreal),
intent(out) :: stiff(:,:)
129 real(kind=kreal),
intent(out) :: force(:)
132 real(kind=kreal) :: shapefunc(nnode)
133 real(kind=kreal) :: n(nnode*3+3), dispmat(2,nnode*3+3)
134 real(kind=kreal) :: metric(2,2)
135 real(kind=kreal) :: det, inverse(2,2), ff(2), cff(2)
136 real(kind=kreal) :: dum11(nnode*3+3,nnode*3+3), dum12(nnode*3+3,nnode*3+3)
137 real(kind=kreal) :: dum21(nnode*3+3,nnode*3+3), dum22(nnode*3+3,nnode*3+3)
138 real(kind=kreal) :: tangent(3,2)
141 n(1:3) = cstate%direction(1:3)
143 n( i*3+1:i*3+3 ) = -shapefunc(i)*cstate%direction(1:3)
147 stiff(i,j) = mu* n(i)*n(j)
150 force(1:nnode*3+3) = n(:)
153 call dispincrematrix( cstate%lpos(1:2), etype, nnode, ele, tangent, metric, dispmat )
156 if( fcoeff/=0.d0 )
then
157 forall(i=1:nnode*3+3, j=1:nnode*3+3)
158 dum11(i,j) = mut*dispmat(1,i)*dispmat(1,j)
159 dum12(i,j) = mut*dispmat(1,i)*dispmat(2,j)
160 dum21(i,j) = mut*dispmat(2,i)*dispmat(1,j)
161 dum22(i,j) = mut*dispmat(2,i)*dispmat(2,j)
163 stiff(1:nnode*3+3,1:nnode*3+3) &
164 = stiff(1:nnode*3+3,1:nnode*3+3) &
165 + metric(1,1)*dum11 + metric(1,2)*dum12 &
166 + metric(2,1)*dum21 + metric(2,2)*dum22
169 det = metric(1,1)*metric(2,2)-metric(1,2)*metric(2,1)
170 if( det==0.d0 ) stop
"Math error in contact stiff calculation"
171 inverse(1,1) = metric(2,2)/det
172 inverse(2,1) = -metric(2,1)/det
173 inverse(1,2) = -metric(1,2)/det
174 inverse(2,2) = metric(1,1)/det
175 ff(:) = cstate%multiplier(2:3)
176 cff(:) = matmul( inverse, ff )
177 ff(:) = ff(:)/dsqrt( ff(1)*ff(1)+ff(2)*ff(2) )
178 cff(:) = cff(:)/dsqrt( cff(1)*cff(1)+cff(2)*cff(2) )
179 stiff(1:nnode*3+3,1:nnode*3+3) = stiff(1:nnode*3+3,1:nnode*3+3) - &
180 ( cff(1)*ff(1)*metric(1,1)+ cff(2)*ff(1)*metric(1,2) )*dum11 - &
181 ( cff(2)*ff(2)*metric(1,2)+ cff(1)*ff(2)*metric(1,1) )*dum21 - &
182 ( cff(1)*ff(1)*metric(1,2)+ cff(2)*ff(1)*metric(2,2) )*dum12 - &
183 ( cff(2)*ff(2)*metric(2,2)+ cff(1)*ff(2)*metric(1,2) )*dum22
190 subroutine tied2stiff( flag, cstate, etype, nnode, mu, mut, stiff, force )
191 integer,
intent(in) :: flag
193 integer,
intent(in) :: etype
194 integer,
intent(in) :: nnode
195 real(kind=kreal),
intent(in) :: mu
196 real(kind=kreal),
intent(in) :: mut
197 real(kind=kreal),
intent(out) :: stiff(:,:)
198 real(kind=kreal),
intent(out) :: force(:)
201 real(kind=kreal) :: shapefunc(nnode)
202 real(kind=kreal) :: n(nnode*3+3)
208 n(2:nnode+1) = -shapefunc(1:nnode)
213 stiff(3*k-3+i,3*j-3+i) = mu*n(k)*n(j)
217 force(1:nnode*3+3) = n(:)
223 real(kind=kreal),
intent(in) :: pos(2)
224 integer,
intent(in) :: etype
225 real(kind=kreal),
intent(in) :: ele(:,:)
226 real(kind=kreal),
intent(out) :: tensor(2,2)
229 real(kind=kreal) :: tangent(3,2)
232 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
233 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
234 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
235 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
241 real(kind=kreal),
intent(in) :: pos(2)
242 integer,
intent(in) :: etype
243 integer,
intent(in) :: nnode
244 real(kind=kreal),
intent(in) :: ele(3,nnode)
245 real(kind=kreal),
intent(out) :: tangent(3,2)
246 real(kind=kreal),
intent(out) :: tensor(2,2)
247 real(kind=kreal),
intent(out) :: matrix(2,nnode*3+3)
250 real(kind=kreal) :: det
251 real(kind=kreal) :: shapefunc(nnode), t1(nnode*3+3), t2(nnode*3+3)
252 call tangentbase( etype, nnode, pos, ele, tangent )
253 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
254 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
255 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
256 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
257 det = tensor(1,1)*tensor(2,2)-tensor(1,2)*tensor(2,1)
258 if( det==0.d0 ) stop
"Error in calculate DispIncreMatrix"
266 t1( j ) = tangent(j,1)
267 t2( j ) = tangent(j,2)
269 forall( i=1:nnode, j=1:3 )
270 t1( i*3+j ) = -tangent(j,1)*shapefunc(i)
271 t2( i*3+j ) = -tangent(j,2)*shapefunc(i)
274 matrix(1,:) = (tensor(2,2)*t1(:)-tensor(1,2)*t2(:))/det
275 matrix(2,:) = (tensor(1,1)*t2(:)-tensor(2,1)*t1(:))/det
276 tangent(:,1) = tangent(:,1)/dsqrt(dot_product(tangent(:,1),tangent(:,1)))
277 tangent(:,2) = tangent(:,2)/dsqrt(dot_product(tangent(:,2),tangent(:,2)))
282 real(kind=kreal),
intent(in) :: xyz(3)
283 integer,
intent(in) :: etype
284 integer,
intent(in) :: nn
285 real(kind=kreal),
intent(in) :: elemt(:,:)
286 real(kind=kreal),
intent(in) :: reflen
288 logical,
intent(out) :: isin
289 real(kind=kreal),
intent(in) :: distclr
290 real(kind=kreal),
optional :: ctpos(2)
291 real(kind=kreal),
optional :: localclr
293 integer :: count,order, initstate
294 real(kind=kreal) :: determ, inverse(2,2)
295 real(kind=kreal) :: sfunc(nn), curv(3,2,2)
296 real(kind=kreal) :: r(2), dr(2), r_tmp(2)
297 real(kind=kreal) :: xyz_out(3)
298 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
299 real(kind=kreal) :: tangent(3,2)
300 real(kind=kreal) :: df(2),d2f(2,2),normal(3)
301 real(kind=kreal),
parameter :: eps = 1.0d-8
302 real(kind=kreal) :: clr, tol, factor
304 initstate = cstate%state
306 if(
present( localclr ) ) clr=localclr
307 if(
present( ctpos ) )
then
316 xyz_out = matmul( elemt(1:3,1:nn), sfunc )
317 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
318 dist_last = dot_product( dxyz, dxyz(:) )
320 call tangentbase( etype, nn, r, elemt(1:3,1:nn), tangent )
321 call curvature( etype, nn, r, elemt(1:3,1:nn), curv )
324 df(1:2) = -matmul( dxyz(:), tangent(:,:) )
326 d2f(1,1)= dot_product( tangent(:,1), tangent(:,1) ) - dot_product( dxyz, curv(:,1,1) )
327 d2f(1,2)= dot_product( tangent(:,1), tangent(:,2) ) - dot_product( dxyz, curv(:,1,2) )
328 d2f(2,1)= dot_product( tangent(:,2), tangent(:,1) ) - dot_product( dxyz, curv(:,2,1) )
329 d2f(2,2)= dot_product( tangent(:,2), tangent(:,2) ) - dot_product( dxyz, curv(:,2,2) )
332 determ = d2f(1,1)*d2f(2,2) - d2f(1,2)*d2f(2,1)
333 if( determ==0.d0 ) stop
"Math error in contact searching"
334 inverse(1,1) = d2f(2,2) / determ
335 inverse(2,2) = d2f(1,1) / determ
336 inverse(1,2) = -d2f(1,2) / determ
337 inverse(2,1) = -d2f(2,1) / determ
338 dr=matmul(inverse,df)
340 tol=dot_product(dr,dr)
341 if( dsqrt(tol)> 3.d0 )
then
347 r_tmp(1:2) = r(1:2) + factor*dr(1:2)
349 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(:) )
350 dxyz(1:3) = xyz(1:3)-xyz_out(:)
351 dist_now = dot_product( dxyz, dxyz )
352 if(dist_now <= dist_last)
exit
353 factor = factor*0.7d0
363 dxyz(:)=xyz_out(:)-xyz(:)
365 normal(:) = normal(:)/dsqrt( dot_product(normal, normal) )
367 if( dabs(normal(count))<1.d-10 ) normal(count) =0.d0
368 if( dabs(1.d0-dabs(normal(count)))<1.d-10 ) normal(count) =sign(1.d0, normal(count))
370 cstate%distance = dot_product( dxyz, normal )
372 if( cstate%interference_flag ==
c_if_slave)
then
373 if( cstate%init_pos == 0.d0 .and. cstate%distance < cstate%end_pos)
then
374 cstate%init_pos = cstate%distance
375 cstate%time_factor = (cstate%end_pos - cstate%distance) / cstate%time_factor
376 cstate%shrink_factor = cstate%distance
380 if( cstate%interference_flag == 0)
then
381 if( cstate%distance < distclr*reflen .and. cstate%distance > -5.0d-01*reflen ) isin = .true.
383 if( cstate%distance < cstate%shrink_factor + distclr*reflen ) isin = .true.
390 cstate%state = initstate
392 cstate%gpos(:)=xyz_out(:)
393 cstate%lpos(1:2)=r(:)
394 cstate%direction(:) = normal(:)
395 cstate%wkdist = cstate%distance
403 real(kind=kreal),
intent(in) :: xyz(3)
404 integer,
intent(in) :: etype
405 integer,
intent(in) :: nn
406 real(kind=kreal),
intent(in) :: elemt(:,:)
407 real(kind=kreal),
intent(in) :: reflen
409 logical,
intent(out) :: isin
410 real(kind=kreal),
intent(in) :: distclr
411 real(kind=kreal),
optional :: ctpos(3)
412 real(kind=kreal),
optional :: localclr
414 integer :: count,order, initstate
415 real(kind=kreal) :: determ, inverse(3,3)
416 real(kind=kreal) :: sfunc(nn), deriv(nn,3)
417 real(kind=kreal) :: r(3), dr(3), r_tmp(3)
418 real(kind=kreal) :: xyz_out(3)
419 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
420 real(kind=kreal) :: tangent(3,2)
421 real(kind=kreal) :: df(2),d2f(2,2),normal(3)
422 real(kind=kreal),
parameter :: eps = 1.0d-8
423 real(kind=kreal) :: clr, tol, factor
425 initstate = cstate%state
427 if(
present( localclr ) ) clr=localclr
428 if(
present( ctpos ) )
then
437 xyz_out = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
438 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
439 dist_last = dot_product( dxyz, dxyz(:) )
442 inverse(1:3,1:3) = matmul(elemt(1:3,1:nn),deriv(1:nn,1:3))
444 dr(1:3) = -matmul(inverse(1:3,1:3),dxyz(1:3))
446 tol=dot_product(dr,dr)
447 if( count > 1 .and. dsqrt(tol)> 3.d0 )
then
453 r_tmp(1:3) = r(1:3) + factor*dr(1:3)
455 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
456 dxyz(1:3) = xyz(1:3)-xyz_out(1:3)
457 dist_now = dot_product( dxyz, dxyz )
458 if(dist_now <= dist_last)
exit
459 factor = factor*0.7d0
469 dxyz(:)=xyz_out(:)-xyz(:)
470 cstate%distance = dsqrt(dot_product( dxyz, dxyz ))
472 if( cstate%distance < distclr ) isin = .true.
478 cstate%state = initstate
480 cstate%gpos(:)=xyz_out(:)
481 cstate%direction(:) = (/1.d0,0.d0,0.d0/)
482 cstate%lpos(1:3)=r(:)
489 integer,
intent(in) :: etype
490 integer,
intent(in) :: nn
491 real(kind=kreal),
intent(in) :: elemt0(3,nn)
492 real(kind=kreal),
intent(in) :: elemt(3,nn)
496 real(kind=kreal) :: tangent0(3,2), tangent(3,2)
497 real(kind=kreal) :: coeff(2), norm, norm_tmp
498 real(kind=kreal) :: tangentforce_tmp(3)
500 call tangentbase( etype, nn, cstate%lpos(1:2), elemt0, tangent0 )
501 call tangentbase( etype, nn, cstate%lpos(1:2), elemt, tangent )
505 coeff(i) = dot_product(cstate%tangentForce(1:3),tangent0(1:3,i))
506 coeff(i) = coeff(i)/dot_product(tangent0(1:3,i),tangent0(1:3,i))
508 tangentforce_tmp(1:3) = coeff(1)*tangent0(1:3,1) + coeff(2)*tangent0(1:3,2)
509 norm_tmp = dsqrt(dot_product(tangentforce_tmp,tangentforce_tmp))
511 if( norm_tmp > 1.d-6 )
then
512 norm = dsqrt(dot_product(cstate%tangentForce,cstate%tangentForce))
513 coeff(1:2) = (norm/norm_tmp)*coeff(1:2)
517 cstate%tangentForce1(1:3) = coeff(1)*tangent(1:3,1) + coeff(2)*tangent(1:3,2)
522 real(kind=kreal),
intent(in) :: ctime, etime
524 integer,
intent(in) :: if_type
526 if (if_type ==
c_if_slave .and. cstate%init_pos == 0.d0)
then
527 cstate%shrink_factor = 0.0d0;
return
529 cstate%shrink_factor = cstate%time_factor*ctime + cstate%init_pos
530 if(ctime >= etime) cstate%shrink_factor = cstate%end_pos
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 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