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
30 real(kind=kreal) :: distance
31 real(kind=kreal) :: wkdist
32 real(kind=kreal) :: lpos(3)
33 real(kind=kreal) :: gpos(3)
34 real(kind=kreal) :: direction(3)
35 real(kind=kreal) :: multiplier(3)
37 real(kind=kreal) :: tangentforce(3)
38 real(kind=kreal) :: tangentforce1(3)
39 real(kind=kreal) :: tangentforce_trial(3)
40 real(kind=kreal) :: tangentforce_final(3)
41 real(kind=kreal) :: reldisp(3)
62 integer,
intent(in) :: fnum
64 write(fnum, *)
"--Contact state=",cstate%state
65 write(fnum, *) cstate%surface, cstate%distance
66 write(fnum, *) cstate%lpos
67 write(fnum, *) cstate%direction
68 write(fnum, *) cstate%multiplier
74 integer,
intent(in) :: etype
75 integer,
intent(in) :: nnode
76 real(kind=kreal),
intent(out) :: mpcval(nnode*3 + 4)
79 real(kind=kreal) :: shapefunc(nnode)
82 mpcval(1:3) = cstate%direction(1:3)
85 mpcval( i*3+j ) = -cstate%direction(j)*shapefunc(i)
88 mpcval( 3*nnode+4 )=cstate%distance
92 subroutine contact2stiff( flag, cstate, etype, nnode, ele, mu, mut, &
93 fcoeff, symm, stiff, force )
94 integer,
intent(in) :: flag
96 integer,
intent(in) :: etype
97 integer,
intent(in) :: nnode
98 real(kind=kreal),
intent(in) :: ele(3,nnode)
99 real(kind=kreal),
intent(in) ::
mu
100 real(kind=kreal),
intent(in) ::
mut
101 real(kind=kreal),
intent(in) :: fcoeff
102 logical,
intent(in) :: symm
103 real(kind=kreal),
intent(out) :: stiff(:,:)
104 real(kind=kreal),
intent(out) :: force(:)
107 real(kind=kreal) :: shapefunc(nnode)
108 real(kind=kreal) :: n(nnode*3+3), dispmat(2,nnode*3+3)
109 real(kind=kreal) :: metric(2,2)
110 real(kind=kreal) :: det, inverse(2,2), ff(2), cff(2)
111 real(kind=kreal) :: dum11(nnode*3+3,nnode*3+3), dum12(nnode*3+3,nnode*3+3)
112 real(kind=kreal) :: dum21(nnode*3+3,nnode*3+3), dum22(nnode*3+3,nnode*3+3)
113 real(kind=kreal) :: tangent(3,2)
116 n(1:3) = cstate%direction(1:3)
118 n( i*3+1:i*3+3 ) = -shapefunc(i)*cstate%direction(1:3)
122 stiff(i,j) =
mu* n(i)*n(j)
125 force(1:nnode*3+3) = n(:)
128 call dispincrematrix( cstate%lpos(1:2), etype, nnode, ele, tangent, metric, dispmat )
131 if( fcoeff/=0.d0 )
then
132 forall(i=1:nnode*3+3, j=1:nnode*3+3)
133 dum11(i,j) =
mut*dispmat(1,i)*dispmat(1,j)
134 dum12(i,j) =
mut*dispmat(1,i)*dispmat(2,j)
135 dum21(i,j) =
mut*dispmat(2,i)*dispmat(1,j)
136 dum22(i,j) =
mut*dispmat(2,i)*dispmat(2,j)
138 stiff(1:nnode*3+3,1:nnode*3+3) &
139 = stiff(1:nnode*3+3,1:nnode*3+3) &
140 + metric(1,1)*dum11 + metric(1,2)*dum12 &
141 + metric(2,1)*dum21 + metric(2,2)*dum22
144 det = metric(1,1)*metric(2,2)-metric(1,2)*metric(2,1)
145 if( det==0.d0 ) stop
"Math error in contact stiff calculation"
146 inverse(1,1) = metric(2,2)/det
147 inverse(2,1) = -metric(2,1)/det
148 inverse(1,2) = -metric(1,2)/det
149 inverse(2,2) = metric(1,1)/det
150 ff(:) = cstate%multiplier(2:3)
151 cff(:) = matmul( inverse, ff )
152 ff(:) = ff(:)/dsqrt( ff(1)*ff(1)+ff(2)*ff(2) )
153 cff(:) = cff(:)/dsqrt( cff(1)*cff(1)+cff(2)*cff(2) )
154 stiff(1:nnode*3+3,1:nnode*3+3) = stiff(1:nnode*3+3,1:nnode*3+3) - &
155 ( cff(1)*ff(1)*metric(1,1)+ cff(2)*ff(1)*metric(1,2) )*dum11 - &
156 ( cff(2)*ff(2)*metric(1,2)+ cff(1)*ff(2)*metric(1,1) )*dum21 - &
157 ( cff(1)*ff(1)*metric(1,2)+ cff(2)*ff(1)*metric(2,2) )*dum12 - &
158 ( cff(2)*ff(2)*metric(2,2)+ cff(1)*ff(2)*metric(1,2) )*dum22
165 subroutine tied2stiff( flag, cstate, etype, nnode, mu, mut, stiff, force )
166 integer,
intent(in) :: flag
168 integer,
intent(in) :: etype
169 integer,
intent(in) :: nnode
170 real(kind=kreal),
intent(in) ::
mu
171 real(kind=kreal),
intent(in) ::
mut
172 real(kind=kreal),
intent(out) :: stiff(:,:)
173 real(kind=kreal),
intent(out) :: force(:)
176 real(kind=kreal) :: shapefunc(nnode)
177 real(kind=kreal) :: n(nnode*3+3)
183 n(2:nnode+1) = -shapefunc(1:nnode)
188 stiff(3*k-3+i,3*j-3+i) =
mu*n(k)*n(j)
192 force(1:nnode*3+3) = n(:)
198 real(kind=kreal),
intent(in) :: pos(2)
199 integer,
intent(in) :: etype
200 real(kind=kreal),
intent(in) :: ele(:,:)
201 real(kind=kreal),
intent(out) :: tensor(2,2)
204 real(kind=kreal) :: tangent(3,2)
207 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
208 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
209 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
210 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
215 subroutine dispincrematrix( pos, etype, nnode, ele, tangent, tensor, matrix )
216 real(kind=kreal),
intent(in) :: pos(2)
217 integer,
intent(in) :: etype
218 integer,
intent(in) :: nnode
219 real(kind=kreal),
intent(in) :: ele(3,nnode)
220 real(kind=kreal),
intent(out) :: tangent(3,2)
221 real(kind=kreal),
intent(out) :: tensor(2,2)
222 real(kind=kreal),
intent(out) :: matrix(2,nnode*3+3)
225 real(kind=kreal) :: det
226 real(kind=kreal) :: shapefunc(nnode), t1(nnode*3+3), t2(nnode*3+3)
227 call tangentbase( etype, nnode, pos, ele, tangent )
228 tensor(1,1)= dot_product( tangent(:,1), tangent(:,1) )
229 tensor(1,2)= dot_product( tangent(:,1), tangent(:,2) )
230 tensor(2,1)= dot_product( tangent(:,2), tangent(:,1) )
231 tensor(2,2)= dot_product( tangent(:,2), tangent(:,2) )
232 det = tensor(1,1)*tensor(2,2)-tensor(1,2)*tensor(2,1)
233 if( det==0.d0 ) stop
"Error in calculate DispIncreMatrix"
241 t1( j ) = tangent(j,1)
242 t2( j ) = tangent(j,2)
244 forall( i=1:nnode, j=1:3 )
245 t1( i*3+j ) = -tangent(j,1)*shapefunc(i)
246 t2( i*3+j ) = -tangent(j,2)*shapefunc(i)
249 matrix(1,:) = (tensor(2,2)*t1(:)-tensor(1,2)*t2(:))/det
250 matrix(2,:) = (tensor(1,1)*t2(:)-tensor(2,1)*t1(:))/det
251 tangent(:,1) = tangent(:,1)/dsqrt(dot_product(tangent(:,1),tangent(:,1)))
252 tangent(:,2) = tangent(:,2)/dsqrt(dot_product(tangent(:,2),tangent(:,2)))
257 real(kind=kreal),
intent(in) :: xyz(3)
258 integer,
intent(in) :: etype
259 integer,
intent(in) :: nn
260 real(kind=kreal),
intent(in) :: elemt(:,:)
261 real(kind=kreal),
intent(in) :: reflen
263 logical,
intent(out) :: isin
264 real(kind=kreal),
intent(in) :: distclr
265 real(kind=kreal),
optional :: ctpos(2)
266 real(kind=kreal),
optional :: localclr
268 integer :: count,order, initstate
269 real(kind=kreal) :: determ, inverse(2,2)
270 real(kind=kreal) :: sfunc(nn), curv(3,2,2)
271 real(kind=kreal) :: r(2), dr(2), r_tmp(2)
272 real(kind=kreal) :: xyz_out(3)
273 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
274 real(kind=kreal) :: tangent(3,2)
275 real(kind=kreal) :: df(2),d2f(2,2),normal(3)
276 real(kind=kreal),
parameter ::
eps = 1.0d-8
277 real(kind=kreal) :: clr, tol, factor
279 initstate = cstate%state
281 if(
present( localclr ) ) clr=localclr
282 if(
present( ctpos ) )
then
291 xyz_out = matmul( elemt(1:3,1:nn), sfunc )
292 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
293 dist_last = dot_product( dxyz, dxyz(:) )
295 call tangentbase( etype, nn, r, elemt(1:3,1:nn), tangent )
296 call curvature( etype, nn, r, elemt(1:3,1:nn), curv )
299 df(1:2) = -matmul( dxyz(:), tangent(:,:) )
301 d2f(1,1)= dot_product( tangent(:,1), tangent(:,1) ) - dot_product( dxyz, curv(:,1,1) )
302 d2f(1,2)= dot_product( tangent(:,1), tangent(:,2) ) - dot_product( dxyz, curv(:,1,2) )
303 d2f(2,1)= dot_product( tangent(:,2), tangent(:,1) ) - dot_product( dxyz, curv(:,2,1) )
304 d2f(2,2)= dot_product( tangent(:,2), tangent(:,2) ) - dot_product( dxyz, curv(:,2,2) )
307 determ = d2f(1,1)*d2f(2,2) - d2f(1,2)*d2f(2,1)
308 if( determ==0.d0 ) stop
"Math error in contact searching"
309 inverse(1,1) = d2f(2,2) / determ
310 inverse(2,2) = d2f(1,1) / determ
311 inverse(1,2) = -d2f(1,2) / determ
312 inverse(2,1) = -d2f(2,1) / determ
313 dr=matmul(inverse,df)
315 tol=dot_product(dr,dr)
316 if( dsqrt(tol)> 3.d0 )
then
322 r_tmp(1:2) = r(1:2) + factor*dr(1:2)
324 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(:) )
325 dxyz(1:3) = xyz(1:3)-xyz_out(:)
326 dist_now = dot_product( dxyz, dxyz )
327 if(dist_now <= dist_last)
exit
328 factor = factor*0.7d0
338 dxyz(:)=xyz_out(:)-xyz(:)
340 normal(:) = normal(:)/dsqrt( dot_product(normal, normal) )
342 if( dabs(normal(count))<1.d-10 ) normal(count) =0.d0
343 if( dabs(1.d0-dabs(normal(count)))<1.d-10 ) normal(count) =sign(1.d0, normal(count))
345 cstate%distance = dot_product( dxyz, normal )
347 if( cstate%distance < distclr*reflen .and. cstate%distance > -5.0d-01*reflen ) isin = .true.
353 cstate%state = initstate
355 cstate%gpos(:)=xyz_out(:)
356 cstate%lpos(1:2)=r(:)
357 cstate%direction(:) = normal(:)
358 cstate%wkdist = cstate%distance
366 real(kind=kreal),
intent(in) :: xyz(3)
367 integer,
intent(in) :: etype
368 integer,
intent(in) :: nn
369 real(kind=kreal),
intent(in) :: elemt(:,:)
370 real(kind=kreal),
intent(in) :: reflen
372 logical,
intent(out) :: isin
373 real(kind=kreal),
intent(in) :: distclr
374 real(kind=kreal),
optional :: ctpos(3)
375 real(kind=kreal),
optional :: localclr
377 integer :: count,order, initstate
378 real(kind=kreal) :: determ, inverse(3,3)
379 real(kind=kreal) :: sfunc(nn), deriv(nn,3)
380 real(kind=kreal) :: r(3), dr(3), r_tmp(3)
381 real(kind=kreal) :: xyz_out(3)
382 real(kind=kreal) :: dist_last,dist_now, dxyz(3)
383 real(kind=kreal) :: tangent(3,2)
384 real(kind=kreal) :: df(2),d2f(2,2),normal(3)
385 real(kind=kreal),
parameter ::
eps = 1.0d-8
386 real(kind=kreal) :: clr, tol, factor
388 initstate = cstate%state
390 if(
present( localclr ) ) clr=localclr
391 if(
present( ctpos ) )
then
400 xyz_out = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
401 dxyz(1:3) = xyz_out(1:3) - xyz(1:3)
402 dist_last = dot_product( dxyz, dxyz(:) )
405 inverse(1:3,1:3) = matmul(elemt(1:3,1:nn),deriv(1:nn,1:3))
407 dr(1:3) = -matmul(inverse(1:3,1:3),dxyz(1:3))
409 tol=dot_product(dr,dr)
410 if( count > 1 .and. dsqrt(tol)> 3.d0 )
then
416 r_tmp(1:3) = r(1:3) + factor*dr(1:3)
418 xyz_out(1:3) = matmul( elemt(1:3,1:nn), sfunc(1:nn) )
419 dxyz(1:3) = xyz(1:3)-xyz_out(1:3)
420 dist_now = dot_product( dxyz, dxyz )
421 if(dist_now <= dist_last)
exit
422 factor = factor*0.7d0
432 dxyz(:)=xyz_out(:)-xyz(:)
433 cstate%distance = dsqrt(dot_product( dxyz, dxyz ))
435 if( cstate%distance < distclr ) isin = .true.
441 cstate%state = initstate
443 cstate%gpos(:)=xyz_out(:)
444 cstate%direction(:) = (/1.d0,0.d0,0.d0/)
445 cstate%lpos(1:3)=r(:)
452 integer,
intent(in) :: etype
453 integer,
intent(in) :: nn
454 real(kind=kreal),
intent(in) :: elemt0(3,nn)
455 real(kind=kreal),
intent(in) :: elemt(3,nn)
459 real(kind=kreal) :: tangent0(3,2), tangent(3,2)
460 real(kind=kreal) :: coeff(2), norm, norm_tmp
461 real(kind=kreal) :: tangentforce_tmp(3)
463 call tangentbase( etype, nn, cstate%lpos(1:2), elemt0, tangent0 )
464 call tangentbase( etype, nn, cstate%lpos(1:2), elemt, tangent )
468 coeff(i) = dot_product(cstate%tangentForce(1:3),tangent0(1:3,i))
469 coeff(i) = coeff(i)/dot_product(tangent0(1:3,i),tangent0(1:3,i))
471 tangentforce_tmp(1:3) = coeff(1)*tangent0(1:3,1) + coeff(2)*tangent0(1:3,2)
472 norm_tmp = dsqrt(dot_product(tangentforce_tmp,tangentforce_tmp))
474 if( norm_tmp > 1.d-6 )
then
475 norm = dsqrt(dot_product(cstate%tangentForce,cstate%tangentForce))
476 coeff(1:2) = (norm/norm_tmp)*coeff(1:2)
480 cstate%tangentForce1(1:3) = coeff(1)*tangent(1:3,1) + coeff(2)*tangent(1:3,2)