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 integer :: id_lagrange
78 real(kind=kreal) :: distance
79 real(kind=kreal) :: wkdist
80 real(kind=kreal) :: lpos(3)
81 real(kind=kreal) :: gpos(3)
82 real(kind=kreal) :: direction(3)
83 real(kind=kreal) :: multiplier(3)
85 real(kind=kreal) :: tangentforce(3)
86 real(kind=kreal) :: tangentforce1(3)
87 real(kind=kreal) :: tangentforce_trial(3)
88 real(kind=kreal) :: tangentforce_final(3)
89 real(kind=kreal) :: reldisp(3)
91 real(kind=kreal) :: shrink_factor
92 real(kind=kreal) :: time_factor
93 real(kind=kreal) :: init_pos
94 real(kind=kreal) :: end_pos
95 integer :: interference_flag
100 integer(kind=kint) :: eid
101 integer(kind=kint) :: etype
102 integer(kind=kint),
pointer :: nodes(:)=>null()
105 integer(kind=kint) :: n_intp
107 integer(kind=kint),
pointer :: nslave_index(:)=>null()
111 integer(kind=kint),
pointer :: lam_begin_id(:)=>null()
112 real(kind=kreal),
pointer :: lam_begin_val(:,:)=>null()
113 integer(kind=kint) :: lam_begin_n = 0
114 integer(kind=kint),
pointer :: lam_work_id(:)=>null()
115 real(kind=kreal),
pointer :: lam_work_val(:,:)=>null()
116 integer(kind=kint) :: lam_work_n = 0
121 real(kind=kreal),
pointer :: lam_begin_t(:,:,:)=>null()
122 real(kind=kreal),
pointer :: lam_work_t(:,:,:)=>null()
123 integer(kind=kint),
pointer :: lam_begin_fstate(:,:)=>null()
124 integer(kind=kint),
pointer :: lam_work_fstate(:,:)=>null()
130 character(len=HECMW_NAME_LEN) :: name
133 character(len=HECMW_NAME_LEN) :: pair_name
134 integer :: surf_id1, surf_id2
135 integer :: surf_id1_sgrp
137 integer :: n_master_owned = 0
138 integer,
pointer :: slave(:)=>null()
139 real(kind=kreal) :: fcoeff
140 real(kind=kreal) :: npenalty
141 real(kind=kreal) :: tpenalty
142 real(kind=kreal) :: refstiff
143 real(kind=kreal) :: damp_alpha
144 real(kind=kreal) :: damp_gact
151 real(kind=kreal) :: ctime = 0.d0
152 integer(kind=kint) :: if_type = 0
153 real(kind=kreal) :: if_etime = 0.d0
154 real(kind=kreal) :: initial_pos = 0.d0
155 real(kind=kreal) :: end_pos = 0.d0
170 real(kind=kreal) :: eps_fric_band = 0.d0
175 type(hecmwst_contact_comm) :: comm
176 type(bucketdb) :: master_bktdb
178 type(tcontactparam),
pointer :: cparam=>null()
183 integer(kind=kint) :: n_statechange(3,3)
184 integer(kind=kint) :: contact2neighbor
185 integer(kind=kint) :: contact2beyond
186 integer(kind=kint) :: contact2difflpos
187 integer(kind=kint) :: free2contact_new
188 integer(kind=kint) :: contactnode_previous
189 integer(kind=kint) :: contactnode_current
192 private :: is_active_contact
201 cstate%id_lagrange = 0
202 cstate%distance = 0.0d0
203 cstate%wkdist = 0.0d0
204 cstate%lpos(:) = 0.0d0
205 cstate%gpos(:) = 0.0d0
206 cstate%direction(:) = 0.0d0
207 cstate%multiplier(:) = 0.0d0
208 cstate%tangentForce(:) = 0.0d0
209 cstate%tangentForce1(:) = 0.0d0
210 cstate%tangentForce_trial(:) = 0.0d0
211 cstate%tangentForce_final(:) = 0.0d0
212 cstate%reldisp(:) = 0.0d0
213 cstate%shrink_factor = 0.0d0
214 cstate%time_factor = 0.0d0
215 cstate%init_pos = 0.0d0
216 cstate%end_pos = 0.0d0
217 cstate%interference_flag = 0
229 integer,
intent(in) :: state
235 integer,
intent(in) :: state
241 integer,
intent(in) :: state
253 type(
tcontact),
intent(inout) :: contact
255 if(
associated( contact%slave ) )
deallocate(contact%slave)
256 if(
associated( contact%master ) )
then
257 do i=1,
size( contact%master )
260 deallocate(contact%master)
262 if(
associated(contact%states) )
deallocate(contact%states)
269 type(
tcontact),
intent(inout) :: contact
270 type(hecmwst_local_mesh),
pointer :: hecmesh
279 do i=1,hecmesh%contact_pair%n_pair
280 if( hecmesh%contact_pair%name(i) == contact%pair_name )
then
281 contact%ctype = hecmesh%contact_pair%type(i)
282 contact%surf_id1 = hecmesh%contact_pair%slave_grp_id(i)
283 contact%surf_id2 = hecmesh%contact_pair%master_grp_id(i)
284 contact%surf_id1_sgrp = hecmesh%contact_pair%slave_orisgrp_id(i)
288 if( .not. isfind ) return;
289 if( contact%fcoeff<=0.d0 ) contact%fcoeff=0.d0
290 if( contact%ctype < 1 .and. contact%ctype > 3 )
return
291 if( contact%group<=0 )
return
298 type(
tcontact),
intent(in) :: contact
299 type(hecmwst_local_mesh),
pointer :: hecmesh
301 integer :: i, is, ie, cgrp
305 cgrp = contact%surf_id1
307 is= hecmesh%node_group%grp_index(cgrp-1) + 1
308 ie= hecmesh%node_group%grp_index(cgrp )
310 if( hecmesh%node_group%grp_item(i) <= hecmesh%nn_internal )
then
318 type(
tcontact),
intent(inout) :: contact
319 type(hecmwst_local_mesh),
pointer :: hecmesh
320 type(tcontactparam),
target :: cparam
322 integer :: i, j, is, ie, cgrp, nsurf, nslave, ic, ic_type, iss, nn, ii
323 integer :: count, id_area
324 logical :: slave_owner, take_master
325 integer,
allocatable :: slave_index(:)
329 contact%cparam => cparam
331 slave_owner = hecmw_partcontact_get_owner( hecmesh%hecmw_flag_partcontact ) == hecmw_flag_partcontact_owner_slave
340 cgrp = contact%surf_id2
342 is= hecmesh%surf_group%grp_index(cgrp-1) + 1
343 ie= hecmesh%surf_group%grp_index(cgrp )
347 contact%n_master_owned = 0
349 ic = hecmesh%surf_group%grp_item(2*i-1)
350 if( hecmesh%elem_ID(ic*2) == hecmesh%my_rank ) contact%n_master_owned = contact%n_master_owned + 1
354 if( take_master )
then
356 ic = hecmesh%surf_group%grp_item(2*i-1)
357 id_area = hecmesh%elem_ID(ic*2)
358 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
362 allocate( contact%master(count) )
364 if( take_master )
then
366 ic = hecmesh%surf_group%grp_item(2*i-1)
367 id_area = hecmesh%elem_ID(ic*2)
368 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
370 nsurf = hecmesh%surf_group%grp_item(2*i)
371 ic_type = hecmesh%elem_type(ic)
373 iss = hecmesh%elem_node_index(ic-1)
374 do j=1,
size( contact%master(count)%nodes )
375 nn = contact%master(count)%nodes(j)
376 contact%master(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
383 cgrp = contact%surf_id1
385 is= hecmesh%node_group%grp_index(cgrp-1) + 1
386 ie= hecmesh%node_group%grp_index(cgrp )
389 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
392 allocate( contact%slave(nslave) )
393 allocate( slave_index(hecmesh%n_node) )
397 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
399 contact%slave(ii) = hecmesh%node_group%grp_item(i)
400 slave_index(contact%slave(ii)) = ii
404 allocate( contact%states(nslave) )
419 do i=1,
size( contact%master )
420 if( contact%master(i)%etype /=
fe_quad4n .and. contact%master(i)%etype /=
fe_tri3n )
then
421 write(*,*)
'### Error: MORTAR=YES supports first-order surfaces only (quad4/tri3) : etype=', &
422 contact%master(i)%etype
423 stop hecmw_exit_model
428 cgrp = contact%surf_id1_sgrp
430 is= hecmesh%surf_group%grp_index(cgrp-1) + 1
431 ie= hecmesh%surf_group%grp_index(cgrp )
439 ic = hecmesh%surf_group%grp_item(2*i-1)
440 if( hecmesh%elem_ID(ic*2) /= hecmesh%my_rank ) cycle
443 allocate( contact%slave_surf(count) )
446 ic = hecmesh%surf_group%grp_item(2*i-1)
447 if( hecmesh%elem_ID(ic*2) /= hecmesh%my_rank ) cycle
449 nsurf = hecmesh%surf_group%grp_item(2*i)
450 ic_type = hecmesh%elem_type(ic)
452 iss = hecmesh%elem_node_index(ic-1)
453 do j=1,
size( contact%slave_surf(count)%nodes )
454 nn = contact%slave_surf(count)%nodes(j)
455 contact%slave_surf(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
456 contact%slave_surf(count)%nslave_index(j) = slave_index(hecmesh%elem_node_item( iss+nn ))
461 do i=1,
size( contact%slave_surf )
462 nn = contact%slave_surf(i)%n_intp
463 allocate( contact%slave_surf(i)%states(nn) )
464 do j = 1, contact%slave_surf(i)%n_intp
465 contact%slave_surf(i)%states(j)%state = -1
466 contact%slave_surf(i)%states(j)%multiplier(:) = 0.d0
467 contact%slave_surf(i)%states(j)%tangentForce(:) = 0.d0
468 contact%slave_surf(i)%states(j)%tangentForce1(:) = 0.d0
469 contact%slave_surf(i)%states(j)%tangentForce_trial(:) = 0.d0
470 contact%slave_surf(i)%states(j)%tangentForce_final(:) = 0.d0
471 contact%slave_surf(i)%states(j)%reldisp(:) = 0.d0
472 contact%slave_surf(i)%states(j)%time_factor = 0.d0
473 contact%slave_surf(i)%states(j)%interference_flag = 0
481 contact%symmetric = .true.
487 type(
tcontact),
intent(inout) :: embed
488 type(hecmwst_local_mesh),
pointer :: hecmesh
489 type(tcontactparam),
target :: cparam
491 integer :: i, j, is, ie, cgrp, nslave, ic, ic_type, iss, nn, ii
492 integer :: count, id_area
493 logical :: slave_owner, take_master
497 embed%cparam => cparam
499 slave_owner = hecmw_partcontact_get_owner( hecmesh%hecmw_flag_partcontact ) == hecmw_flag_partcontact_owner_slave
505 cgrp = embed%surf_id2
507 is= hecmesh%elem_group%grp_index(cgrp-1) + 1
508 ie= hecmesh%elem_group%grp_index(cgrp )
511 if( take_master )
then
513 ic = hecmesh%elem_group%grp_item(i)
514 id_area = hecmesh%elem_ID(ic*2)
515 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
519 allocate( embed%master(count) )
521 if( take_master )
then
523 ic = hecmesh%elem_group%grp_item(i)
524 id_area = hecmesh%elem_ID(ic*2)
525 if( .not. slave_owner .and. id_area /= hecmesh%my_rank ) cycle
527 ic_type = hecmesh%elem_type(ic)
529 iss = hecmesh%elem_node_index(ic-1)
530 do j=1,
size( embed%master(count)%nodes )
531 nn = embed%master(count)%nodes(j)
532 embed%master(count)%nodes(j) = hecmesh%elem_node_item( iss+nn )
538 cgrp = embed%surf_id1
540 is= hecmesh%node_group%grp_index(cgrp-1) + 1
541 ie= hecmesh%node_group%grp_index(cgrp )
544 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
547 allocate( embed%slave(nslave) )
550 if( slave_owner .and. hecmesh%node_group%grp_item(i) > hecmesh%nn_internal ) cycle
552 embed%slave(ii) = hecmesh%node_group%grp_item(i)
556 allocate( embed%states(nslave) )
571 embed%nPenalty = 1.0d0
572 embed%tPenalty = 0.1d0
573 embed%refStiff = 0.0d0
574 embed%damp_alpha = 0.0d0
575 embed%damp_gact = 0.0d0
577 embed%symmetric = .true.
582 type(tcontactinterference),
intent(inout) :: contact_if
592 do i = 1,
size(contacts)
593 if( contacts(i)%pair_name == contact_if%cp_name )
then
596 write(*,*)
'### Error: CONTACT_INTERFERENCE is not supported with MORTAR=YES'
597 stop hecmw_exit_model
599 contacts(i)%if_type = contact_if%if_type
600 contacts(i)%if_etime = contact_if%etime
601 contacts(i)%initial_pos = contact_if%initial_pos
602 contacts(i)%end_pos = contact_if%end_pos
603 do j = 1,
size(contacts(i)%states)
604 contacts(i)%states(j)%interference_flag = contact_if%if_type
605 contacts(i)%states(j)%init_pos = contact_if%initial_pos
606 contacts(i)%states(j)%end_pos = contact_if%end_pos
608 contacts(i)%states(j)%time_factor = (contact_if%end_pos - contact_if%initial_pos) / contact_if%etime
610 contacts(i)%states(j)%time_factor = contact_if%etime
617 if( .not. isfind ) return;
624 type(
tcontact),
intent(inout) :: contact
626 if( .not.
associated(contact%states) )
return
627 do i=1,
size( contact%states )
628 contact%states(i)%state = -1
633 logical function is_active_contact( acgrp, contact )
634 integer,
intent(in) :: acgrp(:)
635 type(
tcontact),
intent(in) :: contact
636 if( any( acgrp==contact%group ) )
then
637 is_active_contact = .true.
639 is_active_contact = .false.
646 integer(kind=kint),
intent(in) :: eid
647 integer(kind=kint),
intent(in) :: etype
648 integer(kind=kint),
intent(in) :: nsurf
650 integer(kind=kint) :: n, outtype, nodes(100)
653 call getsubface( etype, nsurf, outtype, nodes )
658 else if(surf%etype ==
fe_tri3n )
then
661 write(*,*)
'### Error: MORTAR=YES supports first-order surfaces only (quad4/tri3) : etype=', surf%etype
662 stop hecmw_exit_model
664 allocate( surf%nodes(n) )
665 allocate( surf%nslave_index(n) )
666 surf%nodes(1:n)=nodes(1:n)
667 surf%nslave_index(:)= 0
669 allocate( surf%lam_begin_id(surf%n_intp), surf%lam_begin_val(n,surf%n_intp) )
670 allocate( surf%lam_work_id (surf%n_intp), surf%lam_work_val (n,surf%n_intp) )
671 surf%lam_begin_id(:) = 0; surf%lam_begin_val(:,:) = 0.0d0; surf%lam_begin_n = 0
672 surf%lam_work_id (:) = 0; surf%lam_work_val (:,:) = 0.0d0; surf%lam_work_n = 0
674 allocate( surf%lam_begin_t(2,n,surf%n_intp), surf%lam_work_t(2,n,surf%n_intp) )
675 allocate( surf%lam_begin_fstate(n,surf%n_intp), surf%lam_work_fstate(n,surf%n_intp) )
676 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.