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(:) == 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
130 write(*,*)
'Warning: contact moved beyond neighbor elements'
131 cstate_free = contact%states(nslave)
133 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
134 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
136 allocate(indexcand(ncand))
137 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
141 if( sid==sid0 ) cycle
142 if(
associated(contact%master(sid0)%neighbor) )
then
143 if( any(sid==contact%master(sid0)%neighbor(:)) ) cycle
145 cstate_try = cstate_free
147 cstate_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_FREE, &
148 localclr=contact%cparam%CLEARANCE, smoothing=contact%smoothing )
149 if( .not. isin ) cycle
150 if( id_best /= 0 )
then
151 if( dabs(cstate_try%distance) > dabs(cstate_best%distance) ) cycle
152 if( dabs(cstate_try%distance) == dabs(cstate_best%distance) .and. sid > id_best ) cycle
155 cstate_best = cstate_try
157 deallocate(indexcand)
158 isin = ( id_best /= 0 )
161 contact%states(nslave) = cstate_best
162 contact%states(nslave)%surface = sid
168 if( contact%states(nslave)%surface==sid0 )
then
169 if(any(dabs(contact%states(nslave)%lpos(1:2)-opos(:)) >= contact%cparam%CLR_DIFFLPOS))
then
171 infoctchange%contact2difflpos = infoctchange%contact2difflpos + 1
174 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3)')
"Node",nodeid(slave),
" move to contact with", &
175 elemid(contact%master(sid)%eid),
" with distance ", &
176 contact%states(nslave)%distance,
" at ",contact%states(nslave)%lpos(1:2)
178 infoctchange%contact2neighbor = infoctchange%contact2neighbor + 1
180 if( update_tangent .and. contact%fcoeff /= 0.d0 )
then
182 etype = contact%master(contact%states(nslave)%surface)%etype
183 nn =
size(contact%master(contact%states(nslave)%surface)%nodes)
185 iss = contact%master(contact%states(nslave)%surface)%nodes(j)
186 elem(1:3,j)=currpos(3*iss-2:3*iss)
188 call update_tangentforce(etype,nn,elem0,elem,contact%states(nslave))
190 iss =
isinsideelement( etype, contact%states(nslave)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
191 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
192 call cal_node_normal( contact%states(nslave)%surface, iss, contact%master, currpos, &
193 contact%states(nslave)%lpos(1:2), contact%states(nslave)%direction(:) )
194 else if( .not. isin )
then
195 if (
contact_log_level >= 1)
write(*,
'(A,i10,A)')
"Node",nodeid(slave),
" move out of contact"
197 contact%states(nslave)%multiplier(:) = 0.d0
210 nodeID, elemID, is_init, active, hecMESH, flag_ctAlgo, ndforce )
211 type(
tcontact ),
intent(inout) :: contact
213 real(kind=kreal),
intent(in) :: currpos(:)
214 real(kind=kreal),
intent(in) :: currdisp(:)
215 integer(kind=kint),
intent(in) :: nodeID(:)
216 integer(kind=kint),
intent(in) :: elemID(:)
217 logical,
intent(in) :: is_init
218 logical,
intent(out) :: active
219 type( hecmwst_local_mesh ),
intent(in),
optional :: hecMESH
220 character(len=9),
intent(in),
optional :: flag_ctAlgo
221 real(kind=kreal),
intent(in),
optional :: ndforce(:)
223 real(kind=kreal) :: distclr
224 integer(kind=kint) :: slave, id, etype
225 integer(kind=kint) :: i, iSS, nactive, icat_prev, icat_curr
226 real(kind=kreal) :: coord(3)
227 real(kind=kreal) :: nlforce
229 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
230 real(kind=kreal) :: effective_near_dist, distclr_use
232 integer,
pointer :: indexCand(:)
233 integer :: idm,bktID,nCand,id_best
235 logical :: is_implicit
237 is_implicit =
present(flag_ctalgo)
240 distclr = contact%cparam%DISTCLR_INIT
242 distclr = contact%cparam%DISTCLR_FREE
245 do i= 1,
size(contact%slave)
254 allocate(contact_surf(
size(nodeid)))
255 allocate(states_prev(
size(contact%slave)))
256 contact_surf(:) = huge(0)
257 do i = 1,
size(contact%slave)
258 states_prev(i) = contact%states(i)%state
261 if( contact%smoothing ==
kcsnagata )
then
266 call update_surface_box_info( contact%master, currpos )
267 call update_surface_bucket_info( contact%master, contact%master_bktDB )
271 effective_near_dist = contact%cparam%NEAR_DIST
272 if (contact%damp_gact > 0.0d0)
then
273 effective_near_dist = max(effective_near_dist, contact%damp_gact)
284 do i= 1,
size(contact%slave)
285 if(contact%if_type /= 0)
call set_shrink_factor(contact%ctime, contact%states(i), contact%if_etime, contact%if_type)
286 slave = contact%slave(i)
288 id = contact%states(i)%surface
289 nlforce = contact%states(i)%multiplier(1)
294 if (.not.is_init) cycle
297 if( nlforce < contact%cparam%TENSILE_FORCE )
then
298 contact%states(i)%multiplier(:) = 0.d0
299 if( effective_near_dist > 0.0d0 )
then
303 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
304 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,e12.3)')
"Node",nodeid(slave), &
305 " released to near contact with element", &
306 elemid(contact%master(id)%eid),
" with tensile force ", nlforce
309 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,e12.3)')
"Node",nodeid(slave),
" free from contact with element", &
310 elemid(contact%master(id)%eid),
" with tensile force ", nlforce
315 contact_surf(contact%slave(i)) = -elemid(contact%master(id)%eid)
317 if( is_implicit )
then
319 flag_ctalgo=flag_ctalgo )
324 id = contact%states(i)%surface
325 contact_surf(contact%slave(i)) = -elemid(contact%master(id)%eid)
329 else if( contact%states(i)%state==
contactnear )
then
331 coord(:) = currpos(3*slave-2:3*slave)
332 id = contact%states(i)%surface
333 if (effective_near_dist > 0.0d0)
then
334 distclr_use = max(distclr, effective_near_dist / contact%master(id)%reflen)
336 distclr_use = distclr
339 contact%states(i), isin, distclr_use, contact%cparam%PENCLR_FREE, &
340 contact%states(i)%lpos(1:2), contact%cparam%CLR_SAME_ELEM, smoothing=contact%smoothing )
342 if (contact%states(i)%distance <= distclr * contact%master(id)%reflen)
then
345 contact%states(i)%multiplier(:) = 0.d0
346 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,i6)')
"Node",nodeid(slave),
" upgraded NEAR->STICK on element", &
347 elemid(contact%master(id)%eid),
" rank=",hecmw_comm_get_rank()
348 else if (contact%states(i)%distance > effective_near_dist)
then
351 contact%states(i)%multiplier(:) = 0.d0
355 etype = contact%master(id)%etype
356 iss =
isinsideelement( etype, contact%states(i)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
357 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
359 contact%states(i)%lpos(1:2), contact%states(i)%direction(:) )
360 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
365 contact%states(i)%multiplier(:) = 0.d0
368 else if( contact%states(i)%state==
contactfree )
then
369 if( contact%algtype ==
contacttied .and. .not. is_init ) cycle
370 coord(:) = currpos(3*slave-2:3*slave)
373 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
374 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
375 if (ncand == 0) cycle
376 allocate(indexcand(ncand))
377 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
384 cstate_free = contact%states(i)
388 if (effective_near_dist > 0.0d0)
then
389 distclr_use = max(distclr, effective_near_dist / contact%master(id)%reflen)
391 distclr_use = distclr
393 cstate_try = cstate_free
395 cstate_try, isin, distclr_use, contact%cparam%PENCLR_FREE, &
396 localclr=contact%cparam%CLEARANCE, smoothing=contact%smoothing )
397 if( .not. isin ) cycle
398 if( id_best /= 0 )
then
399 if( dabs(cstate_try%distance) > dabs(cstate_best%distance) ) cycle
400 if( dabs(cstate_try%distance) == dabs(cstate_best%distance) .and. id > id_best ) cycle
403 cstate_best = cstate_try
405 deallocate(indexcand)
406 if( id_best == 0 ) cycle
409 contact%states(i) = cstate_best
411 if (effective_near_dist > 0.0d0 .and. &
412 contact%states(i)%distance > distclr * contact%master(id)%reflen)
then
415 contact%states(i)%surface = id
416 contact%states(i)%multiplier(:) = 0.d0
417 etype = contact%master(id)%etype
418 iss =
isinsideelement( etype, contact%states(i)%lpos(1:2), contact%cparam%CLR_CAL_NORM )
419 if( iss>0 .and. contact%smoothing /=
kcsnagata ) &
420 call cal_node_normal( id, iss, contact%master, currpos, contact%states(i)%lpos(1:2), &
421 contact%states(i)%direction(:) )
422 contact_surf(contact%slave(i)) = elemid(contact%master(id)%eid)
425 write(*,
'(A,i10,A,i10,A,f7.3,A,i6)')
"Node",nodeid(slave),
" near element", &
426 elemid(contact%master(id)%eid), &
427 " with distance ", contact%states(i)%distance,
" rank=",hecmw_comm_get_rank()
429 write(*,
'(A,i10,A,i10,A,f7.3,A,2f7.3,A,3f7.3,A,i6)')
"Node",nodeid(slave),
" contact with element", &
430 elemid(contact%master(id)%eid), &
431 " with distance ", contact%states(i)%distance,
" at ",contact%states(i)%lpos(1:2), &
432 " along direction ", contact%states(i)%direction,
" rank=",hecmw_comm_get_rank()
439 if( contact%algtype ==
contacttied .and. .not. is_init )
then
440 deallocate(contact_surf)
441 deallocate(states_prev)
445 call hecmw_contact_comm_allreduce_i(contact%comm, contact_surf, hecmw_min)
447 do i = 1,
size(contact%slave)
449 id = contact%states(i)%surface
450 if (abs(contact_surf(contact%slave(i))) /= elemid(contact%master(id)%eid))
then
453 &
write(*,
'(A,i10,A,i10,A,i6,A,i6,A)')
"Node",nodeid(contact%slave(i)), &
454 &
" contact with element",elemid(contact%master(id)%eid), &
455 &
" in rank",hecmw_comm_get_rank(),
" freed due to duplication"
457 nactive = nactive + 1
462 if (icat_prev /= icat_curr) infoctchange%n_statechange(icat_prev,icat_curr) = &
463 infoctchange%n_statechange(icat_prev,icat_curr) + 1
465 active = (nactive > 0)
466 deallocate(contact_surf)
467 deallocate(states_prev)
473 subroutine scan_embed_state( flag_ctAlgo, embed, currpos, currdisp, ndforce, infoCTChange, &
474 nodeID, elemID, is_init, active, B )
475 character(len=9),
intent(in) :: flag_ctAlgo
476 type(
tcontact ),
intent(inout) :: embed
478 real(kind=kreal),
intent(in) :: currpos(:)
479 real(kind=kreal),
intent(in) :: currdisp(:)
480 real(kind=kreal),
intent(in) :: ndforce(:)
481 integer(kind=kint),
intent(in) :: nodeID(:)
482 integer(kind=kint),
intent(in) :: elemID(:)
483 logical,
intent(in) :: is_init
484 logical,
intent(out) :: active
485 real(kind=kreal),
optional,
target :: b(:)
487 real(kind=kreal) :: distclr
488 integer(kind=kint) :: slave, id, etype
489 integer(kind=kint) :: nn, i, j, iSS, nactive, icat_prev, icat_curr
490 real(kind=kreal) :: coord(3), elem(3, l_max_elem_node )
492 integer(kind=kint),
allocatable :: contact_surf(:), states_prev(:)
494 integer,
pointer :: indexCand(:)
495 integer :: idm,bktID,nCand,id_best
497 logical :: is_present_B
498 real(kind=kreal),
pointer :: bp(:)
501 distclr = embed%cparam%DISTCLR_INIT
503 distclr = embed%cparam%DISTCLR_FREE
505 do i= 1,
size(embed%slave)
514 allocate(contact_surf(
size(nodeid)))
515 allocate(states_prev(
size(embed%slave)))
516 contact_surf(:) = huge(0)
517 do i = 1,
size(embed%slave)
518 states_prev(i) = embed%states(i)%state
521 call update_surface_box_info( embed%master, currpos )
522 call update_surface_bucket_info( embed%master, embed%master_bktDB )
525 is_present_b =
present(b)
526 if( is_present_b ) bp => b
536 do i= 1,
size(embed%slave)
537 slave = embed%slave(i)
539 coord(:) = currpos(3*slave-2:3*slave)
542 bktid = bucketdb_getbucketid(embed%master_bktDB, coord)
543 ncand = bucketdb_getnumcand(embed%master_bktDB, bktid)
544 if (ncand == 0) cycle
545 allocate(indexcand(ncand))
546 call bucketdb_getcand(embed%master_bktDB, bktid, ncand, indexcand)
551 cstate_free = embed%states(i)
554 etype = embed%master(id)%etype
555 if( mod(etype,10) == 2 ) etype = etype - 1
558 iss = embed%master(id)%nodes(j)
559 elem(1:3,j)=currpos(3*iss-2:3*iss)
561 cstate_try = cstate_free
563 isin,distclr,localclr=embed%cparam%CLEARANCE )
564 if( .not. isin ) cycle
565 if( id_best /= 0 )
then
566 if( cstate_try%distance > cstate_best%distance ) cycle
567 if( cstate_try%distance == cstate_best%distance .and. id > id_best ) cycle
570 cstate_best = cstate_try
572 deallocate(indexcand)
573 if( id_best == 0 ) cycle
576 embed%states(i) = cstate_best
577 embed%states(i)%surface = id
578 embed%states(i)%multiplier(:) = 0.d0
579 contact_surf(embed%slave(i)) = elemid(embed%master(id)%eid)
580 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,3f7.3,A,i6)')
"Node",nodeid(slave),
" embeded to element", &
581 elemid(embed%master(id)%eid),
" at ",embed%states(i)%lpos(:),
" rank=",hecmw_comm_get_rank()
586 call hecmw_contact_comm_allreduce_i(embed%comm, contact_surf, hecmw_min)
588 do i = 1,
size(embed%slave)
590 id = embed%states(i)%surface
591 if (abs(contact_surf(embed%slave(i))) /= elemid(embed%master(id)%eid))
then
593 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i10,A,i6,A,i6,A)')
"Node",nodeid(embed%slave(i)),
" contact with element", &
594 & elemid(embed%master(id)%eid),
" in rank",hecmw_comm_get_rank(),
" freed due to duplication"
596 nactive = nactive + 1
601 if (icat_prev /= icat_curr) infoctchange%n_statechange(icat_prev,icat_curr) = &
602 infoctchange%n_statechange(icat_prev,icat_curr) + 1
604 active = (nactive > 0)
605 deallocate(contact_surf)
606 deallocate(states_prev)
611 integer(kind=kint),
intent(in) :: cstep
612 type( hecmwst_local_mesh ),
intent(in) :: hecMESH
616 integer(kind=kint) :: i, j, grpid, slave
617 integer(kind=kint) :: k, id, iSS, icat
618 integer(kind=kint) :: ig0, ig, iS0, iE0
619 integer(kind=kint),
allocatable :: states(:)
621 allocate(states(hecmesh%n_node))
625 do ig0= 1, fstrsolid%BOUNDARY_ngrp_tot
626 grpid = fstrsolid%BOUNDARY_ngrp_GRPID(ig0)
628 ig= fstrsolid%BOUNDARY_ngrp_ID(ig0)
629 is0= hecmesh%node_group%grp_index(ig-1) + 1
630 ie0= hecmesh%node_group%grp_index(ig )
632 iss = hecmesh%node_group%grp_item(k)
637 do i=1,fstrsolid%n_contacts
638 if( fstrsolid%contacts(i)%algtype /=
contacttied ) cycle
639 grpid = fstrsolid%contacts(i)%group
642 do j=1,
size(fstrsolid%contacts(i)%slave)
644 slave = fstrsolid%contacts(i)%slave(j)
646 states(slave) = fstrsolid%contacts(i)%states(j)%state
647 id = fstrsolid%contacts(i)%states(j)%surface
648 do k=1,
size( fstrsolid%contacts(i)%master(id)%nodes )
649 iss = fstrsolid%contacts(i)%master(id)%nodes(k)
650 states(iss) = fstrsolid%contacts(i)%states(j)%state
654 fstrsolid%contacts(i)%states(j)%state =
contactfree
655 infoctchange%n_statechange(
kcatfree,icat) = infoctchange%n_statechange(
kcatfree,icat) - 1
656 if (
contact_log_level >= 1)
write(*,
'(A,i10,A,i6,A,i6,A)')
"Node",hecmesh%global_node_ID(slave), &
657 " in rank",hecmw_comm_get_rank(),
" freed due to duplication"
669 type(
tcontact ),
intent(inout) :: contact
671 real(kind=kreal),
intent(in) :: currpos(:)
672 logical,
intent(in) :: is_init
673 logical,
intent(out) :: active
675 real(kind=kreal) :: distclr
676 integer(kind=kint) :: slave, id
677 integer(kind=kint) :: nnode_s, i, j
678 real(kind=kreal) :: coord(3), ncoord(2)
679 real(kind=kreal) :: surf_node_pos(3,4), sfunc(4)
682 integer,
pointer :: indexCand(:)
683 integer :: idm,bktID,nCand,id_best
686 integer(kind=kint) :: maplist(MAX_N_INTP), master_idxs(MAX_N_INTP)
687 integer(kind=kint) :: unique_count
688 integer(kind=kint) :: known_masters(MAX_N_INTP), n_known
691 logical :: counted_f2c, counted_nbr, counted_byd
693 distclr = contact%cparam%DISTCLR_INIT
695 distclr = contact%cparam%DISTCLR_FREE
697 call update_surface_box_info( contact%master, currpos )
698 call update_surface_bucket_info( contact%master, contact%master_bktDB )
712 do i = 1,
size(contact%slave_surf)
713 surf_node_pos(:,:) = 0.d0
714 nnode_s =
size(contact%slave_surf(i)%nodes)
718 call get_unique_map(contact%slave_surf(i), maplist, master_idxs, unique_count)
719 n_known = unique_count
720 if( n_known > 0 ) known_masters(1:n_known) = master_idxs(1:n_known)
721 counted_f2c = .false.
722 counted_nbr = .false.
723 counted_byd = .false.
727 do j = 1, contact%slave_surf(i)%n_intp
728 if (contact%slave_surf(i)%states(j)%state ==
contactfree)
then
734 slave = contact%slave_surf(i)%nodes(j)
735 surf_node_pos(:,j) = currpos(3*slave-2:3*slave)
739 contact%slave_surf(i)%state_prev = contact%slave_surf(i)%state
741 do j = 1, contact%slave_surf(i)%n_intp
747 call getintpoint4ss( contact%slave_surf(i)%etype, j, ncoord, contact%slave_surf(i)%n_intp, sfunc )
748 coord(:) = matmul( surf_node_pos(:,1:nnode_s), sfunc(1:nnode_s) )
751 if( contact%slave_surf(i)%states(j)%state==
contactstick .or. contact%slave_surf(i)%states(j)%state==
contactslip )
then
753 id = contact%slave_surf(i)%states(j)%surface
759 contact%slave_surf(i), ncoord, contact, currpos, infoctchange, counted_nbr, counted_byd )
764 else if( contact%slave_surf(i)%states(j)%state==
candidate_intp )
then
768 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
769 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
770 if (ncand == 0) cycle
771 allocate(indexcand(ncand))
772 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
778 state_free = contact%slave_surf(i)%states(j)
785 state_try = state_free
787 ncoord, currpos, state_try, isin, distclr=distclr, &
788 penclr=contact%cparam%PENCLR_FREE, localclr=contact%cparam%CLEARANCE )
789 if( .not. isin ) cycle
790 if( id_best /= 0 )
then
791 if( dabs(state_try%distance) > dabs(state_best%distance) ) cycle
792 if( dabs(state_try%distance) == dabs(state_best%distance) .and. id > id_best ) cycle
795 state_best = state_try
797 if( id_best /= 0 )
then
799 contact%slave_surf(i)%states(j) = state_best
800 contact%slave_surf(i)%states(j)%surface = id
801 contact%slave_surf(i)%states(j)%multiplier(:) = 0.d0
809 if( (contact%sparsity_expansion ==
sparsity_none .or. .not. is_known) .and. .not. counted_f2c )
then
811 infoctchange%free2contact_new = infoctchange%free2contact_new + 1
815 deallocate(indexcand)
824 type(
tcontact ),
intent(inout) :: contact
827 real(kind=kreal),
intent(in) :: ncoord(2)
829 logical,
intent(inout) :: counted_nbr
830 logical,
intent(inout) :: counted_byd
831 real(kind=kreal),
intent(in) :: currpos(:)
832 real(kind=kreal),
intent(inout) :: coord(:)
834 integer(kind=kint) :: sid0, sid
835 integer(kind=kint) :: i, j
836 logical :: isin, found_in_neighbor
837 real(kind=kreal) :: opos(2)
838 integer(kind=kint) :: bktid, ncand, idm, id_best
839 integer(kind=kint),
allocatable :: indexcand(:)
843 found_in_neighbor = .false.
847 opos = state%lpos(1:2)
850 state, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
851 state%lpos(1:2), contact%cparam%CLR_SAME_ELEM )
852 if( .not. isin )
then
857 do i=1, contact%master(sid0)%n_neighbor
858 sid = contact%master(sid0)%neighbor(i)
859 state_try = state_free
861 state_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_NOCHECK, &
862 localclr=contact%cparam%CLEARANCE )
863 if( .not. isin ) cycle
864 if( id_best /= 0 )
then
865 if( dabs(state_try%distance) > dabs(state_best%distance) ) cycle
866 if( dabs(state_try%distance) == dabs(state_best%distance) .and. sid > id_best ) cycle
869 state_best = state_try
871 isin = ( id_best /= 0 )
876 found_in_neighbor = .true.
880 if( .not. isin )
then
883 bktid = bucketdb_getbucketid(contact%master_bktDB, coord)
884 ncand = bucketdb_getnumcand(contact%master_bktDB, bktid)
886 allocate(indexcand(ncand))
887 call bucketdb_getcand(contact%master_bktDB, bktid, ncand, indexcand)
891 if( sid==sid0 ) cycle
892 if(
associated(contact%master(sid0)%neighbor) )
then
893 if( any(sid==contact%master(sid0)%neighbor(:)) ) cycle
895 state_try = state_free
897 state_try, isin, contact%cparam%DISTCLR_NOCHECK, contact%cparam%PENCLR_FREE, &
898 localclr=contact%cparam%CLEARANCE )
899 if( .not. isin ) cycle
900 if( id_best /= 0 )
then
901 if( dabs(state_try%distance) > dabs(state_best%distance) ) cycle
902 if( dabs(state_try%distance) == dabs(state_best%distance) .and. sid > id_best ) cycle
905 state_best = state_try
907 deallocate(indexcand)
908 isin = ( id_best /= 0 )
918 if( state%distance > contact%cparam%DISTCLR_C2F * contact%master(state%surface)%reflen )
then
920 state%multiplier(:) = 0.d0
925 if( state%surface /= sid0 )
then
926 if( found_in_neighbor )
then
928 if( contact%sparsity_expansion ==
sparsity_none .and. .not. counted_nbr )
then
930 infoctchange%contact2neighbor = infoctchange%contact2neighbor + 1
933 else if( .not. counted_byd )
then
935 infoctchange%contact2beyond = infoctchange%contact2beyond + 1
940 else if( .not. isin )
then
942 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)