30 type(
tcontact),
intent(in) :: contact
31 integer(kind=kint),
intent(inout) :: known_masters(:)
32 integer(kind=kint),
intent(inout) :: n_known
33 integer(kind=kint),
intent(in) :: id
34 logical,
intent(out) :: is_known
36 integer(kind=kint) :: k
38 is_known = any(known_masters(1:n_known) == id)
42 if(
associated(contact%master(known_masters(k))%neighbor) )
then
43 if( any(contact%master(known_masters(k))%neighbor(1:contact%master(known_masters(k))%n_neighbor) == id) )
then
44 is_known = .true.;
exit
49 if( .not. is_known )
then
51 known_masters(n_known) = id
59 integer,
intent(in) :: nslave
60 type(
tcontact ),
intent(inout) :: contact
62 real(kind=kreal),
intent(in) :: currpos(:)
63 real(kind=kreal),
intent(in) :: currdisp(:)
64 integer(kind=kint),
intent(in) :: nodeID(:)
65 integer(kind=kint),
intent(in) :: elemID(:)
66 character(len=9),
intent(in),
optional :: flag_ctAlgo
68 integer(kind=kint) :: slave, sid0, sid, etype
69 integer(kind=kint) :: nn, i, j, iSS
70 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node), elem0(3, l_max_elem_node)
72 real(kind=kreal) :: opos(2)
73 integer(kind=kint) :: bktID, nCand, idm, id_best
74 integer(kind=kint),
allocatable :: indexCand(:)
75 logical :: is_implicit, update_tangent
78 is_implicit =
present(flag_ctalgo)
79 if( is_implicit )
then
80 update_tangent = (flag_ctalgo ==
'SLagrange')
82 update_tangent = .true.
87 slave = contact%slave(nslave)
88 coord(:) = currpos(3*slave-2:3*slave)
90 sid0 = contact%states(nslave)%surface
91 opos = contact%states(nslave)%lpos(1:2)
92 etype = contact%master(sid0)%etype
95 iss = contact%master(sid0)%nodes(j)
96 elem0(1:3,j)=currpos(3*iss-2:3*iss)-currdisp(3*iss-2:3*iss)
99 contact%states(nslave), isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
100 contact%states(nslave)%lpos(1:2), contact%cparam%CLR_SAME_ELEM, smoothing=contact%smoothing )
101 if( .not. isin )
then
105 cstate_free = contact%states(nslave)
107 do i=1, contact%master(sid0)%n_neighbor
108 sid = contact%master(sid0)%neighbor(i)
109 cstate_try = cstate_free
111 cstate_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
112 localclr=contact%cparam%CLEARANCE, smoothing=contact%smoothing )
113 if( .not. isin ) cycle
114 if( id_best /= 0 )
then
115 if( dabs(cstate_try%distance) > dabs(cstate_best%distance) ) cycle
116 if( dabs(cstate_try%distance) == dabs(cstate_best%distance) .and. sid > id_best ) cycle
119 cstate_best = cstate_try
121 isin = ( id_best /= 0 )
124 contact%states(nslave) = cstate_best
125 contact%states(nslave)%surface = sid
129 if( .not. isin )
then
131 write(*,*)
'Warning: contact moved beyond neighbor elements'
133 cstate_free = contact%states(nslave)
135 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
136 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
138 allocate(indexcand(ncand))
139 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
143 if( sid==sid0 ) cycle
144 if(
associated(contact%master(sid0)%neighbor) )
then
145 if( any(sid==contact%master(sid0)%neighbor(1:contact%master(sid0)%n_neighbor)) ) cycle
147 cstate_try = cstate_free
149 cstate_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_FREE, &
150 localclr=contact%cparam%CLEARANCE, smoothing=contact%smoothing )
151 if( .not. isin ) cycle
152 if( id_best /= 0 )
then
153 if( dabs(cstate_try%distance) > dabs(cstate_best%distance) ) cycle
154 if( dabs(cstate_try%distance) == dabs(cstate_best%distance) .and. sid > id_best ) cycle
157 cstate_best = cstate_try
159 deallocate(indexcand)
160 isin = ( id_best /= 0 )
163 contact%states(nslave) = cstate_best
164 contact%states(nslave)%surface = sid
170 if( contact%states(nslave)%surface==sid0 )
then
171 if(any(dabs(contact%states(nslave)%lpos(1:2)-opos(:)) >= contact%cparam%CLR_DIFFLPOS))
then
173 infoctchange%contact2difflpos = infoctchange%contact2difflpos + 1
178 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3)')
"Node",nodeid(slave),
" move to contact with", &
179 elemid(contact%master(sid)%eid),
" with distance ", &
180 contact%states(nslave)%distance,
" at ",contact%states(nslave)%lpos(1:2)
184 infoctchange%contact2neighbor = infoctchange%contact2neighbor + 1
186 if( update_tangent .and. contact%fcoeff /= 0.d0 )
then
188 etype = contact%master(contact%states(nslave)%surface)%etype
189 nn =
size(contact%master(contact%states(nslave)%surface)%nodes)
191 iss = contact%master(contact%states(nslave)%surface)%nodes(j)
192 elem(1:3,j)=currpos(3*iss-2:3*iss)
194 call update_tangentforce(etype,nn,elem0,elem,contact%states(nslave))
196 iss =
isinsideelement( etype, contact%states(nslave)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
197 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
198 call cal_node_normal( contact%states(nslave)%surface, iss, contact%master, currpos, &
199 contact%states(nslave)%lpos(1:2), contact%states(nslave)%direction(:) )
200 else if( .not. isin )
then
203 write(*,
'(A,i10,A)')
"Node",nodeid(slave),
" move out of contact"
207 contact%states(nslave)%multiplier(:) = 0.d0
220 nodeID, elemID, is_init, active, hecMESH, flag_ctAlgo, ndforce )
221 type(
tcontact ),
intent(inout) :: contact
223 real(kind=kreal),
intent(in) :: currpos(:)
224 real(kind=kreal),
intent(in) :: currdisp(:)
225 integer(kind=kint),
intent(in) :: nodeID(:)
226 integer(kind=kint),
intent(in) :: elemID(:)
227 logical,
intent(in) :: is_init
228 logical,
intent(out) :: active
229 type( hecmwst_local_mesh ),
intent(in),
optional :: hecMESH
230 character(len=9),
intent(in),
optional :: flag_ctAlgo
231 real(kind=kreal),
intent(in),
optional :: ndforce(:)
233 real(kind=kreal) :: distclr
234 integer(kind=kint) :: slave, id, etype
235 integer(kind=kint) :: i, iSS, nactive, icat_prev, icat_curr, surf_key
236 real(kind=kreal) :: coord(3)
237 real(kind=kreal) :: nlforce
239 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
240 integer(kind=kint),
allocatable :: contact_prio(:), contact_prio_min(:)
241 real(kind=kreal) :: effective_near_dist, distclr_use
243 integer,
pointer :: indexCand(:)
244 integer :: idm,bktID,nCand,id_best
246 logical :: is_implicit
248 is_implicit =
present(flag_ctalgo)
251 distclr = contact%cparam%DISTCLR_INIT
253 distclr = contact%cparam%DISTCLR_FREE
256 do i= 1,
size(contact%slave)
265 allocate(contact_surf(
size(nodeid)))
266 allocate(contact_prio(
size(nodeid)))
267 allocate(states_prev(
size(contact%slave)))
268 contact_surf(:) = huge(0)
269 contact_prio(:) = huge(0)
270 do i = 1,
size(contact%slave)
271 states_prev(i) = contact%states(i)%state
274 if( contact%smoothing ==
kcsnagata )
then
279 call update_surface_box_info( contact%master, currpos )
280 call update_surface_bucket_info( contact%master, contact%master_bktDB )
284 effective_near_dist = contact%cparam%NEAR_DIST
285 if (contact%damp_gact > 0.0d0)
then
286 effective_near_dist = max(effective_near_dist, contact%damp_gact)
298 do i= 1,
size(contact%slave)
299 if(contact%if_type /= 0)
call set_shrink_factor(contact%ctime, contact%states(i), contact%if_etime, contact%if_type)
300 slave = contact%slave(i)
302 id = contact%states(i)%surface
303 nlforce = contact%states(i)%multiplier(1)
308 if (.not.is_init) cycle
311 if( nlforce < contact%cparam%TENSILE_FORCE )
then
312 contact%states(i)%multiplier(:) = 0.d0
313 if( effective_near_dist > 0.0d0 )
then
317 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
318 contact_prio(contact%slave(i)) = 1
321 write(*,
'(A,i10,A,i10,A,e12.3)')
"Node",nodeid(slave), &
322 " released to near contact with element", &
323 elemid(contact%master(id)%eid),
" with tensile force ", nlforce
330 write(*,
'(A,i10,A,i10,A,e12.3)')
"Node",nodeid(slave),
" free from contact with element", &
331 elemid(contact%master(id)%eid),
" with tensile force ", nlforce
338 contact_surf(contact%slave(i)) = -elemid(contact%master(id)%eid)
339 contact_prio(contact%slave(i)) = 0
341 if( is_implicit )
then
343 flag_ctalgo=flag_ctalgo )
348 id = contact%states(i)%surface
349 contact_surf(contact%slave(i)) = -elemid(contact%master(id)%eid)
350 contact_prio(contact%slave(i)) = 0
354 else if( contact%states(i)%state==
contactnear )
then
356 coord(:) = currpos(3*slave-2:3*slave)
357 id = contact%states(i)%surface
358 if (effective_near_dist > 0.0d0)
then
359 distclr_use = max(distclr, effective_near_dist / contact%master(id)%reflen)
361 distclr_use = distclr
364 contact%states(i), isin, distclr_use, contact%cparam%PENCLR_FREE, &
365 contact%states(i)%lpos(1:2), contact%cparam%CLR_SAME_ELEM, smoothing=contact%smoothing )
367 if (contact%states(i)%distance <= distclr * contact%master(id)%reflen)
then
370 contact%states(i)%multiplier(:) = 0.d0
373 write(*,
'(A,i10,A,i10,A,i6)')
"Node",nodeid(slave),
" upgraded NEAR->STICK on element", &
374 elemid(contact%master(id)%eid),
" rank=",hecmw_comm_get_rank()
377 else if (contact%states(i)%distance > effective_near_dist)
then
380 contact%states(i)%multiplier(:) = 0.d0
384 etype = contact%master(id)%etype
385 iss =
isinsideelement( etype, contact%states(i)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
386 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
388 contact%states(i)%lpos(1:2), contact%states(i)%direction(:) )
389 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
390 contact_prio(contact%slave(i)) = 1
395 contact%states(i)%multiplier(:) = 0.d0
398 else if( contact%states(i)%state==
contactfree )
then
399 if( contact%algtype ==
contacttied .and. .not. is_init ) cycle
400 coord(:) = currpos(3*slave-2:3*slave)
403 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
404 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
405 if (ncand == 0) cycle
406 allocate(indexcand(ncand))
407 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
414 cstate_free = contact%states(i)
418 if (effective_near_dist > 0.0d0)
then
419 distclr_use = max(distclr, effective_near_dist / contact%master(id)%reflen)
421 distclr_use = distclr
423 cstate_try = cstate_free
425 cstate_try, isin, distclr_use, contact%cparam%PENCLR_FREE, &
426 localclr=contact%cparam%CLEARANCE, smoothing=contact%smoothing )
427 if( .not. isin ) cycle
428 if( id_best /= 0 )
then
429 if( dabs(cstate_try%distance) > dabs(cstate_best%distance) ) cycle
430 if( dabs(cstate_try%distance) == dabs(cstate_best%distance) .and. id > id_best ) cycle
433 cstate_best = cstate_try
435 deallocate(indexcand)
436 if( id_best == 0 ) cycle
439 contact%states(i) = cstate_best
441 if (effective_near_dist > 0.0d0 .and. &
442 contact%states(i)%distance > distclr * contact%master(id)%reflen)
then
445 contact%states(i)%surface = id
446 contact%states(i)%multiplier(:) = 0.d0
447 etype = contact%master(id)%etype
448 iss =
isinsideelement( etype, contact%states(i)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
449 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
450 call cal_node_normal( id, iss, contact%master, currpos, contact%states(i)%lpos(1:2), &
451 contact%states(i)%direction(:) )
452 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
453 contact_prio(contact%slave(i)) = 1
457 write(*,
'(A,i10,A,i10,A,f7.3,A,i6)')
"Node",nodeid(slave),
" near element", &
458 elemid(contact%master(id)%eid), &
459 " with distance ", contact%states(i)%distance,
" rank=",hecmw_comm_get_rank()
461 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3,A,3f7.3,A,i6)')
"Node",nodeid(slave),
" contact with element", &
462 elemid(contact%master(id)%eid), &
463 " with distance ", contact%states(i)%distance,
" at ",contact%states(i)%lpos(1:2), &
464 " along direction ", contact%states(i)%direction,
" rank=",hecmw_comm_get_rank()
472 if( contact%algtype ==
contacttied .and. .not. is_init )
then
473 deallocate(contact_surf)
474 deallocate(contact_prio)
475 deallocate(states_prev)
481 allocate(contact_prio_min(
size(nodeid)))
482 contact_prio_min(:) = contact_prio(:)
483 call hecmw_contact_comm_allreduce_i(contact%comm, contact_prio_min, hecmw_min)
484 where( contact_prio(:) > contact_prio_min(:) ) contact_surf(:) = huge(0)
485 call hecmw_contact_comm_allreduce_i(contact%comm, contact_surf, hecmw_min)
487 do i = 1,
size(contact%slave)
489 id = contact%states(i)%surface
490 surf_key = elemid(contact%master(id)%eid)
491 if (contact_prio(contact%slave(i)) == 0) surf_key = -surf_key
492 if (contact_prio(contact%slave(i)) /= contact_prio_min(contact%slave(i)) .or. &
493 & contact_surf(contact%slave(i)) /= surf_key)
then
496 &
write(*,
'(A,i10,A,i10,A,i6,A,i6,A)')
"Node",nodeid(contact%slave(i)), &
497 &
" contact with element",elemid(contact%master(id)%eid), &
498 &
" in rank",hecmw_comm_get_rank(),
" freed due to duplication"
500 nactive = nactive + 1
505 if (icat_prev /= icat_curr) infoctchange%n_statechange(icat_prev,icat_curr) = &
506 infoctchange%n_statechange(icat_prev,icat_curr) + 1
508 active = (nactive > 0)
509 deallocate(contact_surf)
510 deallocate(contact_prio, contact_prio_min)
511 deallocate(states_prev)
518 nodeID, elemID, is_init, active, B )
519 type(
tcontact ),
intent(inout) :: embed
521 real(kind=kreal),
intent(in) :: currpos(:)
522 integer(kind=kint),
intent(in) :: nodeID(:)
523 integer(kind=kint),
intent(in) :: elemID(:)
524 logical,
intent(in) :: is_init
525 logical,
intent(out) :: active
526 real(kind=kreal),
optional,
target :: b(:)
528 real(kind=kreal) :: distclr
529 integer(kind=kint) :: slave, id, etype
530 integer(kind=kint) :: nn, i, j, iSS, nactive, icat_prev, icat_curr
531 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node )
533 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
535 integer,
pointer :: indexCand(:)
536 integer :: idm,bktID,nCand,id_best
538 logical :: is_present_B
539 real(kind=kreal),
pointer :: bp(:)
542 distclr = embed%cparam%DISTCLR_INIT
544 distclr = embed%cparam%DISTCLR_FREE
546 do i= 1,
size(embed%slave)
555 allocate(contact_surf(
size(nodeid)))
556 allocate(states_prev(
size(embed%slave)))
557 contact_surf(:) = huge(0)
558 do i = 1,
size(embed%slave)
559 states_prev(i) = embed%states(i)%state
562 call update_surface_box_info( embed%master, currpos )
563 call update_surface_bucket_info( embed%master, embed%master_bktDB )
566 is_present_b =
present(b)
567 if( is_present_b ) bp => b
577 do i= 1,
size(embed%slave)
578 slave = embed%slave(i)
580 coord(:) = currpos(3*slave-2:3*slave)
583 bktid = bucketdb_getbucketid(embed%master_bktDB, coord)
584 ncand = bucketdb_getnumcand(embed%master_bktDB, bktid)
585 if (ncand == 0) cycle
586 allocate(indexcand(ncand))
587 call bucketdb_getcand(embed%master_bktDB, bktid, ncand, indexcand)
592 cstate_free = embed%states(i)
595 etype = embed%master(id)%etype
596 if( mod(etype,10) == 2 ) etype = etype - 1
599 iss = embed%master(id)%nodes(j)
600 elem(1:3,j)=currpos(3*iss-2:3*iss)
602 cstate_try = cstate_free
604 isin,distclr,localclr=embed%cparam%CLEARANCE )
605 if( .not. isin ) cycle
606 if( id_best /= 0 )
then
607 if( cstate_try%distance > cstate_best%distance ) cycle
608 if( cstate_try%distance == cstate_best%distance .and. id > id_best ) cycle
611 cstate_best = cstate_try
613 deallocate(indexcand)
614 if( id_best == 0 ) cycle
617 embed%states(i) = cstate_best
618 embed%states(i)%surface = id
619 embed%states(i)%multiplier(:) = 0.d0
620 contact_surf(embed%slave(i)) = elemid(embed%master(id)%eid)
623 write(*,
'(A,i10,A,i10,A,3f7.3,A,i6)')
"Node",nodeid(slave),
" embeded to element", &
624 elemid(embed%master(id)%eid),
" at ",embed%states(i)%lpos(:),
" rank=",hecmw_comm_get_rank()
631 call hecmw_contact_comm_allreduce_i(embed%comm, contact_surf, hecmw_min)
633 do i = 1,
size(embed%slave)
635 id = embed%states(i)%surface
636 if (contact_surf(embed%slave(i)) /= elemid(embed%master(id)%eid))
then
638 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,i6,A,i6,A)')
"Node",nodeid(embed%slave(i)),
" contact with element", &
639 & elemid(embed%master(id)%eid),
" in rank",hecmw_comm_get_rank(),
" freed due to duplication"
641 nactive = nactive + 1
646 if (icat_prev /= icat_curr) infoctchange%n_statechange(icat_prev,icat_curr) = &
647 infoctchange%n_statechange(icat_prev,icat_curr) + 1
649 active = (nactive > 0)
650 deallocate(contact_surf)
651 deallocate(states_prev)
656 integer(kind=kint),
intent(in) :: cstep
657 type( hecmwst_local_mesh ),
intent(in) :: hecMESH
661 integer(kind=kint) :: i, j, grpid, slave
662 integer(kind=kint) :: k, id, iSS, icat
663 integer(kind=kint) :: ig0, ig, iS0, iE0
664 integer(kind=kint),
allocatable :: states(:)
666 allocate(states(hecmesh%n_node))
670 do ig0= 1, fstrsolid%BOUNDARY_ngrp_tot
671 grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
673 ig= fstrsolid%BOUNDARY_ngrp_ID(ig0)
674 is0= hecmesh%node_group%grp_index(ig-1) + 1
675 ie0= hecmesh%node_group%grp_index(ig )
677 iss = hecmesh%node_group%grp_item(k)
682 do i=1,fstrsolid%n_contacts
683 if( fstrsolid%contacts(i)%algtype /=
contacttied ) cycle
684 grpid = fstrsolid%contacts(i)%group
687 do j=1,
size(fstrsolid%contacts(i)%slave)
689 slave = fstrsolid%contacts(i)%slave(j)
691 states(slave) = fstrsolid%contacts(i)%states(j)%state
692 id = fstrsolid%contacts(i)%states(j)%surface
693 do k=1,
size( fstrsolid%contacts(i)%master(id)%nodes )
694 iss = fstrsolid%contacts(i)%master(id)%nodes(k)
695 states(iss) = fstrsolid%contacts(i)%states(j)%state
699 fstrsolid%contacts(i)%states(j)%state =
contactfree
700 infoctchange%n_statechange(
kcatfree,icat) = infoctchange%n_statechange(
kcatfree,icat) - 1
701 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i6,A,i6,A)')
"Node",hecmesh%global_node_ID(slave), &
702 " in rank",hecmw_comm_get_rank(),
" freed due to duplication"
714 type(
tcontact ),
intent(inout) :: contact
716 real(kind=kreal),
intent(in) :: currpos(:)
717 logical,
intent(in) :: is_init
718 logical,
intent(out) :: active
720 real(kind=kreal) :: distclr
721 integer(kind=kint) :: slave, id
722 integer(kind=kint) :: nnode_s, i, j
723 real(kind=kreal) :: coord(3), ncoord(2)
724 real(kind=kreal) :: surf_node_pos(3,4), sfunc(4)
727 integer,
pointer :: indexCand(:)
728 integer :: idm,bktID,nCand,id_best
731 integer(kind=kint) :: maplist(MAX_N_INTP), master_idxs(MAX_N_INTP)
732 integer(kind=kint) :: unique_count
733 integer(kind=kint) :: known_masters(MAX_N_INTP), n_known
736 logical :: counted_f2c, counted_nbr, counted_byd
738 distclr = contact%cparam%DISTCLR_INIT
740 distclr = contact%cparam%DISTCLR_FREE
742 call update_surface_box_info( contact%master, currpos )
743 call update_surface_bucket_info( contact%master, contact%master_bktDB )
757 do i = 1,
size(contact%slave_surf)
758 surf_node_pos(:,:) = 0.d0
759 nnode_s =
size(contact%slave_surf(i)%nodes)
763 call get_unique_map(contact%slave_surf(i), maplist, master_idxs, unique_count)
764 n_known = unique_count
765 if( n_known > 0 ) known_masters(1:n_known) = master_idxs(1:n_known)
766 counted_f2c = .false.
767 counted_nbr = .false.
768 counted_byd = .false.
772 do j = 1, contact%slave_surf(i)%n_intp
773 if (contact%slave_surf(i)%states(j)%state ==
contactfree)
then
779 slave = contact%slave_surf(i)%nodes(j)
780 surf_node_pos(:,j) = currpos(3*slave-2:3*slave)
784 contact%slave_surf(i)%state_prev = contact%slave_surf(i)%state
786 do j = 1, contact%slave_surf(i)%n_intp
792 call getintpoint4ss( contact%slave_surf(i)%etype, j, ncoord, contact%slave_surf(i)%n_intp, sfunc )
793 coord(:) = matmul( surf_node_pos(:,1:nnode_s), sfunc(1:nnode_s) )
796 if( contact%slave_surf(i)%states(j)%state==
contactstick .or. contact%slave_surf(i)%states(j)%state==
contactslip )
then
798 id = contact%slave_surf(i)%states(j)%surface
804 contact%slave_surf(i), ncoord, contact, currpos, infoctchange, counted_nbr, counted_byd )
809 else if( contact%slave_surf(i)%states(j)%state==
candidate_intp )
then
813 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
814 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
815 if (ncand == 0) cycle
816 allocate(indexcand(ncand))
817 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
823 state_free = contact%slave_surf(i)%states(j)
830 state_try = state_free
832 ncoord, currpos, state_try, isin, distclr=distclr, &
833 penclr=contact%cparam%PENCLR_FREE, localclr=contact%cparam%CLEARANCE )
834 if( .not. isin ) cycle
835 if( id_best /= 0 )
then
836 if( dabs(state_try%distance) > dabs(state_best%distance) ) cycle
837 if( dabs(state_try%distance) == dabs(state_best%distance) .and. id > id_best ) cycle
840 state_best = state_try
842 if( id_best /= 0 )
then
844 contact%slave_surf(i)%states(j) = state_best
845 contact%slave_surf(i)%states(j)%surface = id
846 contact%slave_surf(i)%states(j)%multiplier(:) = 0.d0
854 if( (contact%sparsity_expansion ==
sparsity_none .or. .not. is_known) .and. .not. counted_f2c )
then
856 infoctchange%free2contact_new = infoctchange%free2contact_new + 1
860 deallocate(indexcand)
869 type(
tcontact ),
intent(inout) :: contact
872 real(kind=kreal),
intent(in) :: ncoord(2)
874 logical,
intent(inout) :: counted_nbr
875 logical,
intent(inout) :: counted_byd
876 real(kind=kreal),
intent(in) :: currpos(:)
877 real(kind=kreal),
intent(inout) :: coord(:)
879 integer(kind=kint) :: sid0, sid
880 integer(kind=kint) :: i
881 logical :: isin, found_in_neighbor
882 real(kind=kreal) :: opos(2)
883 integer(kind=kint) :: bktid, ncand, idm, id_best
884 integer(kind=kint),
allocatable :: indexcand(:)
888 found_in_neighbor = .false.
892 opos = state%lpos(1:2)
895 state, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
896 state%lpos(1:2), contact%cparam%CLR_SAME_ELEM )
897 if( .not. isin )
then
902 do i=1, contact%master(sid0)%n_neighbor
903 sid = contact%master(sid0)%neighbor(i)
904 state_try = state_free
906 state_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
907 localclr=contact%cparam%CLEARANCE )
908 if( .not. isin ) cycle
909 if( id_best /= 0 )
then
910 if( dabs(state_try%distance) > dabs(state_best%distance) ) cycle
911 if( dabs(state_try%distance) == dabs(state_best%distance) .and. sid > id_best ) cycle
914 state_best = state_try
916 isin = ( id_best /= 0 )
921 found_in_neighbor = .true.
925 if( .not. isin )
then
928 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
929 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
931 allocate(indexcand(ncand))
932 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
936 if( sid==sid0 ) cycle
937 if(
associated(contact%master(sid0)%neighbor) )
then
938 if( any(sid==contact%master(sid0)%neighbor(1:contact%master(sid0)%n_neighbor)) ) cycle
940 state_try = state_free
942 state_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_FREE, &
943 localclr=contact%cparam%CLEARANCE )
944 if( .not. isin ) cycle
945 if( id_best /= 0 )
then
946 if( dabs(state_try%distance) > dabs(state_best%distance) ) cycle
947 if( dabs(state_try%distance) == dabs(state_best%distance) .and. sid > id_best ) cycle
950 state_best = state_try
952 deallocate(indexcand)
953 isin = ( id_best /= 0 )
963 if( state%distance > contact%cparam%DISTCLR_C2F * contact%master(state%surface)%reflen )
then
965 state%multiplier(:) = 0.d0
970 if( state%surface /= sid0 )
then
971 if( found_in_neighbor )
then
973 if( contact%sparsity_expansion ==
sparsity_none .and. .not. counted_nbr )
then
975 infoctchange%contact2neighbor = infoctchange%contact2neighbor + 1
978 else if( .not. counted_byd )
then
980 infoctchange%contact2beyond = infoctchange%contact2beyond + 1
985 else if( .not. isin )
then
987 state%multiplier(:) = 0.d0
This module encapsulate the basic functions of all elements provide by this software.
integer(kind=kind(2)) function getnumberofnodes(etype)
Obtain number of nodes of the element.
integer function isinsideelement(fetype, localcoord, clearance)
if a point is inside a surface element -1: No; 0: Yes; >0: Node's (vertex) number
subroutine getintpoint4ss(fetype, np, pos, n_intp, shapefunc)
This module defines common data and basic structures for analysis.
logical function fstr_iscontactactive(fstrSOLID, nbc, cstep)
logical function fstr_isboundaryactive(fstrSOLID, nbc, cstep)