23 include
'fstr_ctrl_util_f.inc'
28 character(len=HECMW_NAME_LEN) :: name
31 character(len=HECMW_NAME_LEN) :: pair_name
32 integer :: surf_id1, surf_id2
33 integer :: surf_id1_sgrp
35 integer,
pointer :: slave(:)=>null()
36 real(kind=kreal) :: fcoeff
37 real(kind=kreal) :: tpenalty
53 type(hecmwst_contact_comm) :: comm
54 type(bucketdb) :: master_bktdb
56 type(tcontactparam),
pointer :: cparam=>null()
61 integer(kind=kint) :: contact2free
62 integer(kind=kint) :: contact2neighbor
63 integer(kind=kint) :: contact2difflpos
64 integer(kind=kint) :: free2contact
65 integer(kind=kint) :: contactnode_previous
66 integer(kind=kint) :: contactnode_current
69 private :: is_mpc_available
70 private :: is_active_contact
71 private :: cal_node_normal
72 private :: track_contact_position
73 private :: reset_contact_force
78 logical function is_mpc_available( contact )
79 type(
tcontact),
intent(in) :: contact
80 is_mpc_available = .true.
81 if( contact%fcoeff/=0.d0 ) is_mpc_available = .false.
86 integer(kind=kint),
intent(in) :: file
87 type(
tcontact),
intent(in) :: contact
89 write(file,*)
"CONTACT:", contact%ctype,contact%group,trim(contact%pair_name),contact%fcoeff
90 write(file,*)
"---Slave----"
91 write(file,*)
"num.slave",
size(contact%slave)
92 if(
associated(contact%slave) )
then
93 do i=1,
size(contact%slave)
94 write(file, *) contact%slave(i)
97 write(file,*)
"----master---"
98 write(file,*)
"num.master",
size(contact%master)
99 if(
associated(contact%master) )
then
100 do i=1,
size(contact%master)
110 if(
associated( contact%slave ) )
deallocate(contact%slave)
111 if(
associated( contact%master ) )
then
112 do i=1,
size( contact%master )
115 deallocate(contact%master)
117 if(
associated(contact%states) )
deallocate(contact%states)
125 type(hecmwst_local_mesh),
pointer :: hecmesh
134 do i=1,hecmesh%contact_pair%n_pair
135 if( hecmesh%contact_pair%name(i) == contact%pair_name )
then
136 contact%ctype = hecmesh%contact_pair%type(i)
137 contact%surf_id1 = hecmesh%contact_pair%slave_grp_id(i)
138 contact%surf_id2 = hecmesh%contact_pair%master_grp_id(i)
139 contact%surf_id1_sgrp = hecmesh%contact_pair%slave_orisgrp_id(i)
143 if( .not. isfind ) return;
144 if( contact%fcoeff<=0.d0 ) contact%fcoeff=0.d0
145 if( contact%ctype < 1 .and. contact%ctype > 3 )
return
146 if( contact%group<=0 )
return
154 type(hecmwst_local_mesh),
pointer :: hecmesh
155 type(tcontactparam),
target :: cparam
156 integer(kint),
intent(in),
optional ::
myrank
158 integer :: i, j, is, ie, cgrp, nsurf, nslave, ic, ic_type, iss, nn, ii
159 integer :: count,nodeid
163 contact%cparam => cparam
166 cgrp = contact%surf_id2
168 is= hecmesh%surf_group%grp_index(cgrp-1) + 1
169 ie= hecmesh%surf_group%grp_index(cgrp )
175 ic = hecmesh%surf_group%grp_item(2*i-1)
176 if(hecmesh%elem_ID(ic*2) /=
myrank) cycle
179 allocate( contact%master(count) )
182 ic = hecmesh%surf_group%grp_item(2*i-1)
183 if(hecmesh%elem_ID(ic*2) /=
myrank) cycle
185 nsurf = hecmesh%surf_group%grp_item(2*i)
186 ic_type = hecmesh%elem_type(ic)
188 iss = hecmesh%elem_node_index(ic-1)
189 do j=1,
size( contact%master(count)%nodes )
190 nn = contact%master(count)%nodes(j)
191 contact%master(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
197 allocate( contact%master(ie-is+1) )
199 ic = hecmesh%surf_group%grp_item(2*i-1)
200 nsurf = hecmesh%surf_group%grp_item(2*i)
201 ic_type = hecmesh%elem_type(ic)
203 iss = hecmesh%elem_node_index(ic-1)
204 do j=1,
size( contact%master(i-is+1)%nodes )
205 nn = contact%master(i-is+1)%nodes(j)
206 contact%master(i-is+1)%nodes(j) = hecmesh%elem_node_item( iss+nn )
214 cgrp = contact%surf_id1
216 is= hecmesh%node_group%grp_index(cgrp-1) + 1
217 ie= hecmesh%node_group%grp_index(cgrp )
220 nodeid = hecmesh%global_node_ID(hecmesh%node_group%grp_item(i))
226 if( hecmesh%node_group%grp_item(i) <= hecmesh%nn_internal)
then
231 allocate( contact%slave(nslave) )
232 allocate( contact%states(nslave) )
235 if(.not.
present(
myrank))
then
237 if( hecmesh%node_group%grp_item(i) > hecmesh%nn_internal) cycle
240 contact%slave(ii) = hecmesh%node_group%grp_item(i)
241 contact%states(ii)%state = -1
242 contact%states(ii)%multiplier(:) = 0.d0
243 contact%states(ii)%tangentForce(:) = 0.d0
244 contact%states(ii)%tangentForce1(:) = 0.d0
245 contact%states(ii)%tangentForce_trial(:) = 0.d0
246 contact%states(ii)%tangentForce_final(:) = 0.d0
247 contact%states(ii)%reldisp(:) = 0.d0
266 contact%symmetric = .true.
273 type(hecmwst_local_mesh),
pointer :: hecmesh
274 type(tcontactparam),
target :: cparam
275 integer(kint),
intent(in),
optional ::
myrank
277 integer :: i, j, is, ie, cgrp, nsurf, nslave, ic, ic_type, iss, nn, ii
278 integer :: count,nodeid
282 embed%cparam => cparam
285 cgrp = embed%surf_id2
287 is= hecmesh%elem_group%grp_index(cgrp-1) + 1
288 ie= hecmesh%elem_group%grp_index(cgrp )
294 ic = hecmesh%elem_group%grp_item(i)
295 if(hecmesh%elem_ID(ic*2) /=
myrank) cycle
298 allocate( embed%master(count) )
301 ic = hecmesh%elem_group%grp_item(i)
302 if(hecmesh%elem_ID(ic*2) /=
myrank) cycle
304 ic_type = hecmesh%elem_type(ic)
306 iss = hecmesh%elem_node_index(ic-1)
307 do j=1,
size( embed%master(count)%nodes )
308 nn = embed%master(count)%nodes(j)
309 embed%master(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
315 allocate( embed%master(ie-is+1) )
317 ic = hecmesh%elem_group%grp_item(i)
318 ic_type = hecmesh%elem_type(ic)
320 iss = hecmesh%elem_node_index(ic-1)
321 do j=1,
size( embed%master(i-is+1)%nodes )
322 nn = embed%master(i-is+1)%nodes(j)
323 embed%master(i-is+1)%nodes(j) = hecmesh%elem_node_item( iss+nn )
333 cgrp = embed%surf_id1
335 is= hecmesh%node_group%grp_index(cgrp-1) + 1
336 ie= hecmesh%node_group%grp_index(cgrp )
339 nodeid = hecmesh%global_node_ID(hecmesh%node_group%grp_item(i))
345 if( hecmesh%node_group%grp_item(i) <= hecmesh%nn_internal)
then
350 allocate( embed%slave(nslave) )
351 allocate( embed%states(nslave) )
354 if(.not.
present(
myrank))
then
356 if( hecmesh%node_group%grp_item(i) > hecmesh%nn_internal) cycle
359 embed%slave(ii) = hecmesh%node_group%grp_item(i)
360 embed%states(ii)%state = -1
361 embed%states(ii)%multiplier(:) = 0.d0
362 embed%states(ii)%tangentForce(:) = 0.d0
363 embed%states(ii)%tangentForce1(:) = 0.d0
364 embed%states(ii)%tangentForce_trial(:) = 0.d0
365 embed%states(ii)%tangentForce_final(:) = 0.d0
366 embed%states(ii)%reldisp(:) = 0.d0
385 embed%symmetric = .true.
394 if( .not.
associated(contact%states) )
return
395 do i=1,
size( contact%states )
396 contact%states(i)%state = -1
401 logical function is_active_contact( acgrp, contact )
402 integer,
intent(in) :: acgrp(:)
403 type(
tcontact),
intent(in) :: contact
404 if( any( acgrp==contact%group ) )
then
405 is_active_contact = .true.
407 is_active_contact = .false.
414 subroutine scan_contact_state( flag_ctAlgo, contact, currpos, currdisp, ndforce, infoCTChange, &
415 nodeID, elemID, is_init, active, mu, B )
416 character(len=9),
intent(in) :: flag_ctAlgo
417 type(
tcontact ),
intent(inout) :: contact
419 real(kind=kreal),
intent(in) :: currpos(:)
420 real(kind=kreal),
intent(in) :: currdisp(:)
421 real(kind=kreal),
intent(in) :: ndforce(:)
422 integer(kind=kint),
intent(in) :: nodeID(:)
423 integer(kind=kint),
intent(in) :: elemID(:)
424 logical,
intent(in) :: is_init
425 logical,
intent(out) :: active
426 real(kind=kreal),
intent(in) ::
mu
427 real(kind=kreal),
optional,
target :: b(:)
429 real(kind=kreal) :: distclr
430 integer(kind=kint) :: slave, id, etype
431 integer(kind=kint) :: nn, i, j, iSS, nactive
432 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node )
433 real(kind=kreal) :: nlforce, slforce(3)
435 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
437 integer,
pointer :: indexMaster(:),indexCand(:)
438 integer :: nMaster,idm,nMasterMax,bktID,nCand
439 logical :: is_cand, is_present_B
440 real(kind=kreal),
pointer :: bp(:)
443 distclr = contact%cparam%DISTCLR_INIT
445 distclr = contact%cparam%DISTCLR_FREE
448 do i= 1,
size(contact%slave)
457 allocate(contact_surf(
size(nodeid)))
458 allocate(states_prev(
size(contact%slave)))
459 contact_surf(:) = huge(0)
460 do i = 1,
size(contact%slave)
461 states_prev(i) = contact%states(i)%state
468 is_present_b =
present(b)
469 if( is_present_b ) bp => b
479 do i= 1,
size(contact%slave)
480 slave = contact%slave(i)
482 slforce(1:3)=ndforce(3*slave-2:3*slave)
483 id = contact%states(i)%surface
484 nlforce = contact%states(i)%multiplier(1)
489 if (.not.is_init) cycle
492 if( nlforce < contact%cparam%TENSILE_FORCE )
then
494 contact%states(i)%multiplier(:) = 0.d0
495 write(*,
'(A,i10,A,i10,A,e12.3)')
"Node",nodeid(slave),
" free from contact with element", &
496 elemid(contact%master(id)%eid),
" with tensile force ", nlforce
499 if( contact%algtype /=
contactfslid .or. (.not. is_present_b) )
then
500 contact_surf(contact%slave(i)) = -elemid(contact%master(id)%eid)
502 call track_contact_position( flag_ctalgo, i, contact, currpos, currdisp,
mu, infoctchange, nodeid, elemid, bp )
504 id = contact%states(i)%surface
505 contact_surf(contact%slave(i)) = -elemid(contact%master(id)%eid)
509 else if( contact%states(i)%state==
contactfree )
then
510 if( contact%algtype ==
contacttied .and. .not. is_init ) cycle
511 coord(:) = currpos(3*slave-2:3*slave)
516 if (ncand == 0) cycle
517 allocate(indexcand(ncand))
521 allocate(indexmaster(nmastermax))
527 if (.not.
is_in_surface_box( contact%master(id), coord(1:3), contact%cparam%BOX_EXP_RATE )) cycle
528 nmaster = nmaster + 1
529 indexmaster(nmaster) = id
531 deallocate(indexcand)
533 if(nmaster == 0)
then
534 deallocate(indexmaster)
539 id = indexmaster(idm)
540 etype = contact%master(id)%etype
541 nn =
size( contact%master(id)%nodes )
543 iss = contact%master(id)%nodes(j)
544 elem(1:3,j)=currpos(3*iss-2:3*iss)
547 isin,distclr,localclr=contact%cparam%CLEARANCE )
548 if( .not. isin ) cycle
549 contact%states(i)%surface = id
550 contact%states(i)%multiplier(:) = 0.d0
551 iss = isinsideelement( etype, contact%states(i)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
553 call cal_node_normal( id, iss, contact%master, currpos, contact%states(i)%lpos(1:2), &
554 contact%states(i)%direction(:) )
555 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
556 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3,A,3f7.3,A,i6)')
"Node",nodeid(slave),
" contact with element", &
557 elemid(contact%master(id)%eid), &
558 " with distance ", contact%states(i)%distance,
" at ",contact%states(i)%lpos(1:2), &
559 " along direction ", contact%states(i)%direction,
" rank=",hecmw_comm_get_rank()
562 deallocate(indexmaster)
567 if( contact%algtype ==
contacttied .and. .not. is_init )
then
568 deallocate(contact_surf)
569 deallocate(states_prev)
575 do i = 1,
size(contact%slave)
577 id = contact%states(i)%surface
578 if (abs(contact_surf(contact%slave(i))) /= elemid(contact%master(id)%eid))
then
580 write(*,
'(A,i10,A,i10,A,i6,A,i6,A)')
"Node",nodeid(contact%slave(i)),
" contact with element", &
581 & elemid(contact%master(id)%eid),
" in rank",hecmw_comm_get_rank(),
" freed due to duplication"
583 nactive = nactive + 1
587 infoctchange%free2contact = infoctchange%free2contact + 1
589 infoctchange%contact2free = infoctchange%contact2free + 1
592 active = (nactive > 0)
593 deallocate(contact_surf)
594 deallocate(states_prev)
600 subroutine scan_embed_state( flag_ctAlgo, embed, currpos, currdisp, ndforce, infoCTChange, &
601 nodeID, elemID, is_init, active, mu, B )
602 character(len=9),
intent(in) :: flag_ctAlgo
603 type(
tcontact ),
intent(inout) :: embed
605 real(kind=kreal),
intent(in) :: currpos(:)
606 real(kind=kreal),
intent(in) :: currdisp(:)
607 real(kind=kreal),
intent(in) :: ndforce(:)
608 integer(kind=kint),
intent(in) :: nodeID(:)
609 integer(kind=kint),
intent(in) :: elemID(:)
610 logical,
intent(in) :: is_init
611 logical,
intent(out) :: active
612 real(kind=kreal),
intent(in) ::
mu
613 real(kind=kreal),
optional,
target :: b(:)
615 real(kind=kreal) :: distclr
616 integer(kind=kint) :: slave, id, etype
617 integer(kind=kint) :: nn, i, j, iSS, nactive
618 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node )
619 real(kind=kreal) :: nlforce, slforce(3)
621 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
623 integer,
pointer :: indexMaster(:),indexCand(:)
624 integer :: nMaster,idm,nMasterMax,bktID,nCand
625 logical :: is_cand, is_present_B
626 real(kind=kreal),
pointer :: bp(:)
629 distclr = embed%cparam%DISTCLR_INIT
631 distclr = embed%cparam%DISTCLR_FREE
633 do i= 1,
size(embed%slave)
642 allocate(contact_surf(
size(nodeid)))
643 allocate(states_prev(
size(embed%slave)))
644 contact_surf(:) = huge(0)
645 do i = 1,
size(embed%slave)
646 states_prev(i) = embed%states(i)%state
653 is_present_b =
present(b)
654 if( is_present_b ) bp => b
664 do i= 1,
size(embed%slave)
665 slave = embed%slave(i)
667 coord(:) = currpos(3*slave-2:3*slave)
672 if (ncand == 0) cycle
673 allocate(indexcand(ncand))
677 allocate(indexmaster(nmastermax))
683 if (.not.
is_in_surface_box( embed%master(id), coord(1:3), embed%cparam%BOX_EXP_RATE )) cycle
684 nmaster = nmaster + 1
685 indexmaster(nmaster) = id
687 deallocate(indexcand)
689 if(nmaster == 0)
then
690 deallocate(indexmaster)
695 id = indexmaster(idm)
696 etype = embed%master(id)%etype
697 if( mod(etype,10) == 2 ) etype = etype - 1
698 nn = getnumberofnodes(etype)
700 iss = embed%master(id)%nodes(j)
701 elem(1:3,j)=currpos(3*iss-2:3*iss)
704 isin,distclr,localclr=embed%cparam%CLEARANCE )
705 if( .not. isin ) cycle
706 embed%states(i)%surface = id
707 embed%states(i)%multiplier(:) = 0.d0
708 contact_surf(embed%slave(i)) = elemid(embed%master(id)%eid)
709 write(*,
'(A,i10,A,i10,A,3f7.3,A,i6)')
"Node",nodeid(slave),
" embeded to element", &
710 elemid(embed%master(id)%eid),
" at ",embed%states(i)%lpos(:),
" rank=",hecmw_comm_get_rank()
713 deallocate(indexmaster)
720 do i = 1,
size(embed%slave)
722 id = embed%states(i)%surface
723 if (abs(contact_surf(embed%slave(i))) /= elemid(embed%master(id)%eid))
then
725 write(*,
'(A,i10,A,i10,A,i6,A,i6,A)')
"Node",nodeid(embed%slave(i)),
" contact with element", &
726 & elemid(embed%master(id)%eid),
" in rank",hecmw_comm_get_rank(),
" freed due to duplication"
728 nactive = nactive + 1
732 infoctchange%free2contact = infoctchange%free2contact + 1
734 infoctchange%contact2free = infoctchange%contact2free + 1
737 active = (nactive > 0)
738 deallocate(contact_surf)
739 deallocate(states_prev)
744 subroutine cal_node_normal( csurf, isin, surf, currpos, lpos, normal )
746 integer,
intent(in) :: csurf
747 integer,
intent(in) :: isin
749 real(kind=kreal),
intent(in) :: currpos(:)
750 real(kind=kreal),
intent(in) :: lpos(:)
751 real(kind=kreal),
intent(out) :: normal(3)
752 integer(kind=kint) :: cnode, i, j, cnt, nd1, gn, etype, iSS, nn,cgn
753 real(kind=kreal) :: cnpos(2), elem(3, l_max_elem_node )
754 integer(kind=kint) :: cnode1, cnode2, gn1, gn2, nsurf, cgn1, cgn2, isin_n
755 real(kind=kreal) :: x=0, normal_n(3), lpos_n(2)
757 if( 1 <= isin .and. isin <= 4 )
then
759 gn = surf(csurf)%nodes(cnode)
760 etype = surf(csurf)%etype
762 nn =
size( surf(csurf)%nodes )
764 iss = surf(csurf)%nodes(j)
765 elem(1:3,j)=currpos(3*iss-2:3*iss)
769 do i=1,surf(csurf)%n_neighbor
770 nd1 = surf(csurf)%neighbor(i)
771 nn =
size( surf(nd1)%nodes )
772 etype = surf(nd1)%etype
775 iss = surf(nd1)%nodes(j)
776 elem(1:3,j)=currpos(3*iss-2:3*iss)
783 normal = normal+normal_n
788 elseif( 12 <= isin .and. isin <= 41 )
then
790 cnode2 = mod(isin, 10)
791 gn1 = surf(csurf)%nodes(cnode1)
792 gn2 = surf(csurf)%nodes(cnode2)
793 etype = surf(csurf)%etype
794 nn =
size( surf(csurf)%nodes )
796 iss = surf(csurf)%nodes(j)
797 elem(1:3,j)=currpos(3*iss-2:3*iss)
801 case (fe_tri3n, fe_tri6n, fe_tri6nc)
802 if ( isin==12 ) then; x=lpos(2)-lpos(1)
803 elseif( isin==23 ) then; x=1.d0-2.d0*lpos(2)
804 elseif( isin==31 ) then; x=2.d0*lpos(1)-1.d0
805 else; stop
"Error: cal_node_normal: invalid isin"
807 case (fe_quad4n, fe_quad8n)
808 if ( isin==12 ) then; x=lpos(1)
809 elseif( isin==23 ) then; x=lpos(2)
810 elseif( isin==34 ) then; x=-lpos(1)
811 elseif( isin==41 ) then; x=-lpos(2)
812 else; stop
"Error: cal_node_normal: invalid isin"
817 neib_loop:
do i=1, surf(csurf)%n_neighbor
818 nd1 = surf(csurf)%neighbor(i)
819 nn =
size( surf(nd1)%nodes )
820 etype = surf(nd1)%etype
824 iss = surf(nd1)%nodes(j)
825 elem(1:3,j)=currpos(3*iss-2:3*iss)
826 if( iss==gn1 ) cgn1=j
827 if( iss==gn2 ) cgn2=j
829 if( cgn1>0 .and. cgn2>0 )
then
831 isin_n = 10*cgn2 + cgn1
834 case (fe_tri3n, fe_tri6n, fe_tri6nc)
835 if ( isin_n==12 ) then; lpos_n(1)=0.5d0*(1.d0-x); lpos_n(2)=0.5d0*(1.d0+x)
836 elseif( isin_n==23 ) then; lpos_n(1)=0.d0; lpos_n(2)=0.5d0*(1.d0-x)
837 elseif( isin_n==31 ) then; lpos_n(1)=0.5d0*(1.d0+x); lpos_n(2)=0.d0
838 else; stop
"Error: cal_node_normal: invalid isin_n"
840 case (fe_quad4n, fe_quad8n)
841 if ( isin_n==12 ) then; lpos_n(1)= x; lpos_n(2)=-1.d0
842 elseif( isin_n==23 ) then; lpos_n(1)= 1.d0; lpos_n(2)= x
843 elseif( isin_n==34 ) then; lpos_n(1)=-x; lpos_n(2)= 1.d0
844 elseif( isin_n==41 ) then; lpos_n(1)=-1.d0; lpos_n(2)=-x
845 else; stop
"Error: cal_node_normal: invalid isin_n"
850 normal = normal+normal_n
857 normal = normal/ dsqrt( dot_product( normal, normal ) )
858 end subroutine cal_node_normal
861 subroutine track_contact_position( flag_ctAlgo, nslave, contact, currpos, currdisp, mu, infoCTChange, nodeID, elemID, B )
862 character(len=9),
intent(in) :: flag_ctAlgo
863 integer,
intent(in) :: nslave
864 type(
tcontact ),
intent(inout) :: contact
866 real(kind=kreal),
intent(in) :: currpos(:)
867 real(kind=kreal),
intent(in) :: currdisp(:)
868 real(kind=kreal),
intent(in) ::
mu
869 integer(kind=kint),
intent(in) :: nodeID(:)
870 integer(kind=kint),
intent(in) :: elemID(:)
871 real(kind=kreal),
intent(inout) :: b(:)
873 integer(kind=kint) :: slave, sid0, sid, etype
874 integer(kind=kint) :: nn, i, j, iSS
875 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node ), elem0(3, l_max_elem_node )
877 real(kind=kreal) :: opos(2), odirec(3)
878 integer(kind=kint) :: bktID, nCand, idm
879 integer(kind=kint),
allocatable :: indexCand(:)
883 slave = contact%slave(nslave)
884 coord(:) = currpos(3*slave-2:3*slave)
886 sid0 = contact%states(nslave)%surface
887 opos = contact%states(nslave)%lpos(1:2)
888 odirec = contact%states(nslave)%direction
889 etype = contact%master(sid0)%etype
890 nn = getnumberofnodes( etype )
892 iss = contact%master(sid0)%nodes(j)
893 elem(1:3,j)=currpos(3*iss-2:3*iss)
894 elem0(1:3,j)=currpos(3*iss-2:3*iss)-currdisp(3*iss-2:3*iss)
896 call project_point2element( coord,etype,nn,elem,contact%master(sid0)%reflen,contact%states(nslave), &
897 isin,contact%cparam%DISTCLR_NOCHECK,contact%states(nslave)%lpos(1:2),contact%cparam%CLR_SAME_ELEM )
898 if( .not. isin )
then
899 do i=1, contact%master(sid0)%n_neighbor
900 sid = contact%master(sid0)%neighbor(i)
901 etype = contact%master(sid)%etype
902 nn = getnumberofnodes( etype )
904 iss = contact%master(sid)%nodes(j)
905 elem(1:3,j)=currpos(3*iss-2:3*iss)
908 isin,contact%cparam%DISTCLR_NOCHECK,localclr=contact%cparam%CLEARANCE )
910 contact%states(nslave)%surface = sid
916 if( .not. isin )
then
917 write(*,*)
'Warning: contact moved beyond neighbor elements'
922 allocate(indexcand(ncand))
926 if( sid==sid0 ) cycle
927 if(
associated(contact%master(sid0)%neighbor) )
then
928 if( any(sid==contact%master(sid0)%neighbor(:)) ) cycle
930 if (.not.
is_in_surface_box( contact%master(sid), coord(1:3), contact%cparam%BOX_EXP_RATE )) cycle
931 etype = contact%master(sid)%etype
932 nn =
size( contact%master(sid)%nodes )
934 iss = contact%master(sid)%nodes(j)
935 elem(1:3,j)=currpos(3*iss-2:3*iss)
938 isin,contact%cparam%DISTCLR_NOCHECK,localclr=contact%cparam%CLEARANCE )
940 contact%states(nslave)%surface = sid
944 deallocate(indexcand)
949 if( contact%states(nslave)%surface==sid0 )
then
950 if(any(dabs(contact%states(nslave)%lpos(1:2)-opos(:)) >= contact%cparam%CLR_DIFFLPOS))
then
952 infoctchange%contact2difflpos = infoctchange%contact2difflpos + 1
955 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3)')
"Node",nodeid(slave),
" move to contact with", &
956 elemid(contact%master(sid)%eid),
" with distance ", &
957 contact%states(nslave)%distance,
" at ",contact%states(nslave)%lpos(1:2)
959 infoctchange%contact2neighbor = infoctchange%contact2neighbor + 1
960 if( flag_ctalgo==
'ALagrange' ) &
961 call reset_contact_force( contact, currpos, nslave, sid0, opos, odirec, b )
963 if( flag_ctalgo==
'SLagrange' )
call update_tangentforce(etype,nn,elem0,elem,contact%states(nslave))
964 iss = isinsideelement( etype, contact%states(nslave)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
966 call cal_node_normal( contact%states(nslave)%surface, iss, contact%master, currpos, &
967 contact%states(nslave)%lpos(1:2), contact%states(nslave)%direction(:) )
968 else if( .not. isin )
then
969 write(*,
'(A,i10,A)')
"Node",nodeid(slave),
" move out of contact"
971 contact%states(nslave)%multiplier(:) = 0.d0
974 end subroutine track_contact_position
978 integer,
intent(in) :: nslave
979 type(
tcontact ),
intent(inout) :: contact
980 real(kind=kreal),
intent(in) :: currpos(:)
982 integer(kind=kint) :: slave, sid0, sid, etype
983 integer(kind=kint) :: nn, i, j, iSS
984 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node ), elem0(3, l_max_elem_node )
986 real(kind=kreal) :: opos(2), odirec(3)
987 integer(kind=kint) :: bktID, nCand, idm
988 integer(kind=kint),
allocatable :: indexCand(:)
993 slave = contact%slave(nslave)
994 coord(:) = currpos(3*slave-2:3*slave)
996 sid0 = contact%states(nslave)%surface
997 opos = contact%states(nslave)%lpos(1:2)
998 odirec = contact%states(nslave)%direction
999 etype = contact%master(sid0)%etype
1000 nn = getnumberofnodes( etype )
1002 iss = contact%master(sid0)%nodes(j)
1003 elem(1:3,j)=currpos(3*iss-2:3*iss)
1006 cstate_tmp%state = contact%states(nslave)%state
1007 cstate_tmp%surface = sid0
1009 isin,contact%cparam%DISTCLR_NOCHECK,contact%states(nslave)%lpos,contact%cparam%CLR_SAME_ELEM )
1012 iss = isinsideelement( etype, cstate_tmp%lpos, contact%cparam%CLR_CAL_NORM )
1014 call cal_node_normal( cstate_tmp%surface, iss, contact%master, currpos, &
1015 cstate_tmp%lpos, cstate_tmp%direction(:) )
1018 contact%states(nslave)%direction = cstate_tmp%direction
1025 subroutine reset_contact_force( contact, currpos, lslave, omaster, opos, odirec, B )
1026 type(
tcontact ),
intent(inout) :: contact
1027 real(kind=kreal),
intent(in) :: currpos(:)
1028 integer,
intent(in) :: lslave
1029 integer,
intent(in) :: omaster
1030 real(kind=kreal),
intent(in) :: opos(2)
1031 real(kind=kreal),
intent(in) :: odirec(3)
1032 real(kind=kreal),
intent(inout) :: b(:)
1034 integer(kind=kint) :: slave, etype, master
1035 integer(kind=kint) :: nn, j, iSS
1036 real(kind=kreal) :: nrlforce, fcoeff, tangent(3,2)
1037 real(kind=kreal) :: elemcrd(3, l_max_elem_node )
1038 real(kind=kreal) :: shapefunc(l_max_surface_node)
1039 real(kind=kreal) :: metric(2,2), dispmat(2,l_max_elem_node*3+3)
1040 real(kind=kreal) :: fric(2), f3(l_max_elem_node*3+3)
1041 integer(kind=kint) :: i, idx0
1043 slave = contact%slave(lslave)
1044 fcoeff = contact%fcoeff
1046 nrlforce = contact%states(lslave)%multiplier(1)
1047 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)+nrlforce*odirec
1048 nn =
size( contact%master(omaster)%nodes )
1049 etype = contact%master(omaster)%etype
1050 call getshapefunc( etype, opos(:), shapefunc )
1052 iss = contact%master(omaster)%nodes(j)
1057 b(idx0+i) = b(idx0+i)-nrlforce*shapefunc(j)*odirec(i)
1060 if( fcoeff/=0.d0 )
then
1062 iss = contact%master(omaster)%nodes(j)
1063 elemcrd(:,j) = currpos(3*iss-2:3*iss)
1067 fric(1:2) = contact%states(lslave)%multiplier(2:3)
1068 f3(:) = fric(1)*dispmat(1,:)+fric(2)*dispmat(2,:)
1069 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)+f3(1:3)
1071 iss = contact%master(omaster)%nodes(j)
1076 b(idx0+i) = b(idx0+i)+f3(3*j+i)
1082 master = contact%states(lslave)%surface
1083 nn =
size( contact%master(master)%nodes )
1084 etype = contact%master(master)%etype
1085 call getshapefunc( etype, contact%states(lslave)%lpos(1:2), shapefunc )
1086 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-nrlforce*contact%states(lslave)%direction
1088 iss = contact%master(master)%nodes(j)
1094 b(idx0+i) = b(idx0+i)+nrlforce* &
1095 shapefunc(j)*contact%states(lslave)%direction(i)
1098 if( fcoeff/=0.d0 )
then
1100 iss = contact%master(master)%nodes(j)
1101 elemcrd(:,j) = currpos(3*iss-2:3*iss)
1103 call dispincrematrix( contact%states(lslave)%lpos(1:2), etype, nn, elemcrd, tangent, &
1105 fric(1:2) = contact%states(lslave)%multiplier(2:3)
1106 f3(:) = fric(1)*dispmat(1,:)+fric(2)*dispmat(2,:)
1107 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-f3(1:3)
1109 iss = contact%master(master)%nodes(j)
1114 b(idx0+i) = b(idx0+i)-f3(3*j+i)
1119 end subroutine reset_contact_force
1127 real(kind=kreal),
intent(in) :: coord(:)
1128 real(kind=kreal),
intent(in) :: disp(:)
1129 real(kind=kreal),
intent(in) :: ddisp(:)
1130 real(kind=kreal),
intent(in) :: fcoeff
1131 real(kind=kreal),
intent(in) ::
mu,
mut
1132 real(kind=kreal),
intent(inout) :: b(:)
1134 integer(kind=kint) :: slave, etype, master
1135 integer(kind=kint) :: nn, i, j, iSS
1136 real(kind=kreal) :: nrlforce, elemdisp(3,l_max_elem_node), tangent(3,2)
1137 real(kind=kreal) :: dg(3), elemg(3), elemcrd(3, l_max_elem_node )
1138 real(kind=kreal) :: dgn, dxi(2), dxy(2), shapefunc(l_max_surface_node)
1139 real(kind=kreal) :: metric(2,2), dispmat(2,l_max_elem_node*3+3)
1140 real(kind=kreal) :: fric(2), f3(3*l_max_elem_node+3), edisp(3*l_max_elem_node+3)
1142 do i= 1,
size(contact%slave)
1144 slave = contact%slave(i)
1145 edisp(1:3) = ddisp(3*slave-2:3*slave)
1146 master = contact%states(i)%surface
1148 nn =
size( contact%master(master)%nodes )
1149 etype = contact%master(master)%etype
1151 iss = contact%master(master)%nodes(j)
1152 elemdisp(:,j) = ddisp(3*iss-2:3*iss)
1153 edisp(3*j+1:3*j+3) = ddisp(3*iss-2:3*iss)
1154 elemcrd(:,j) = coord(3*iss-2:3*iss)+disp(3*iss-2:3*iss)
1156 call getshapefunc( etype, contact%states(i)%lpos(1:2), shapefunc )
1161 elemg(:) = elemg(:)+shapefunc(j)*elemdisp(:,j)
1163 dg(:) = ddisp(3*slave-2:3*slave) - elemg(:)
1164 dgn = dot_product( contact%states(i)%direction, dg )
1165 nrlforce = contact%states(i)%multiplier(1)-
mu*(contact%states(i)%wkdist-dgn)
1166 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-nrlforce*contact%states(i)%direction
1169 iss = contact%master(master)%nodes(j)
1170 b(3*iss-2:3*iss) = b(3*iss-2:3*iss)+nrlforce* &
1171 shapefunc(j)*contact%states(i)%direction
1174 if( fcoeff==0.d0 ) cycle
1176 call dispincrematrix( contact%states(i)%lpos(1:2), etype, nn, elemcrd, tangent, &
1178 dxi(1) = dot_product( dispmat(1,1:nn*3+3), edisp(1:nn*3+3) )
1179 dxi(2) = dot_product( dispmat(2,1:nn*3+3), edisp(1:nn*3+3) )
1180 dxy(:) = matmul( metric, dxi )
1181 fric(1:2) = contact%states(i)%multiplier(2:3) +
mut*dxy(1:2)
1182 f3(:) = fric(1)*dispmat(1,:)+fric(2)*dispmat(2,:)
1185 dgn = dsqrt( f3(1)*f3(1)+f3(2)*f3(2)+f3(3)*f3(3) )
1186 f3(:) = f3(:)*fcoeff*contact%states(i)%multiplier(1)/dgn
1188 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-f3(1:3)
1190 iss = contact%master(master)%nodes(j)
1191 b(3*iss-2:3*iss) = b(3*iss-2:3*iss)-f3(3*j+1:3*j+3)
1201 real(kind=kreal),
intent(in) :: disp(:)
1202 real(kind=kreal),
intent(in) :: ddisp(:)
1203 real(kind=kreal),
intent(in) ::
mu
1204 real(kind=kreal),
intent(inout) :: b(:)
1206 integer(kind=kint) :: slave, etype, master
1207 integer(kind=kint) :: nn, i, j, iss
1208 real(kind=kreal) :: nrlforce(3)
1209 real(kind=kreal) :: dg(3)
1210 real(kind=kreal) :: shapefunc(l_max_surface_node)
1211 real(kind=kreal) :: edisp(3*l_max_elem_node+3)
1213 do i= 1,
size(contact%slave)
1215 slave = contact%slave(i)
1216 edisp(1:3) = disp(3*slave-2:3*slave)+ddisp(3*slave-2:3*slave)
1217 master = contact%states(i)%surface
1219 nn =
size( contact%master(master)%nodes )
1220 etype = contact%master(master)%etype
1222 iss = contact%master(master)%nodes(j)
1223 edisp(3*j+1:3*j+3) = disp(3*iss-2:3*iss)+ddisp(3*iss-2:3*iss)
1225 call getshapefunc( etype, contact%states(i)%lpos(1:2), shapefunc )
1228 dg(1:3) = edisp(1:3)
1230 dg(1:3) = dg(1:3)-shapefunc(j)*edisp(3*j+1:3*j+3)
1233 nrlforce(1:3) = contact%states(i)%multiplier(1:3)+
mu*dg(1:3)
1235 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-nrlforce(1:3)
1237 iss = contact%master(master)%nodes(j)
1238 b(3*iss-2:3*iss) = b(3*iss-2:3*iss) + shapefunc(j)*nrlforce(1:3)
1249 real(kind=kreal),
intent(in) :: coord(:)
1250 real(kind=kreal),
intent(in) :: disp(:)
1251 real(kind=kreal),
intent(in) :: ddisp(:)
1252 real(kind=kreal),
intent(in) :: fcoeff
1253 real(kind=kreal),
intent(in) ::
mu,
mut
1254 real(kind=kreal),
intent(out) ::
gnt(2)
1255 logical,
intent(inout) :: ctchanged
1257 integer(kind=kint) :: slave, etype, master
1258 integer(kind=kint) :: nn, i, j, iss, cnt
1259 real(kind=kreal) :: elemdisp(3,l_max_elem_node), tangent(3,2)
1260 real(kind=kreal) :: dg(3), elemg(3), elemcrd(3, l_max_elem_node )
1261 real(kind=kreal) :: dgn, dxi(2), dxy(2), shapefunc(l_max_surface_node)
1262 real(kind=kreal) :: metric(2,2), dispmat(2,l_max_elem_node*3+3)
1263 real(kind=kreal) :: lgnt(2), fric(2), f3(3*l_max_elem_node+3), edisp(3*l_max_elem_node+3)
1265 cnt =0; lgnt(:)=0.d0
1266 do i= 1,
size(contact%slave)
1268 slave = contact%slave(i)
1269 edisp(1:3) = ddisp(3*slave-2:3*slave)
1270 master = contact%states(i)%surface
1272 nn =
size( contact%master(master)%nodes )
1273 etype = contact%master(master)%etype
1275 iss = contact%master(master)%nodes(j)
1276 elemdisp(:,j) = ddisp(3*iss-2:3*iss)
1277 edisp(3*j+1:3*j+3) = ddisp(3*iss-2:3*iss)
1278 elemcrd(:,j) = coord(3*iss-2:3*iss)+disp(3*iss-2:3*iss)
1280 call getshapefunc( etype, contact%states(i)%lpos(1:2), shapefunc )
1285 elemg(:) = elemg(:)+shapefunc(j)*elemdisp(:,j)
1287 dg(:) = ddisp(3*slave-2:3*slave) - elemg(:)
1288 dgn = dot_product( contact%states(i)%direction, dg )
1289 contact%states(i)%wkdist = contact%states(i)%wkdist-dgn
1290 contact%states(i)%multiplier(1) = contact%states(i)%multiplier(1)-
mu*contact%states(i)%wkdist
1291 contact%states(i)%distance = contact%states(i)%distance - dgn
1293 lgnt(1) = lgnt(1)- contact%states(i)%wkdist
1295 if( fcoeff==0.d0 ) cycle
1297 call dispincrematrix( contact%states(i)%lpos(1:2), etype, nn, elemcrd, tangent, &
1299 dxi(1) = dot_product( dispmat(1,1:nn*3+3), edisp(1:nn*3+3) )
1300 dxi(2) = dot_product( dispmat(2,1:nn*3+3), edisp(1:nn*3+3) )
1301 dxy(:) = matmul( metric, dxi )
1302 fric(1:2) = contact%states(i)%multiplier(2:3) +
mut*dxy(1:2)
1303 f3(:) = fric(1)*dispmat(1,:)+fric(2)*dispmat(2,:)
1304 dgn = dsqrt( f3(1)*f3(1)+f3(2)*f3(2)+f3(3)*f3(3) )
1305 if( contact%states(i)%multiplier(1)>0.d0 )
then
1306 if( dgn > fcoeff*contact%states(i)%multiplier(1) )
then
1309 print *,
"Node", slave,
"to slip state",dgn, fcoeff*contact%states(i)%multiplier(1)
1312 fric(:) = fric(:)*fcoeff*contact%states(i)%multiplier(1)/dgn
1316 print *,
"Node", slave,
"to stick state",dgn, fcoeff*contact%states(i)%multiplier(1)
1321 contact%states(i)%multiplier(2:3) = fric(:)
1322 dxy(:) = matmul( dg, tangent )
1323 lgnt(2) = lgnt(2)+dsqrt( dxy(1)*dxy(1)+dxy(2)*dxy(2) )
1325 if(cnt>0) lgnt(:) = lgnt(:)/cnt
1333 real(kind=kreal),
intent(in) :: disp(:)
1334 real(kind=kreal),
intent(in) :: ddisp(:)
1335 real(kind=kreal),
intent(in) ::
mu
1336 logical,
intent(inout) :: ctchanged
1338 integer(kind=kint) :: slave, etype, master
1339 integer(kind=kint) :: nn, i, j, iss, cnt
1340 real(kind=kreal) :: dg(3), dgmax
1341 real(kind=kreal) :: shapefunc(l_max_surface_node)
1342 real(kind=kreal) :: edisp(3*l_max_elem_node+3)
1344 do i= 1,
size(contact%slave)
1346 slave = contact%slave(i)
1347 edisp(1:3) = disp(3*slave-2:3*slave)+ddisp(3*slave-2:3*slave)
1348 master = contact%states(i)%surface
1350 nn =
size( contact%master(master)%nodes )
1351 etype = contact%master(master)%etype
1353 iss = contact%master(master)%nodes(j)
1354 edisp(3*j+1:3*j+3) = disp(3*iss-2:3*iss)+ddisp(3*iss-2:3*iss)
1356 call getshapefunc( etype, contact%states(i)%lpos(1:2), shapefunc )
1359 dg(1:3) = edisp(1:3)
1361 dg(1:3) = dg(1:3)-shapefunc(j)*edisp(3*j+1:3*j+3)
1364 contact%states(i)%multiplier(1:3) = contact%states(i)%multiplier(1:3) +
mu*dg(1:3)
1369 dgmax = dgmax + dabs(edisp(j))
1371 dgmax = dgmax/dble((nn+1)*3)
1373 if( dabs(dg(j))/dmax1(1.d0,dgmax) > 1.d-3 ) ctchanged = .true.
1382 real(kind=kreal),
intent(in) :: coord(:)
1383 real(kind=kreal),
intent(in) :: disp(:)
1384 real(kind=kreal),
intent(inout) :: b(:)
1386 integer(kind=kint) :: slave, etype, master
1387 integer(kind=kint) :: nn, i, j, iss
1388 real(kind=kreal) :: fcoeff, nrlforce, tangent(3,2)
1389 real(kind=kreal) :: elemcrd(3, l_max_elem_node )
1390 real(kind=kreal) :: shapefunc(l_max_surface_node)
1391 real(kind=kreal) :: metric(2,2), dispmat(2,l_max_elem_node*3+3)
1392 real(kind=kreal) :: fric(2), f3(l_max_elem_node*3+3)
1393 fcoeff = contact%fcoeff
1394 do i= 1,
size(contact%slave)
1396 slave = contact%slave(i)
1397 master = contact%states(i)%surface
1399 nn =
size( contact%master(master)%nodes )
1400 etype = contact%master(master)%etype
1401 call getshapefunc( etype, contact%states(i)%lpos(1:2), shapefunc )
1404 nrlforce = contact%states(i)%multiplier(1)
1405 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-nrlforce*contact%states(i)%direction
1408 iss = contact%master(master)%nodes(j)
1409 b(3*iss-2:3*iss) = b(3*iss-2:3*iss)+nrlforce* &
1410 shapefunc(j)*contact%states(i)%direction
1413 if( fcoeff==0.d0 ) cycle
1416 iss = contact%master(master)%nodes(j)
1417 elemcrd(:,j) = coord(3*iss-2:3*iss)+disp(3*iss-2:3*iss)
1419 call dispincrematrix( contact%states(i)%lpos(1:2), etype, nn, elemcrd, tangent, &
1422 fric(1:2) = contact%states(i)%multiplier(2:3)
1423 f3(:) = fric(1)*dispmat(1,:)+fric(2)*dispmat(2,:)
1424 b(3*slave-2:3*slave) = b(3*slave-2:3*slave)-f3(1:3)
1426 iss = contact%master(master)%nodes(j)
1427 b(3*iss-2:3*iss) = b(3*iss-2:3*iss)-f3(3*j+1:3*j+3)
1436 real(kind=kreal),
intent(in) ::
dt
1437 real(kind=kreal),
intent(inout) :: relvel_vec(:)
1438 real(kind=kreal),
intent(inout) :: state_vec(:)
1440 integer(kind=kint) :: i, slave
1442 do i= 1,
size(contact%slave)
1443 slave = contact%slave(i)
1444 if( state_vec(slave) < 0.1d0 .or. contact%states(i)%state > 0 ) &
1445 & state_vec(slave) = dble(contact%states(i)%state)
1448 if(
dt < 1.d-16 ) cycle
1449 relvel_vec(3*slave-2:3*slave) = contact%states(i)%reldisp(1:3)/
dt
1457 integer(kind=kint) :: i
1459 do i= 1,
size(contact%slave)
1461 contact%states(i)%tangentForce(1:3) = 0.d0
1462 contact%states(i)%tangentForce_trial(1:3) = 0.d0
1463 contact%states(i)%tangentForce_final(1:3) = 0.d0
1465 contact%states(i)%tangentForce(1:3) = contact%states(i)%tangentForce_final(1:3)
1467 contact%states(i)%tangentForce1(1:3) = contact%states(i)%tangentForce(1:3)
1473 integer,
intent(in) :: nslave
1474 type(
tcontact ),
intent(inout) :: contact
1476 real(kind=kreal),
intent(in) :: currpos(:)
1477 real(kind=kreal),
intent(in) :: currdisp(:)
1478 integer(kind=kint),
intent(in) :: nodeID(:)
1479 integer(kind=kint),
intent(in) :: elemID(:)
1481 integer(kind=kint) :: slave, sid0, sid, etype
1482 integer(kind=kint) :: nn, i, j, iSS
1483 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node ), elem0(3, l_max_elem_node )
1485 real(kind=kreal) :: opos(2), odirec(3)
1486 integer(kind=kint) :: bktID, nCand, idm
1487 integer(kind=kint),
allocatable :: indexCand(:)
1491 slave = contact%slave(nslave)
1492 coord(:) = currpos(3*slave-2:3*slave)
1494 sid0 = contact%states(nslave)%surface
1495 opos = contact%states(nslave)%lpos(1:2)
1496 odirec = contact%states(nslave)%direction
1497 etype = contact%master(sid0)%etype
1498 nn = getnumberofnodes( etype )
1500 iss = contact%master(sid0)%nodes(j)
1501 elem(1:3,j)=currpos(3*iss-2:3*iss)
1502 elem0(1:3,j)=currpos(3*iss-2:3*iss)-currdisp(3*iss-2:3*iss)
1504 call project_point2element( coord,etype,nn,elem,contact%master(sid0)%reflen,contact%states(nslave), &
1505 isin,contact%cparam%DISTCLR_NOCHECK,contact%states(nslave)%lpos(1:2),contact%cparam%CLR_SAME_ELEM )
1506 if( .not. isin )
then
1507 do i=1, contact%master(sid0)%n_neighbor
1508 sid = contact%master(sid0)%neighbor(i)
1509 etype = contact%master(sid)%etype
1510 nn = getnumberofnodes( etype )
1512 iss = contact%master(sid)%nodes(j)
1513 elem(1:3,j)=currpos(3*iss-2:3*iss)
1515 call project_point2element( coord,etype,nn,elem,contact%master(sid)%reflen,contact%states(nslave), &
1516 isin,contact%cparam%DISTCLR_NOCHECK,localclr=contact%cparam%CLEARANCE )
1518 contact%states(nslave)%surface = sid
1524 if( .not. isin )
then
1525 write(*,*)
'Warning: contact moved beyond neighbor elements'
1530 allocate(indexcand(ncand))
1533 sid = indexcand(idm)
1534 if( sid==sid0 ) cycle
1535 if( any(sid==contact%master(sid0)%neighbor(:)) ) cycle
1536 if (.not.
is_in_surface_box( contact%master(sid), coord(1:3), contact%cparam%BOX_EXP_RATE )) cycle
1537 etype = contact%master(sid)%etype
1538 nn =
size( contact%master(sid)%nodes )
1540 iss = contact%master(sid)%nodes(j)
1541 elem(1:3,j)=currpos(3*iss-2:3*iss)
1543 call project_point2element( coord,etype,nn,elem,contact%master(sid)%reflen,contact%states(nslave), &
1544 isin,contact%cparam%DISTCLR_NOCHECK,localclr=contact%cparam%CLEARANCE )
1546 contact%states(nslave)%surface = sid
1550 deallocate(indexcand)
1555 if( contact%states(nslave)%surface==sid0 )
then
1556 if(any(dabs(contact%states(nslave)%lpos(1:2)-opos(:)) >= contact%cparam%CLR_DIFFLPOS))
then
1558 infoctchange%contact2difflpos = infoctchange%contact2difflpos + 1
1561 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3)')
"Node",nodeid(slave),
" move to contact with", &
1562 elemid(contact%master(sid)%eid),
" with distance ", &
1563 contact%states(nslave)%distance,
" at ",contact%states(nslave)%lpos(1:2)
1565 infoctchange%contact2neighbor = infoctchange%contact2neighbor + 1
1567 iss = isinsideelement( etype, contact%states(nslave)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
1569 call cal_node_normal( contact%states(nslave)%surface, iss, contact%master, currpos, &
1570 contact%states(nslave)%lpos(1:2), contact%states(nslave)%direction(:) )
1572 else if( .not. isin )
then
1573 write(*,
'(A,i10,A)')
"Node",nodeid(slave),
" move out of contact"
1575 contact%states(nslave)%multiplier(:) = 0.d0
1584 nodeID, elemID, is_init, active )
1587 real(kind=kreal),
intent(in) :: currpos(:)
1588 real(kind=kreal),
intent(in) :: currdisp(:)
1589 integer(kind=kint),
intent(in) :: nodeID(:)
1590 integer(kind=kint),
intent(in) :: elemID(:)
1591 logical,
intent(in) :: is_init
1592 logical,
intent(out) :: active
1594 real(kind=kreal) :: distclr
1595 integer(kind=kint) :: slave, id, etype
1596 integer(kind=kint) :: nn, i, j, iSS, nactive
1597 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node )
1598 real(kind=kreal) :: nlforce
1600 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
1602 integer,
pointer :: indexMaster(:),indexCand(:)
1603 integer :: nMaster,idm,nMasterMax,bktID,nCand
1607 distclr = contact%cparam%DISTCLR_INIT
1609 distclr = contact%cparam%DISTCLR_FREE
1612 do i= 1,
size(contact%slave)
1622 allocate(contact_surf(
size(nodeid)))
1623 allocate(states_prev(
size(contact%slave)))
1624 contact_surf(:) =
size(elemid)+1
1625 do i = 1,
size(contact%slave)
1626 states_prev(i) = contact%states(i)%state
1640 do i= 1,
size(contact%slave)
1641 slave = contact%slave(i)
1645 contact_surf(contact%slave(i)) = -contact%states(i)%surface
1647 else if( contact%states(i)%state==
contactfree )
then
1648 coord(:) = currpos(3*slave-2:3*slave)
1653 if (ncand == 0) cycle
1654 allocate(indexcand(ncand))
1658 allocate(indexmaster(nmastermax))
1664 if (.not.
is_in_surface_box( contact%master(id), coord(1:3), contact%cparam%BOX_EXP_RATE )) cycle
1665 nmaster = nmaster + 1
1666 indexmaster(nmaster) = id
1668 deallocate(indexcand)
1670 if(nmaster == 0)
then
1671 deallocate(indexmaster)
1676 id = indexmaster(idm)
1677 etype = contact%master(id)%etype
1678 nn =
size( contact%master(id)%nodes )
1680 iss = contact%master(id)%nodes(j)
1681 elem(1:3,j)=currpos(3*iss-2:3*iss)
1684 isin,distclr,localclr=contact%cparam%CLEARANCE )
1685 if( .not. isin ) cycle
1686 contact%states(i)%surface = id
1687 contact%states(i)%multiplier(:) = 0.d0
1688 iss = isinsideelement( etype, contact%states(i)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
1690 call cal_node_normal( id, iss, contact%master, currpos, contact%states(i)%lpos(1:2), &
1691 contact%states(i)%direction(:) )
1692 contact_surf(contact%slave(i)) = id
1693 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3,A,3f7.3)')
"Node",nodeid(slave),
" contact with element", &
1694 elemid(contact%master(id)%eid), &
1695 " with distance ", contact%states(i)%distance,
" at ",contact%states(i)%lpos(1:2), &
1696 " along direction ", contact%states(i)%direction
1699 deallocate(indexmaster)
1706 do i = 1,
size(contact%slave)
1708 if (abs(contact_surf(contact%slave(i))) /= contact%states(i)%surface)
then
1710 write(*,
'(A,i10,A,i6,A,i6,A)')
"Node",nodeid(contact%slave(i)), &
1711 " in rank",hecmw_comm_get_rank(),
" freed due to duplication"
1713 nactive = nactive + 1
1717 infoctchange%free2contact = infoctchange%free2contact + 1
1719 infoctchange%contact2free = infoctchange%contact2free + 1
1722 active = (nactive > 0)
1723 deallocate(contact_surf)
1724 deallocate(states_prev)