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
274 real(kind=kreal) :: ctime,
etime
275 integer(kind=kint) :: if_type
278 if(
associated(fstrsolid%CONT_NFORCE) ) fstrsolid%CONT_NFORCE(:) = 0.d0
279 if(
associated(fstrsolid%CONT_FRIC) ) fstrsolid%CONT_FRIC(:) = 0.d0
280 if(
associated(fstrsolid%EMBED_NFORCE) ) fstrsolid%EMBED_NFORCE(:) = 0.d0
282 do i = 1, fstrsolid%n_contacts
284 grpid = fstrsolid%contacts(i)%group
287 algtype = fstrsolid%contacts(i)%algtype
289 if_flag = (fstrsolid%contacts(i)%if_type /= 0)
291 ctime = fstrsolid%contacts(i)%ctime
292 etime = fstrsolid%contacts(i)%if_etime
293 if_type = fstrsolid%contacts(i)%if_type
296 do j = 1,
size(fstrsolid%contacts(i)%slave)
298 if( fstrsolid%contacts(i)%states(j)%state ==
contactfree ) cycle
301 ctsurf = fstrsolid%contacts(i)%states(j)%surface
302 etype = fstrsolid%contacts(i)%master(ctsurf)%etype
303 nnode =
size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
304 ndlocal(1) = fstrsolid%contacts(i)%slave(j)
305 ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
307 nddu((k-1)*3+1:(k-1)*3+3) = fstrsolid%dunode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
308 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)
309 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)
313 id_lagrange = id_lagrange + 1
314 lagrange = heclagmat%Lagrange(id_lagrange)
316 fstrsolid%contacts(i)%states(j)%multiplier(k) = heclagmat%Lagrange(id_lagrange)
322 call getcontactnodalforce(etype,nnode,ndcoord,nddu,fstrsolid%contacts(i)%states(j), &
323 fstrsolid%contacts(i)%tPenalty,fstrsolid%contacts(i)%fcoeff,lagrange,ctnforce,cttforce,.true.)
326 & conmat,fstrsolid%CONT_NFORCE,fstrsolid%CONT_FRIC)
328 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%contacts(i)%states(j),lagrange,ctnforce,cttforce)
331 & conmat,fstrsolid%CONT_NFORCE,fstrsolid%CONT_FRIC)
339 do i = 1, fstrsolid%n_embeds
341 grpid = fstrsolid%embeds(i)%group
344 do j = 1,
size(fstrsolid%embeds(i)%slave)
346 if( fstrsolid%embeds(i)%states(j)%state ==
contactfree ) cycle
348 ctsurf = fstrsolid%embeds(i)%states(j)%surface
349 etype = fstrsolid%embeds(i)%master(ctsurf)%etype
350 nnode =
size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
351 ndlocal(1) = fstrsolid%embeds(i)%slave(j)
352 ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
354 nddu((k-1)*3+1:(k-1)*3+3) = fstrsolid%dunode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
355 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)
356 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)
360 id_lagrange = id_lagrange + 1
361 lagrange = heclagmat%Lagrange(id_lagrange)
363 fstrsolid%embeds(i)%states(j)%multiplier(k) = heclagmat%Lagrange(id_lagrange)
365 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%embeds(i)%states(j),lagrange,ctnforce,cttforce)
368 & conmat,fstrsolid%EMBED_NFORCE,fstrsolid%EMBED_NFORCE)
381 subroutine gettiednodalforce(etype,nnode,idof,ndu,ctState,lagrange,ctNForce,ctTForce)
382 integer(kind=kint) :: etype
383 integer(kind=kint) :: nnode
384 integer(kind=kint) :: idof
385 real(kind=kreal) :: ndu((nnode + 1)*3)
387 real(kind=kreal) :: lagrange
388 real(kind=kreal) :: ctnforce((nnode+1)*3+1)
389 real(kind=kreal) :: cttforce((nnode+1)*3+1)
391 integer(kind=kint) :: i, j
392 real(kind=kreal) :: normal(3), shapefunc(nnode)
393 real(kind=kreal) :: ntm((nnode + 1)*3)
394 real(kind=kreal) :: ttm((nnode + 1)*3)
401 normal(1:3) = ctstate%direction(1:3)
403 ntm(1:3) = -normal(idof)*normal(1:3)
405 ntm(i*3+1:i*3+3) = -shapefunc(i)*ntm(1:3)
409 ttm(1:3) = ttm(1:3)-ntm(1:3)
411 ttm(i*3+1:i*3+3) = -shapefunc(i)*ttm(1:3)
414 do j = 1, (nnode+1)*3
415 ctnforce(j) = lagrange*ntm(j)
416 cttforce(j) = lagrange*ttm(j)
419 ctnforce(j) = dot_product(ntm,ndu)
420 cttforce(j) = dot_product(ttm,ndu)
424 subroutine getcontactnodalforce(etype,nnode,ndCoord,ndDu,ctState,tPenalty,fcoeff,lagrange,ctNForce,ctTForce,cflag)
427 integer(kind=kint) :: etype, nnode
428 integer(kind=kint) :: i, j
429 real(kind=kreal) :: fcoeff, tpenalty
430 real(kind=kreal) :: lagrange
431 real(kind=kreal) :: ndcoord((nnode + 1)*3), nddu((nnode + 1)*3)
432 real(kind=kreal) :: normal(3), shapefunc(nnode)
433 real(kind=kreal) :: ntm((nnode + 1)*3)
434 real(kind=kreal) :: tf_trial(3), length_tft, tangent(3), tf_final(3)
435 real(kind=kreal) :: ctnforce((nnode+1)*3+1)
436 real(kind=kreal) :: cttforce((nnode+1)*3+1)
444 normal(1:3) = ctstate%direction(1:3)
446 ntm(1:3) = -normal(1:3)
448 ntm(i*3+1:i*3+3) = shapefunc(i)*normal(1:3)
451 do j = 1, (nnode+1)*3
452 ctnforce(j) = lagrange*ntm(j)
455 ctnforce(j) = dot_product(ntm,ndcoord)
457 if(fcoeff /= 0.0d0 .and. lagrange > 0.0d0)
then
460 call gettrialfricforceandcheckfricstate(nnode,tpenalty,fcoeff,lagrange,normal,shapefunc,ntm,nddu,ctstate)
463 tf_final(1:3) = ctstate%tangentForce_trial(1:3)
465 tf_trial(1:3) = ctstate%tangentForce_trial(1:3)
466 length_tft = dsqrt(dot_product(tf_trial,tf_trial))
467 tangent(1:3) = tf_trial(1:3)/length_tft
468 tf_final(1:3) = fcoeff*dabs(lagrange)*tangent(1:3)
470 ctstate%tangentForce_final(1:3) = tf_final(1:3)
472 tf_final(1:3) = ctstate%tangentForce_final(1:3)
475 cttforce(1:3) = -tf_final(1:3)
477 cttforce(j*3+1:j*3+3) = shapefunc(j)*tf_final(1:3)
482 end subroutine getcontactnodalforce
486 subroutine gettrialfricforceandcheckfricstate(nnode,tPenalty,fcoeff,lagrange,normal,shapefunc,nTm,ndDu,ctstate)
489 integer(kind=kint) :: nnode
490 integer(kind=kint) :: i, j
491 real(kind=kreal) :: fcoeff, tpenalty
492 real(kind=kreal) :: lagrange
493 real(kind=kreal) :: nddu((nnode + 1)*3)
494 real(kind=kreal) :: normal(3), shapefunc(nnode)
495 real(kind=kreal) :: ntm((nnode + 1)*3)
496 real(kind=kreal) :: dotp
497 real(kind=kreal) :: relativedisp(3)
498 real(kind=kreal) :: tf_yield
502 dotp = dot_product(ntm,nddu)
504 relativedisp(i) = - nddu(i)
506 relativedisp(i) = relativedisp(i) + shapefunc(j)*nddu(j*3+i)
508 relativedisp(i) = relativedisp(i) - dotp*normal(i)
509 ctstate%reldisp(i) = -relativedisp(i)
510 ctstate%tangentForce_trial(i) = ctstate%tangentForce1(i) -tpenalty*relativedisp(i)
513 tf_yield = fcoeff*dabs(lagrange)
514 if(ctstate%state ==
contactslip) tf_yield =0.99d0*tf_yield
515 if( dsqrt(dot_product(ctstate%tangentForce_trial,ctstate%tangentForce_trial)) <= tf_yield )
then
521 end subroutine gettrialfricforceandcheckfricstate
526 subroutine update_ndforce_contact(nnode,ndLocal,id_lagrange,lagrange,ctNForce,ctTForce,hecMAT,cont_nforce,cont_fric)
528 type(hecmwst_matrix) :: hecmat
529 integer(kind=kint) :: nnode, ndlocal(nnode + 1)
531 integer(kind=kint) :: id_lagrange
532 real(kind=kreal) :: lagrange
533 integer(kind=kint) :: np, ndof
534 integer (kind=kint) :: i, inod, idx
535 real(kind=kreal) :: ctnforce((nnode+1)*3+1)
536 real(kind=kreal) :: cttforce((nnode+1)*3+1)
537 real(kind=kreal),
pointer :: cont_nforce(:)
538 real(kind=kreal),
pointer,
optional :: cont_fric(:)
540 np = hecmat%NP; ndof = hecmat%NDOF
545 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)
546 cont_nforce(idx:idx+2) = cont_nforce(idx:idx+2) + ctnforce((i-1)*3+1:(i-1)*3+3)
547 if(
present(cont_fric) ) cont_fric(idx:idx+2) = cont_fric(idx:idx+2) + cttforce((i-1)*3+1:(i-1)*3+3)
550 hecmat%B(np*ndof+id_lagrange) = ctnforce((nnode+1)*3+1)+cttforce((nnode+1)*3+1)
559 type(hecmwst_local_mesh) :: hecmesh
560 type(hecmwst_matrix) :: hecmat
562 type(hecmwst_matrix_lagrange) :: heclagmat
563 integer(kind=kint) :: cstep
564 integer(kind=kint) :: np, ndof
565 integer(kind=kint) :: i, j, k, l, id_lagrange, lnod, grpid
566 integer(kind=kint) :: ctsurf, etype, nnode, ndlocal(21)
567 real(kind=kreal) :: ndu(21*3), ndcoord(21*3), lagrange
568 real(kind=kreal) :: normal(3), shapefunc(21)
569 real(kind=kreal) :: ntm(10*3)
570 real(kind=kreal) :: tf_final(3)
571 real(kind=kreal) :: ctforce(21*3 + 1)
573 integer(kind=kint) :: algtype, nlag
574 real(kind=kreal) :: ctnforce(21*3+1)
575 real(kind=kreal) :: cttforce(21*3+1)
577 real(kind=kreal) :: ctime,
etime
578 integer(kind=kint) :: if_type
580 np = hecmat%NP ; ndof = hecmat%NDOF
584 do i = 1, fstrsolid%n_contacts
586 grpid = fstrsolid%contacts(i)%group
589 algtype = fstrsolid%contacts(i)%algtype
592 if_flag = (fstrsolid%contacts(i)%if_type /= 0)
594 ctime = fstrsolid%contacts(i)%ctime
595 etime = fstrsolid%contacts(i)%if_etime
596 if_type = fstrsolid%contacts(i)%if_type
599 do j = 1,
size(fstrsolid%contacts(i)%slave)
601 if( fstrsolid%contacts(i)%states(j)%state ==
contactfree ) cycle
604 ctsurf = fstrsolid%contacts(i)%states(j)%surface
605 etype = fstrsolid%contacts(i)%master(ctsurf)%etype
606 nnode =
size(fstrsolid%contacts(i)%master(ctsurf)%nodes)
607 ndlocal(1) = fstrsolid%contacts(i)%slave(j)
608 ndlocal(2:nnode+1) = fstrsolid%contacts(i)%master(ctsurf)%nodes(1:nnode)
610 ndu((k-1)*3+1:(k-1)*3+3) = fstrsolid%unode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
611 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)
615 id_lagrange = id_lagrange + 1
616 lagrange = fstrsolid%contacts(i)%states(j)%multiplier(k)
620 call getcontactnodalforce(etype,nnode,ndcoord,ndu,fstrsolid%contacts(i)%states(j), &
621 fstrsolid%contacts(i)%tPenalty,fstrsolid%contacts(i)%fcoeff,lagrange,ctnforce,cttforce,.false.)
624 & hecmat,fstrsolid%CONT_NFORCE,fstrsolid%CONT_FRIC)
626 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%contacts(i)%states(j),lagrange,ctnforce,cttforce)
628 call update_ndforce_contact(nnode,ndlocal,id_lagrange,-1.d0,ctnforce,cttforce,hecmat,fstrsolid%CONT_NFORCE)
635 do i = 1, fstrsolid%n_embeds
637 grpid = fstrsolid%embeds(i)%group
641 do j = 1,
size(fstrsolid%embeds(i)%slave)
643 if( fstrsolid%embeds(i)%states(j)%state ==
contactfree ) cycle
645 ctsurf = fstrsolid%embeds(i)%states(j)%surface
646 etype = fstrsolid%embeds(i)%master(ctsurf)%etype
647 nnode =
size(fstrsolid%embeds(i)%master(ctsurf)%nodes)
648 ndlocal(1) = fstrsolid%embeds(i)%slave(j)
649 ndlocal(2:nnode+1) = fstrsolid%embeds(i)%master(ctsurf)%nodes(1:nnode)
651 ndu((k-1)*3+1:(k-1)*3+3) = fstrsolid%unode((ndlocal(k)-1)*3+1:(ndlocal(k)-1)*3+3)
652 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)
656 id_lagrange = id_lagrange + 1
657 lagrange = fstrsolid%embeds(i)%states(j)%multiplier(k)
659 call gettiednodalforce(etype,nnode,k,ndu,fstrsolid%embeds(i)%states(j),lagrange,ctnforce,cttforce)
661 call update_ndforce_contact(nnode,ndlocal,id_lagrange,-1.d0,ctnforce,cttforce,hecmat,fstrsolid%EMBED_NFORCE)
671 integer(kind=kint) :: nnode, i
673 real(kind=kreal) :: coords(:), ctime
674 real(kind=kreal) :: factor, d(3)
676 d = - cstate%shrink_factor * cstate%direction(1:3)
679 coords(1+i*3:(i+1)*3) = coords(1+i*3:(i+1)*3) + d(1:3)