23 real(kind=kreal),
save ::
cgn=1.d-5
24 real(kind=kreal),
save ::
cgt=1.d-3
26 real(kind=kreal),
save ::
gnt(2)
77 real(kind=kreal) :: distance
78 real(kind=kreal) :: wkdist
79 real(kind=kreal) :: lpos(3)
80 real(kind=kreal) :: gpos(3)
81 real(kind=kreal) :: direction(3)
82 real(kind=kreal) :: multiplier(3)
84 real(kind=kreal) :: tangentforce(3)
85 real(kind=kreal) :: tangentforce1(3)
86 real(kind=kreal) :: tangentforce_trial(3)
87 real(kind=kreal) :: tangentforce_final(3)
88 real(kind=kreal) :: reldisp(3)
90 real(kind=kreal) :: shrink_factor
91 real(kind=kreal) :: time_factor
92 real(kind=kreal) :: init_pos
93 real(kind=kreal) :: end_pos
94 integer :: interference_flag
99 integer(kind=kint) :: eid
100 integer(kind=kint) :: etype
101 integer(kind=kint),
pointer :: nodes(:)=>null()
104 integer(kind=kint) :: n_intp
106 integer(kind=kint),
pointer :: nslave_index(:)=>null()
110 integer(kind=kint),
pointer :: lam_begin_id(:)=>null()
111 real(kind=kreal),
pointer :: lam_begin_val(:,:)=>null()
112 integer(kind=kint) :: lam_begin_n = 0
113 integer(kind=kint),
pointer :: lam_work_id(:)=>null()
114 real(kind=kreal),
pointer :: lam_work_val(:,:)=>null()
115 integer(kind=kint) :: lam_work_n = 0
120 real(kind=kreal),
pointer :: lam_begin_t(:,:,:)=>null()
121 real(kind=kreal),
pointer :: lam_work_t(:,:,:)=>null()
122 integer(kind=kint),
pointer :: lam_begin_fstate(:,:)=>null()
123 integer(kind=kint),
pointer :: lam_work_fstate(:,:)=>null()
132 character(len=HECMW_NAME_LEN) :: name
135 character(len=HECMW_NAME_LEN) :: pair_name
136 integer :: surf_id1, surf_id2
137 integer :: surf_id1_sgrp
139 integer :: n_master_owned = 0
140 integer,
pointer :: slave(:)=>null()
141 real(kind=kreal) :: fcoeff
142 real(kind=kreal) :: npenalty
143 real(kind=kreal) :: tpenalty
144 real(kind=kreal) :: refstiff
145 real(kind=kreal) :: damp_alpha
146 real(kind=kreal) :: damp_gact
153 real(kind=kreal) :: ctime = 0.d0
154 integer(kind=kint) :: if_type = 0
155 real(kind=kreal) :: if_etime = 0.d0
156 real(kind=kreal) :: initial_pos = 0.d0
157 real(kind=kreal) :: end_pos = 0.d0
172 real(kind=kreal) :: eps_fric_band = 0.d0
177 type(hecmwst_contact_comm) :: comm
178 type(bucketdb) :: master_bktdb
180 type(tcontactparam),
pointer :: cparam=>null()
185 integer(kind=kint) :: n_statechange(3,3)
186 integer(kind=kint) :: contact2neighbor
187 integer(kind=kint) :: contact2beyond
188 integer(kind=kint) :: contact2difflpos
189 integer(kind=kint) :: free2contact_new
190 integer(kind=kint) :: contactnode_previous
191 integer(kind=kint) :: contactnode_current
194 private :: is_active_contact
203 cstate%distance = 0.0d0
204 cstate%wkdist = 0.0d0
205 cstate%lpos(:) = 0.0d0
206 cstate%gpos(:) = 0.0d0
207 cstate%direction(:) = 0.0d0
208 cstate%multiplier(:) = 0.0d0
209 cstate%tangentForce(:) = 0.0d0
210 cstate%tangentForce1(:) = 0.0d0
211 cstate%tangentForce_trial(:) = 0.0d0
212 cstate%tangentForce_final(:) = 0.0d0
213 cstate%reldisp(:) = 0.0d0
214 cstate%shrink_factor = 0.0d0
215 cstate%time_factor = 0.0d0
216 cstate%init_pos = 0.0d0
217 cstate%end_pos = 0.0d0
218 cstate%interference_flag = 0
230 integer,
intent(in) :: state
236 integer,
intent(in) :: state
242 integer,
intent(in) :: state
254 type(
tcontact),
intent(inout) :: contact
256 if(
associated( contact%slave ) )
deallocate(contact%slave)
257 if(
associated( contact%master ) )
then
258 do i=1,
size( contact%master )
261 deallocate(contact%master)
263 if(
associated(contact%states) )
deallocate(contact%states)
270 type(
tcontact),
intent(inout) :: contact
271 type(hecmwst_local_mesh),
pointer :: hecmesh
280 do i=1,hecmesh%contact_pair%n_pair
281 if( hecmesh%contact_pair%name(i) == contact%pair_name )
then
282 contact%ctype = hecmesh%contact_pair%type(i)
283 contact%surf_id1 = hecmesh%contact_pair%slave_grp_id(i)
284 contact%surf_id2 = hecmesh%contact_pair%master_grp_id(i)
285 contact%surf_id1_sgrp = hecmesh%contact_pair%slave_orisgrp_id(i)
289 if( .not. isfind ) return;
290 if( contact%fcoeff<=0.d0 ) contact%fcoeff=0.d0
291 if( contact%ctype < 1 .and. contact%ctype > 3 )
return
292 if( contact%group<=0 )
return
299 type(
tcontact),
intent(in) :: contact
300 type(hecmwst_local_mesh),
pointer :: hecmesh
302 integer :: i, is, ie, cgrp
306 cgrp = contact%surf_id1
308 is= hecmesh%node_group%grp_index(cgrp-1) + 1
309 ie= hecmesh%node_group%grp_index(cgrp )
311 if( hecmesh%node_group%grp_item(i) <= hecmesh%nn_internal )
then
319 type(
tcontact),
intent(inout) :: contact
320 type(hecmwst_local_mesh),
pointer :: hecmesh
321 type(tcontactparam),
target :: cparam
323 integer :: i, j, is, ie, cgrp, nsurf, nslave, ic, ic_type, iss, nn, ii
324 integer :: count, id_area
325 logical :: slave_owner, take_master
326 integer,
allocatable :: slave_index(:)
330 contact%cparam => cparam
332 slave_owner = hecmw_partcontact_get_owner( hecmesh%hecmw_flag_partcontact ) == hecmw_flag_partcontact_owner_slave
341 cgrp = contact%surf_id2
343 is= hecmesh%surf_group%grp_index(cgrp-1) + 1
344 ie= hecmesh%surf_group%grp_index(cgrp )
348 contact%n_master_owned = 0
350 ic = hecmesh%surf_group%grp_item(2*i-1)
351 if( hecmesh%elem_ID(ic*2) == hecmesh%my_rank ) contact%n_master_owned = contact%n_master_owned + 1
355 if( take_master )
then
357 ic = hecmesh%surf_group%grp_item(2*i-1)
358 id_area = hecmesh%elem_ID(ic*2)
359 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
363 allocate( contact%master(count) )
365 if( take_master )
then
367 ic = hecmesh%surf_group%grp_item(2*i-1)
368 id_area = hecmesh%elem_ID(ic*2)
369 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
371 nsurf = hecmesh%surf_group%grp_item(2*i)
372 ic_type = hecmesh%elem_type(ic)
374 iss = hecmesh%elem_node_index(ic-1)
375 do j=1,
size( contact%master(count)%nodes )
376 nn = contact%master(count)%nodes(j)
377 contact%master(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
384 cgrp = contact%surf_id1
386 is= hecmesh%node_group%grp_index(cgrp-1) + 1
387 ie= hecmesh%node_group%grp_index(cgrp )
390 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
393 allocate( contact%slave(nslave) )
394 allocate( slave_index(hecmesh%n_node) )
398 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
400 contact%slave(ii) = hecmesh%node_group%grp_item(i)
401 slave_index(contact%slave(ii)) = ii
405 allocate( contact%states(nslave) )
420 do i=1,
size( contact%master )
421 if( contact%master(i)%etype /=
fe_quad4n .and. contact%master(i)%etype /=
fe_tri3n )
then
422 write(*,*)
'### Error: MORTAR=YES supports first-order surfaces only (quad4/tri3) : etype=', &
423 contact%master(i)%etype
424 stop hecmw_exit_model
429 cgrp = contact%surf_id1_sgrp
431 is= hecmesh%surf_group%grp_index(cgrp-1) + 1
432 ie= hecmesh%surf_group%grp_index(cgrp )
440 ic = hecmesh%surf_group%grp_item(2*i-1)
441 if( hecmesh%elem_ID(ic*2) /= hecmesh%my_rank ) cycle
444 allocate( contact%slave_surf(count) )
447 ic = hecmesh%surf_group%grp_item(2*i-1)
448 if( hecmesh%elem_ID(ic*2) /= hecmesh%my_rank ) cycle
450 nsurf = hecmesh%surf_group%grp_item(2*i)
451 ic_type = hecmesh%elem_type(ic)
453 iss = hecmesh%elem_node_index(ic-1)
454 do j=1,
size( contact%slave_surf(count)%nodes )
455 nn = contact%slave_surf(count)%nodes(j)
456 contact%slave_surf(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
457 contact%slave_surf(count)%nslave_index(j) = slave_index(hecmesh%elem_node_item( iss+nn ))
462 do i=1,
size( contact%slave_surf )
463 nn = contact%slave_surf(i)%n_intp
464 allocate( contact%slave_surf(i)%states(nn) )
465 do j = 1, contact%slave_surf(i)%n_intp
466 contact%slave_surf(i)%states(j)%state = -1
467 contact%slave_surf(i)%states(j)%multiplier(:) = 0.d0
468 contact%slave_surf(i)%states(j)%tangentForce(:) = 0.d0
469 contact%slave_surf(i)%states(j)%tangentForce1(:) = 0.d0
470 contact%slave_surf(i)%states(j)%tangentForce_trial(:) = 0.d0
471 contact%slave_surf(i)%states(j)%tangentForce_final(:) = 0.d0
472 contact%slave_surf(i)%states(j)%reldisp(:) = 0.d0
473 contact%slave_surf(i)%states(j)%time_factor = 0.d0
474 contact%slave_surf(i)%states(j)%interference_flag = 0
482 contact%symmetric = .true.
488 type(
tcontact),
intent(inout) :: embed
489 type(hecmwst_local_mesh),
pointer :: hecmesh
490 type(tcontactparam),
target :: cparam
492 integer :: i, j, is, ie, cgrp, nslave, ic, ic_type, iss, nn, ii
493 integer :: count, id_area
494 logical :: slave_owner, take_master
498 embed%cparam => cparam
500 slave_owner = hecmw_partcontact_get_owner( hecmesh%hecmw_flag_partcontact ) == hecmw_flag_partcontact_owner_slave
506 cgrp = embed%surf_id2
508 is= hecmesh%elem_group%grp_index(cgrp-1) + 1
509 ie= hecmesh%elem_group%grp_index(cgrp )
512 if( take_master )
then
514 ic = hecmesh%elem_group%grp_item(i)
515 id_area = hecmesh%elem_ID(ic*2)
516 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
520 allocate( embed%master(count) )
522 if( take_master )
then
524 ic = hecmesh%elem_group%grp_item(i)
525 id_area = hecmesh%elem_ID(ic*2)
526 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
528 ic_type = hecmesh%elem_type(ic)
530 iss = hecmesh%elem_node_index(ic-1)
531 do j=1,
size( embed%master(count)%nodes )
532 nn = embed%master(count)%nodes(j)
533 embed%master(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
539 cgrp = embed%surf_id1
541 is= hecmesh%node_group%grp_index(cgrp-1) + 1
542 ie= hecmesh%node_group%grp_index(cgrp )
545 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
548 allocate( embed%slave(nslave) )
551 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
553 embed%slave(ii) = hecmesh%node_group%grp_item(i)
557 allocate( embed%states(nslave) )
572 embed%nPenalty = 1.0d0
573 embed%tPenalty = 0.1d0
574 embed%refStiff = 0.0d0
575 embed%damp_alpha = 0.0d0
576 embed%damp_gact = 0.0d0
578 embed%symmetric = .true.
583 type(tcontactinterference),
intent(inout) :: contact_if
593 do i = 1,
size(contacts)
594 if( contacts(i)%pair_name == contact_if%cp_name )
then
597 write(*,*)
'### Error: CONTACT_INTERFERENCE is not supported with MORTAR=YES'
598 stop hecmw_exit_model
600 contacts(i)%if_type = contact_if%if_type
601 contacts(i)%if_etime = contact_if%etime
602 contacts(i)%initial_pos = contact_if%initial_pos
603 contacts(i)%end_pos = contact_if%end_pos
604 do j = 1,
size(contacts(i)%states)
605 contacts(i)%states(j)%interference_flag = contact_if%if_type
606 contacts(i)%states(j)%init_pos = contact_if%initial_pos
607 contacts(i)%states(j)%end_pos = contact_if%end_pos
609 contacts(i)%states(j)%time_factor = (contact_if%end_pos - contact_if%initial_pos) / contact_if%etime
611 contacts(i)%states(j)%time_factor = contact_if%etime
618 if( .not. isfind ) return;
625 type(
tcontact),
intent(inout) :: contact
627 if( .not.
associated(contact%states) )
return
628 do i=1,
size( contact%states )
629 contact%states(i)%state = -1
634 logical function is_active_contact( acgrp, contact )
635 integer,
intent(in) :: acgrp(:)
636 type(
tcontact),
intent(in) :: contact
637 if( any( acgrp==contact%group ) )
then
638 is_active_contact = .true.
640 is_active_contact = .false.
647 integer(kind=kint),
intent(in) :: eid
648 integer(kind=kint),
intent(in) :: etype
649 integer(kind=kint),
intent(in) :: nsurf
651 integer(kind=kint) :: n, outtype, nodes(100)
654 call getsubface( etype, nsurf, outtype, nodes )
659 else if(surf%etype ==
fe_tri3n )
then
662 write(*,*)
'### Error: MORTAR=YES supports first-order surfaces only (quad4/tri3) : etype=', surf%etype
663 stop hecmw_exit_model
665 allocate( surf%nodes(n) )
666 allocate( surf%nslave_index(n) )
667 surf%nodes(1:n)=nodes(1:n)
668 surf%nslave_index(:)= 0
670 allocate( surf%lam_begin_id(surf%n_intp), surf%lam_begin_val(n,surf%n_intp) )
671 allocate( surf%lam_work_id (surf%n_intp), surf%lam_work_val (n,surf%n_intp) )
672 surf%lam_begin_id(:) = 0; surf%lam_begin_val(:,:) = 0.0d0; surf%lam_begin_n = 0
673 surf%lam_work_id (:) = 0; surf%lam_work_val (:,:) = 0.0d0; surf%lam_work_n = 0
676 allocate( surf%lam_begin_t(2,n,surf%n_intp), surf%lam_work_t(2,n,surf%n_intp) )
677 allocate( surf%lam_begin_fstate(n,surf%n_intp), surf%lam_work_fstate(n,surf%n_intp) )
678 surf%lam_begin_t(:,:,:) = 0.0d0; surf%lam_work_t(:,:,:) = 0.0d0
This module provides bucket-search functionality It provides definition of bucket info and its access...
subroutine, public bucketdb_finalize(bktdb)
Finalizer.
subroutine, public bucketdb_init(bktdb)
Initializer.
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.
subroutine getsubface(intype, innumber, outtype, nodes)
Find the definition of surface of the element.
integer, parameter fe_tri3n
integer, parameter fe_quad4n
This module manages surface elements in 3D It provides basic definition of surface elements (triangla...
subroutine initialize_surf(eid, etype, nsurf, surf)
Initializer.
subroutine update_surface_reflen(surf, coord)
Compute reference length of surface elements.
subroutine update_surface_box_info(surf, currpos)
Update info of cubic box including surface elements.
subroutine find_surface_neighbor(surf, bktDB)
Find neighboring surface elements.
subroutine update_surface_bucket_info(surf, bktDB)
Update bucket info for searching surface elements.
subroutine finalize_surf(surf)
Memory management subroutine.
Structure to define surface group.