29 private :: getcontactstiffness
30 private :: getcontactnodalforce
31 private :: gettrialfricforceandcheckfricstate
39 integer(kind=kint) :: cstep
40 integer(kind=kint) :: iter
41 type(hecmwst_matrix) :: hecmat
43 type(hecmwst_matrix_lagrange) :: heclagmat
44 integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(21)
45 integer(kind=kint) :: i, j, k, nlag, id_lagrange, grpid, algtype
46 real(kind=kreal) :: lagrange
47 real(kind=kreal) :: stiffness(21*3 + 1, 21*3 + 1)
49 heclagmat%AL_lagrange = 0.0d0
50 heclagmat%AU_lagrange = 0.0d0
54 do i = 1, fstrsolid%n_contacts
56 grpid = fstrsolid%contacts(i)%group
59 algtype = fstrsolid%contacts(i)%algtype
62 do j = 1,
size(fstrsolid%contacts(i)%slave)
64 if( fstrsolid%contacts(i)%states(j)%state ==
contactfree ) cycle
66 ctsurf = fstrsolid%contacts(i)%states(j)%surface
67 etype = fstrsolid%contacts(i)%master(ctsurf)%etype
68 nnode =
size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
69 ndlocal(1) = fstrsolid%contacts(i)%slave(j)
70 ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
73 id_lagrange = id_lagrange + 1
74 lagrange = heclagmat%Lagrange(id_lagrange)
78 call getcontactstiffness(iter,etype,nnode,fstrsolid%contacts(i)%states(j), &
79 fstrsolid%contacts(i)%tPenalty,fstrsolid%contacts(i)%fcoeff,lagrange,stiffness)
81 call gettiedstiffness(etype,nnode,k,fstrsolid%contacts(i)%states(j),lagrange,stiffness)
90 do i = 1, fstrsolid%n_embeds
92 grpid = fstrsolid%embeds(i)%group
95 do j = 1,
size(fstrsolid%embeds(i)%slave)
97 if( fstrsolid%embeds(i)%states(j)%state ==
contactfree ) cycle
99 ctsurf = fstrsolid%embeds(i)%states(j)%surface
100 etype = fstrsolid%embeds(i)%master(ctsurf)%etype
101 nnode =
size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
102 ndlocal(1) = fstrsolid%embeds(i)%slave(j)
103 ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
106 id_lagrange = id_lagrange + 1
107 lagrange = heclagmat%Lagrange(id_lagrange)
109 call gettiedstiffness(etype,nnode,k,fstrsolid%embeds(i)%states(j),lagrange,stiffness)
121 integer(kind=kint) :: etype
122 integer(kind=kint) :: nnode
123 integer(kind=kint) :: idof
125 real(kind=kreal) :: lagrange
126 real(kind=kreal) :: stiffness(:,:)
128 integer(kind=kint) :: i, j, k, l
129 real(kind=kreal) :: shapefunc(nnode)
130 real(kind=kreal) :: ntm((nnode+1)*3)
139 ntm(i*3+idof) = -shapefunc(i)
143 do j = 1, (nnode+1)*3
144 stiffness(i,j) = ntm(j); stiffness(j,i) = ntm(j)
150 subroutine getcontactstiffness(iter,etype,nnode,ctState,tPenalty,fcoeff,lagrange,stiffness)
153 integer(kind=kint) :: iter
154 integer(kind=kint) :: etype, nnode
155 integer(kind=kint) :: i, j, k, l
156 real(kind=kreal) :: normal(3), shapefunc(nnode)
157 real(kind=kreal) :: ntm((nnode + 1)*3)
158 real(kind=kreal) :: fcoeff, tpenalty
159 real(kind=kreal) :: lagrange
160 real(kind=kreal) :: tf_trial(3), length_tft
161 real(kind=kreal) :: tangent(3), ttm((nnode + 1)*3)
162 real(kind=kreal) :: stiffness(:,:)
168 normal(1:3) = ctstate%direction(1:3)
170 ntm(1:3) = normal(1:3)
172 ntm(i*3+1:i*3+3) = -shapefunc(i)*normal(1:3)
176 do j = 1, (nnode+1)*3
177 stiffness(i,j) = ntm(j); stiffness(j,i) = ntm(j)
181 if( fcoeff /= 0.0d0 )
then
182 if( lagrange>0.0d0 .or. iter==1 )
then
188 stiffness((i-1)*3+k,(j-1)*3+l) = stiffness((i-1)*3+k,(j-1)*3+l) - tpenalty*ntm((i-1)*3+k)*ntm((j-1)*3+l)
190 if(i==1 .and. j==1)
then
191 stiffness((i-1)*3+k,(j-1)*3+l) = stiffness((i-1)*3+k,(j-1)*3+l) + tpenalty
192 elseif(i>1 .and. j==1)
then
193 stiffness((i-1)*3+k,(j-1)*3+l) = stiffness((i-1)*3+k,(j-1)*3+l) - tpenalty*shapefunc(i-1)
194 elseif(i>1 .and. j>1)
then
195 stiffness((i-1)*3+k,(j-1)*3+l) = stiffness((i-1)*3+k,(j-1)*3+l) + tpenalty*shapefunc(i-1)*shapefunc(j-1)
199 stiffness((j-1)*3+l,(i-1)*3+k) = stiffness((i-1)*3+k,(j-1)*3+l)
207 tf_trial(1:3) = ctstate%tangentForce_trial(1:3)
208 length_tft = dsqrt(dot_product(tf_trial,tf_trial))
209 tangent(1:3) = tf_trial(1:3)/length_tft
211 ttm(1:3) = -tangent(1:3)
213 ttm(i*3+1:i*3+3) = shapefunc(i)*tangent(1:3)
220 stiffness((i-1)*3+k,(j-1)*3+l) = stiffness((i-1)*3+k,(j-1)*3+l) &
221 + tpenalty*(-ttm((i-1)*3+k)*ttm((j-1)*3+l) &
222 +ttm((i-1)*3+k)*ntm((j-1)*3+l)*dot_product(tangent,normal))
227 stiffness(1:(nnode+1)*3,1:(nnode+1)*3) = (fcoeff*lagrange/length_tft)*stiffness(1:(nnode+1)*3,1:(nnode+1)*3)
246 stiffness(1:(nnode+1)*3,(nnode+1)*3+1) = stiffness(1:(nnode+1)*3,(nnode+1)*3+1) - fcoeff*ttm(1:(nnode+1)*3)
252 end subroutine getcontactstiffness
258 type(hecmwst_local_mesh) :: hecmesh
259 type(hecmwst_matrix) :: hecmat
261 type(hecmwst_matrix_lagrange) :: heclagmat
262 type(hecmwst_matrix) :: conmat
263 integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(21)
264 integer(kind=kint) :: i, j, k, nlag, id_lagrange, algtype
265 real(kind=kreal) :: ndcoord(21*3)
266 real(kind=kreal) :: ndu(21*3), nddu(21*3)
267 real(kind=kreal) :: lagrange
268 real(kind=kreal) :: ctnforce(21*3+1)
269 real(kind=kreal) :: cttforce(21*3+1)
271 integer(kind=kint) :: cstep
272 integer(kind=kint) :: grpid
275 if(
associated(fstrsolid%CONT_NFORCE) ) fstrsolid%CONT_NFORCE(:) = 0.d0
276 if(
associated(fstrsolid%CONT_FRIC) ) fstrsolid%CONT_FRIC(:) = 0.d0
277 if(
associated(fstrsolid%EMBED_NFORCE) ) fstrsolid%EMBED_NFORCE(:) = 0.d0
279 do i = 1, fstrsolid%n_contacts
281 grpid = fstrsolid%contacts(i)%group
284 algtype = fstrsolid%contacts(i)%algtype
287 do j = 1,
size(fstrsolid%contacts(i)%slave)
289 if( fstrsolid%contacts(i)%states(j)%state ==
contactfree ) cycle
291 ctsurf = fstrsolid%contacts(i)%states(j)%surface
292 etype = fstrsolid%contacts(i)%master(ctsurf)%etype
293 nnode =
size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
294 ndlocal(1) = fstrsolid%contacts(i)%slave(j)
295 ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
297 nddu((k-1)*3+1:(k-1)*3+3) = fstrsolid%dunode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
298 ndu((k-1)*3+1:(k-1)*3+3) = fstrsolid%unode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3) + nddu((k-1)*3+1:(k-1)*3+3)
299 ndcoord((k-1)*3+1:(k-1)*3+3) = hecmesh%node((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3) + ndu((k-1)*3+1:(k-1)*3+3)
303 id_lagrange = id_lagrange + 1
304 lagrange = heclagmat%Lagrange(id_lagrange)
306 fstrsolid%contacts(i)%states(j)%multiplier(k) = heclagmat%Lagrange(id_lagrange)
310 call getcontactnodalforce(etype,nnode,ndcoord,nddu,fstrsolid%contacts(i)%states(j), &
311 fstrsolid%contacts(i)%tPenalty,fstrsolid%contacts(i)%fcoeff,lagrange,ctnforce,cttforce,.true.)
314 & conmat,fstrsolid%CONT_NFORCE,fstrsolid%CONT_FRIC)
316 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%contacts(i)%states(j),lagrange,ctnforce,cttforce)
319 & conmat,fstrsolid%CONT_NFORCE,fstrsolid%CONT_FRIC)
327 do i = 1, fstrsolid%n_embeds
329 grpid = fstrsolid%embeds(i)%group
332 do j = 1,
size(fstrsolid%embeds(i)%slave)
334 if( fstrsolid%embeds(i)%states(j)%state ==
contactfree ) cycle
336 ctsurf = fstrsolid%embeds(i)%states(j)%surface
337 etype = fstrsolid%embeds(i)%master(ctsurf)%etype
338 nnode =
size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
339 ndlocal(1) = fstrsolid%embeds(i)%slave(j)
340 ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
342 nddu((k-1)*3+1:(k-1)*3+3) = fstrsolid%dunode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
343 ndu((k-1)*3+1:(k-1)*3+3) = fstrsolid%unode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3) + nddu((k-1)*3+1:(k-1)*3+3)
344 ndcoord((k-1)*3+1:(k-1)*3+3) = hecmesh%node((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3) + ndu((k-1)*3+1:(k-1)*3+3)
348 id_lagrange = id_lagrange + 1
349 lagrange = heclagmat%Lagrange(id_lagrange)
351 fstrsolid%embeds(i)%states(j)%multiplier(k) = heclagmat%Lagrange(id_lagrange)
353 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%embeds(i)%states(j),lagrange,ctnforce,cttforce)
356 & conmat,fstrsolid%EMBED_NFORCE,fstrsolid%EMBED_NFORCE)
369 subroutine gettiednodalforce(etype,nnode,idof,ndu,ctState,lagrange,ctNForce,ctTForce)
370 integer(kind=kint) :: etype
371 integer(kind=kint) :: nnode
372 integer(kind=kint) :: idof
373 real(kind=kreal) :: ndu((nnode + 1)*3)
375 real(kind=kreal) :: lagrange
376 real(kind=kreal) :: ctnforce((nnode+1)*3+1)
377 real(kind=kreal) :: cttforce((nnode+1)*3+1)
379 integer(kind=kint) :: i, j
380 real(kind=kreal) :: normal(3), shapefunc(nnode)
381 real(kind=kreal) :: ntm((nnode + 1)*3)
382 real(kind=kreal) :: ttm((nnode + 1)*3)
389 normal(1:3) = ctstate%direction(1:3)
391 ntm(1:3) = -normal(idof)*normal(1:3)
393 ntm(i*3+1:i*3+3) = -shapefunc(i)*ntm(1:3)
397 ttm(1:3) = ttm(1:3)-ntm(1:3)
399 ttm(i*3+1:i*3+3) = -shapefunc(i)*ttm(1:3)
402 do j = 1, (nnode+1)*3
403 ctnforce(j) = lagrange*ntm(j)
404 cttforce(j) = lagrange*ttm(j)
407 ctnforce(j) = dot_product(ntm,ndu)
408 cttforce(j) = dot_product(ttm,ndu)
412 subroutine getcontactnodalforce(etype,nnode,ndCoord,ndDu,ctState,tPenalty,fcoeff,lagrange,ctNForce,ctTForce,cflag)
415 integer(kind=kint) :: etype, nnode
416 integer(kind=kint) :: i, j
417 real(kind=kreal) :: fcoeff, tpenalty
418 real(kind=kreal) :: lagrange
419 real(kind=kreal) :: ndcoord((nnode + 1)*3), nddu((nnode + 1)*3)
420 real(kind=kreal) :: normal(3), shapefunc(nnode)
421 real(kind=kreal) :: ntm((nnode + 1)*3)
422 real(kind=kreal) :: tf_trial(3), length_tft, tangent(3), tf_final(3)
423 real(kind=kreal) :: ctnforce((nnode+1)*3+1)
424 real(kind=kreal) :: cttforce((nnode+1)*3+1)
432 normal(1:3) = ctstate%direction(1:3)
434 ntm(1:3) = -normal(1:3)
436 ntm(i*3+1:i*3+3) = shapefunc(i)*normal(1:3)
439 do j = 1, (nnode+1)*3
440 ctnforce(j) = lagrange*ntm(j)
443 ctnforce(j) = dot_product(ntm,ndcoord)
445 if(fcoeff /= 0.0d0 .and. lagrange > 0.0d0)
then
448 call gettrialfricforceandcheckfricstate(nnode,tpenalty,fcoeff,lagrange,normal,shapefunc,ntm,nddu,ctstate)
451 tf_final(1:3) = ctstate%tangentForce_trial(1:3)
453 tf_trial(1:3) = ctstate%tangentForce_trial(1:3)
454 length_tft = dsqrt(dot_product(tf_trial,tf_trial))
455 tangent(1:3) = tf_trial(1:3)/length_tft
456 tf_final(1:3) = fcoeff*dabs(lagrange)*tangent(1:3)
458 ctstate%tangentForce_final(1:3) = tf_final(1:3)
460 tf_final(1:3) = ctstate%tangentForce_final(1:3)
463 cttforce(1:3) = -tf_final(1:3)
465 cttforce(j*3+1:j*3+3) = shapefunc(j)*tf_final(1:3)
470 end subroutine getcontactnodalforce
474 subroutine gettrialfricforceandcheckfricstate(nnode,tPenalty,fcoeff,lagrange,normal,shapefunc,nTm,ndDu,ctstate)
477 integer(kind=kint) :: nnode
478 integer(kind=kint) :: i, j
479 real(kind=kreal) :: fcoeff, tpenalty
480 real(kind=kreal) :: lagrange
481 real(kind=kreal) :: nddu((nnode + 1)*3)
482 real(kind=kreal) :: normal(3), shapefunc(nnode)
483 real(kind=kreal) :: ntm((nnode + 1)*3)
484 real(kind=kreal) :: dotp
485 real(kind=kreal) :: relativedisp(3)
486 real(kind=kreal) :: tf_yield
490 dotp = dot_product(ntm,nddu)
492 relativedisp(i) = - nddu(i)
494 relativedisp(i) = relativedisp(i) + shapefunc(j)*nddu(j*3+i)
496 relativedisp(i) = relativedisp(i) - dotp*normal(i)
497 ctstate%reldisp(i) = -relativedisp(i)
498 ctstate%tangentForce_trial(i) = ctstate%tangentForce1(i) -tpenalty*relativedisp(i)
501 tf_yield = fcoeff*dabs(lagrange)
502 if(ctstate%state ==
contactslip) tf_yield =0.99d0*tf_yield
503 if( dsqrt(dot_product(ctstate%tangentForce_trial,ctstate%tangentForce_trial)) <= tf_yield )
then
509 end subroutine gettrialfricforceandcheckfricstate
514 subroutine update_ndforce_contact(nnode,ndLocal,id_lagrange,lagrange,ctNForce,ctTForce,hecMAT,cont_nforce,cont_fric)
516 type(hecmwst_matrix) :: hecmat
517 integer(kind=kint) :: nnode, ndlocal(nnode + 1)
519 integer(kind=kint) :: id_lagrange
520 real(kind=kreal) :: lagrange
521 integer(kind=kint) :: np, ndof
522 integer (kind=kint) :: i, inod, idx
523 real(kind=kreal) :: ctnforce((nnode+1)*3+1)
524 real(kind=kreal) :: cttforce((nnode+1)*3+1)
525 real(kind=kreal),
pointer :: cont_nforce(:)
526 real(kind=kreal),
pointer,
optional :: cont_fric(:)
528 np = hecmat%NP; ndof = hecmat%NDOF
533 hecmat%B(idx:idx+2) = hecmat%B(idx:idx+2) + ctnforce((i-1)*3+1:(i-1)*3+3) + cttforce((i-1)*3+1:(i-1)*3+3)
534 cont_nforce(idx:idx+2) = cont_nforce(idx:idx+2) + ctnforce((i-1)*3+1:(i-1)*3+3)
535 if(
present(cont_fric) ) cont_fric(idx:idx+2) = cont_fric(idx:idx+2) + cttforce((i-1)*3+1:(i-1)*3+3)
538 hecmat%B(np*ndof+id_lagrange) = ctnforce((nnode+1)*3+1)+cttforce((nnode+1)*3+1)
547 type(hecmwst_local_mesh) :: hecmesh
548 type(hecmwst_matrix) :: hecmat
550 type(hecmwst_matrix_lagrange) :: heclagmat
551 integer(kind=kint) :: cstep
552 integer(kind=kint) :: np, ndof
553 integer(kind=kint) :: i, j, k, l, id_lagrange, lnod, grpid
554 integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(21)
555 real(kind=kreal) :: ndu(21*3), ndcoord(21*3), lagrange
556 real(kind=kreal) :: normal(3), shapefunc(21)
557 real(kind=kreal) :: ntm(10*3)
558 real(kind=kreal) :: tf_final(3)
559 real(kind=kreal) :: ctforce(21*3 + 1)
561 integer(kind=kint) :: algtype, nlag
562 real(kind=kreal) :: ctnforce(21*3+1)
563 real(kind=kreal) :: cttforce(21*3+1)
565 np = hecmat%NP ; ndof = hecmat%NDOF
569 do i = 1, fstrsolid%n_contacts
571 grpid = fstrsolid%contacts(i)%group
574 algtype = fstrsolid%contacts(i)%algtype
577 do j = 1,
size(fstrsolid%contacts(i)%slave)
579 if( fstrsolid%contacts(i)%states(j)%state ==
contactfree ) cycle
581 ctsurf = fstrsolid%contacts(i)%states(j)%surface
582 etype = fstrsolid%contacts(i)%master(ctsurf)%etype
583 nnode =
size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
584 ndlocal(1) = fstrsolid%contacts(i)%slave(j)
585 ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
587 ndu((k-1)*3+1:(k-1)*3+3) = fstrsolid%unode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
588 ndcoord((k-1)*3+1:(k-1)*3+3) = hecmesh%node((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3) + ndu((k-1)*3+1:(k-1)*3+3)
592 id_lagrange = id_lagrange + 1
593 lagrange = fstrsolid%contacts(i)%states(j)%multiplier(k)
597 call getcontactnodalforce(etype,nnode,ndcoord,ndu,fstrsolid%contacts(i)%states(j), &
598 fstrsolid%contacts(i)%tPenalty,fstrsolid%contacts(i)%fcoeff,lagrange,ctnforce,cttforce,.false.)
601 & hecmat,fstrsolid%CONT_NFORCE,fstrsolid%CONT_FRIC)
603 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%contacts(i)%states(j),lagrange,ctnforce,cttforce)
605 call update_ndforce_contact(nnode,ndlocal,id_lagrange,-1.d0,ctnforce,cttforce,hecmat,fstrsolid%CONT_NFORCE)
612 do i = 1, fstrsolid%n_embeds
614 grpid = fstrsolid%embeds(i)%group
618 do j = 1,
size(fstrsolid%embeds(i)%slave)
620 if( fstrsolid%embeds(i)%states(j)%state ==
contactfree ) cycle
622 ctsurf = fstrsolid%embeds(i)%states(j)%surface
623 etype = fstrsolid%embeds(i)%master(ctsurf)%etype
624 nnode =
size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
625 ndlocal(1) = fstrsolid%embeds(i)%slave(j)
626 ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
628 ndu((k-1)*3+1:(k-1)*3+3) = fstrsolid%unode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
629 ndcoord((k-1)*3+1:(k-1)*3+3) = hecmesh%node((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3) + ndu((k-1)*3+1:(k-1)*3+3)
633 id_lagrange = id_lagrange + 1
634 lagrange = fstrsolid%embeds(i)%states(j)%multiplier(k)
636 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%embeds(i)%states(j),lagrange,ctnforce,cttforce)
638 call update_ndforce_contact(nnode,ndlocal,id_lagrange,-1.d0,ctnforce,cttforce,hecmat,fstrsolid%EMBED_NFORCE)