32 subroutine getcontactstiffness_alag(cstate, tSurf, ele, mu, mut, fcoeff, symm, stiff, force, smoothing_type, edisp, iter, &
37 real(kind=kreal),
intent(in) :: ele(:,:)
38 real(kind=kreal),
intent(in) :: mu, mut
39 real(kind=kreal),
intent(in) :: fcoeff
40 logical,
intent(in) :: symm
41 real(kind=kreal),
intent(out) :: stiff(:,:)
42 real(kind=kreal),
intent(out) :: force(:)
43 integer(kind=kint),
optional,
intent(in) :: smoothing_type
44 real(kind=kreal),
optional,
intent(in) :: edisp(:)
45 integer(kind=kint),
intent(in) :: iter
46 real(kind=kreal),
intent(in) :: slvpos(3)
48 integer :: i, j, nnode
49 real(kind=kreal) :: bn(
size(tsurf%nodes)*3+3), ht(2,
size(tsurf%nodes)*3+3), gt(2,
size(tsurf%nodes)*3+3)
50 real(kind=kreal) :: metric(2,2)
51 real(kind=kreal) :: a(2,2)
52 real(kind=kreal) :: alpha_proj, that_dir(2)
53 real(kind=kreal) :: k_fric(
size(tsurf%nodes)*3+3,
size(tsurf%nodes)*3+3)
54 real(kind=kreal) :: tmp_vec(2)
55 real(kind=kreal) :: dummy_force(
size(tsurf%nodes)*3+3)
56 real(kind=kreal) :: eval_disp(
size(tsurf%nodes)*3+3)
57 real(kind=kreal) :: curpos(
size(tsurf%nodes)*3+3)
58 real(kind=kreal) :: lam_cone
59 real(kind=kreal) :: htt(
size(tsurf%nodes)*3+3)
60 real(kind=kreal) :: tdir(2)
61 real(kind=kreal) :: invmetric(2,2), det, norm_lamt
63 nnode =
size(tsurf%nodes)
71 stiff(i,j) = mu * bn(i) * bn(j)
74 force(1:nnode*3+3) = bn(:)
77 if( fcoeff /= 0.d0 )
then
79 if(
present(edisp) )
then
80 eval_disp(1:nnode*3+3) = edisp(1:nnode*3+3)
91 lam_cone = cstate%multiplier(1)
93 curpos(1:3) = slvpos(1:3) + eval_disp(1:3)
95 curpos(j*3+1:j*3+3) = ele(1:3,j) + eval_disp(j*3+1:j*3+3)
97 lam_cone = max( 0.d0, cstate%multiplier(1) + mu*dot_product( bn(1:nnode*3+3), curpos(1:nnode*3+3) ) )
101 ht, gt, eval_disp, nnode*3+3, dummy_force, &
102 mut, alpha=alpha_proj, that=that_dir)
105 if( lam_cone <= 0.0d0 .or. alpha_proj <= 1.0d-20 )
then
108 else if( alpha_proj >= 0.999d0 )
then
110 a(1,1) = mut * metric(1,1)
111 a(1,2) = mut * metric(1,2)
112 a(2,1) = mut * metric(2,1)
113 a(2,2) = mut * metric(2,2)
120 a(1,1) = alpha_proj * mut * metric(1,1)
121 a(1,2) = alpha_proj * mut * metric(1,2)
122 a(2,1) = alpha_proj * mut * metric(2,1)
123 a(2,2) = alpha_proj * mut * metric(2,2)
125 a(1,1) = alpha_proj * mut * (metric(1,1) - that_dir(1)*that_dir(1))
126 a(1,2) = alpha_proj * mut * (metric(1,2) - that_dir(1)*that_dir(2))
127 a(2,1) = alpha_proj * mut * (metric(2,1) - that_dir(2)*that_dir(1))
128 a(2,2) = alpha_proj * mut * (metric(2,2) - that_dir(2)*that_dir(2))
134 tmp_vec = matmul(a, ht(1:2,j))
136 k_fric(i,j) = dot_product(ht(1:2,i), tmp_vec)
147 if( .not.symm .and. lam_cone > 0.0d0 .and. alpha_proj > 1.0d-20 .and. alpha_proj < 0.999d0 )
then
151 tdir(1:2) = that_dir(1:2)
152 det = metric(1,1)*metric(2,2) - metric(1,2)*metric(2,1)
153 if( abs(det) > 1.0d-20 )
then
154 invmetric(1,1) = metric(2,2)/det
155 invmetric(2,2) = metric(1,1)/det
156 invmetric(1,2) = -metric(1,2)/det
157 invmetric(2,1) = -metric(2,1)/det
158 tmp_vec(1:2) = matmul( invmetric(1:2,1:2), cstate%multiplier(2:3) )
159 norm_lamt = dsqrt( dot_product( cstate%multiplier(2:3), tmp_vec(1:2) ) )
160 if( norm_lamt > 1.0d-20 ) tdir(1:2) = cstate%multiplier(2:3) / norm_lamt
162 htt(1:nnode*3+3) = matmul( transpose(ht(1:2,1:nnode*3+3)), tdir(1:2) )
165 k_fric(i,j) = k_fric(i,j) + fcoeff * mu * htt(i) * bn(j)
170 stiff(1:nnode*3+3,1:nnode*3+3) = stiff(1:nnode*3+3,1:nnode*3+3) + k_fric(1:nnode*3+3,1:nnode*3+3)
177 integer(kind=kint),
intent(out) :: maplist(:), master_idxs(:)
178 integer(kind=kint),
intent(out) :: unique_count
180 integer(kind=kint) :: i, j, n_intp, ctsurf
183 n_intp = ssurf%n_intp
190 ctsurf = ssurf%states(i)%surface
193 do j = 1, unique_count
194 if (tmp(j) == ctsurf)
then
200 if (.not. found)
then
201 unique_count = unique_count + 1
202 tmp(unique_count) = ctsurf
203 maplist(i) = unique_count
207 master_idxs(1:unique_count) = tmp(1:unique_count)
222 subroutine getintgap(slave_surf, master, coord, disp, ddisp, &
223 unique_count, maplist, master_idxs, &
224 Snode, Nsnode, gapwnode)
227 real(kind=kreal),
intent(in) :: coord(:), disp(:), ddisp(:)
228 integer(kind=kint),
intent(in) :: unique_count
229 integer(kind=kint),
intent(in) :: maplist(:), master_idxs(:)
230 real(kind=kreal),
intent(out) :: snode(:,:), nsnode(:,:,:), gapwnode(:,:)
232 integer(kind=kint) :: i, j, g, a, nnode_s, nnode_m, etype, slave, n_intp, ctsurf, nd
234 real(kind=kreal) :: snode_pos(3,4), weight(
max_n_intp)
235 real(kind=kreal) :: ncoord(2), shapefunc_s(4), shapefunc_m(4), direction(3)
236 real(kind=kreal) :: curr_pos(24)
238 nnode_s =
size(slave_surf%nodes)
247 slave = slave_surf%nodes(i)
248 snode_pos(:,i) = coord(3*slave-2:3*slave) + disp(3*slave-2:3*slave)
250 n_intp = slave_surf%n_intp
252 call get_intp_weights(slave_surf%etype, nnode_s, n_intp, snode_pos, weight(1:n_intp))
256 if( slave_surf%states(i)%state ==
contactfree ) cycle
257 ctsurf = slave_surf%states(i)%surface
258 etype = master(ctsurf)%etype
259 nnode_m =
size(master(ctsurf)%nodes)
260 direction = slave_surf%states(i)%direction(1:3)
261 call getintpoint4ss(slave_surf%etype, i, ncoord, n_intp, shapefunc_s)
262 call getshapefunc(etype, slave_surf%states(i)%lpos(1:2), shapefunc_m)
266 snode(g,a) = snode(g,a) + shapefunc_s(a)*weight(i)
268 nsnode(g,a,3*j-2:3*j) = nsnode(g,a,3*j-2:3*j) &
269 + shapefunc_s(a)*shapefunc_s(j)*weight(i)*direction(1:3)
271 do j = nnode_s+1, nnode_s+nnode_m
272 nsnode(g,a,3*j-2:3*j) = nsnode(g,a,3*j-2:3*j) &
273 - shapefunc_s(a)*shapefunc_m(j-nnode_s)*weight(i)*direction(1:3)
279 do g = 1, unique_count
280 ctsurf = master_idxs(g)
281 nnode_m =
size(master(ctsurf)%nodes)
282 ndlocal(1:nnode_s) = slave_surf%nodes(1:nnode_s)
283 ndlocal(nnode_s+1:nnode_s+nnode_m) = master(ctsurf)%nodes(1:nnode_m)
284 do j = 1, nnode_s + nnode_m
286 curr_pos(3*j-2:3*j) = coord(3*nd-2:3*nd) + disp(3*nd-2:3*nd) + ddisp(3*nd-2:3*nd)
290 gapwnode(g,a) = dot_product(nsnode(g,a,1:(nnode_s+nnode_m)*3), curr_pos(1:(nnode_s+nnode_m)*3))
291 if( snode(g,a) > 0.d0 )
then
292 nsnode(g,a,1:(nnode_s+nnode_m)*3) = nsnode(g,a,1:(nnode_s+nnode_m)*3) / snode(g,a)
294 nsnode(g,a,1:(nnode_s+nnode_m)*3) = 0.d0
309 real(kind=kreal),
intent(in) :: n_hat(3)
310 real(kind=kreal),
intent(out) :: t1(3), t2(3)
312 integer(kind=kint) :: k
313 real(kind=kreal) :: v(3), vn, dotk
317 if( abs(n_hat(2)) < abs(n_hat(k)) ) k = 2
318 if( abs(n_hat(3)) < abs(n_hat(k)) ) k = 3
322 v(1:3) = -dotk * n_hat(1:3)
325 vn = sqrt( v(1)*v(1) + v(2)*v(2) + v(3)*v(3) )
326 t1(1:3) = v(1:3) / vn
329 t2(1) = n_hat(2)*t1(3) - n_hat(3)*t1(2)
330 t2(2) = n_hat(3)*t1(1) - n_hat(1)*t1(3)
331 t2(3) = n_hat(1)*t1(2) - n_hat(2)*t1(1)
345 unique_count, maplist, master_idxs, Sigma_node, nacc_node)
348 real(kind=kreal),
intent(in) :: coord(:), disp(:), ddisp(:)
349 integer(kind=kint),
intent(in) :: unique_count
350 integer(kind=kint),
intent(in) :: maplist(:), master_idxs(:)
351 real(kind=kreal),
intent(out) :: sigma_node(:,:,:)
352 real(kind=kreal),
intent(out) :: nacc_node(:,:,:)
354 integer(kind=kint) :: i, j, g, a, nnode_s, nnode_m, etype, slave, n_intp, ctsurf, nd
355 real(kind=kreal) :: snode_pos(3,4), weight(
max_n_intp)
356 real(kind=kreal) :: ncoord(2), shapefunc_s(4), shapefunc_m(4), direction(3)
357 real(kind=kreal) :: du_rel(3), du_master(3)
359 nnode_s =
size(slave_surf%nodes)
367 slave = slave_surf%nodes(i)
368 snode_pos(:,i) = coord(3*slave-2:3*slave) + disp(3*slave-2:3*slave)
370 n_intp = slave_surf%n_intp
372 call get_intp_weights(slave_surf%etype, nnode_s, n_intp, snode_pos, weight(1:n_intp))
375 if( slave_surf%states(i)%state ==
contactfree ) cycle
376 ctsurf = slave_surf%states(i)%surface
377 etype = master(ctsurf)%etype
378 nnode_m =
size(master(ctsurf)%nodes)
379 direction = slave_surf%states(i)%direction(1:3)
380 call getintpoint4ss(slave_surf%etype, i, ncoord, n_intp, shapefunc_s)
381 call getshapefunc(etype, slave_surf%states(i)%lpos(1:2), shapefunc_m)
388 nd = slave_surf%nodes(j)
389 du_rel(1:3) = du_rel(1:3) + shapefunc_s(j) * ddisp(3*nd-2:3*nd)
391 du_master(1:3) = 0.d0
393 nd = master(ctsurf)%nodes(j)
394 du_master(1:3) = du_master(1:3) + shapefunc_m(j) * ddisp(3*nd-2:3*nd)
396 du_rel(1:3) = du_rel(1:3) - du_master(1:3)
400 sigma_node(g, a, 1:3) = sigma_node(g, a, 1:3) + shapefunc_s(a) * weight(i) * du_rel(1:3)
401 nacc_node(g, a, 1:3) = nacc_node(g, a, 1:3) + shapefunc_s(a) * weight(i) * direction(1:3)
414 lam_t_out, fric_state, alpha, that, update_state)
415 real(kind=kreal),
intent(in) :: lam_t_in(2)
416 real(kind=kreal),
intent(in) :: rho_t
417 real(kind=kreal),
intent(in) :: dxi(2)
418 real(kind=kreal),
intent(in) :: fcoeff
419 real(kind=kreal),
intent(in) :: lam_n
420 real(kind=kreal),
intent(in) :: eps_fric_band
421 real(kind=kreal),
intent(out) :: lam_t_out(2)
422 integer(kind=kint),
intent(inout) :: fric_state
423 real(kind=kreal),
intent(out) :: alpha
424 real(kind=kreal),
intent(out) :: that(2)
425 logical,
optional,
intent(in) :: update_state
427 real(kind=kreal) :: trial(2), norm_trial, radius
428 logical :: is_stick, do_update
431 if(
present(update_state) ) do_update = update_state
433 trial(1:2) = lam_t_in(1:2) + rho_t * dxi(1:2)
434 norm_trial = sqrt( trial(1)*trial(1) + trial(2)*trial(2) )
435 radius = fcoeff * lam_n
437 if( norm_trial > 1.0d-20 )
then
438 that(1:2) = trial(1:2) / norm_trial
443 if( lam_n <= 0.0d0 )
then
445 lam_t_out(1:2) = 0.0d0
447 else if( do_update )
then
455 if( norm_trial > (1.0d0 + eps_fric_band) * radius ) is_stick = .false.
457 if( norm_trial <= (1.0d0 - eps_fric_band) * radius ) is_stick = .true.
462 lam_t_out(1:2) = trial(1:2)
467 alpha = radius / norm_trial
468 lam_t_out(1:2) = alpha * trial(1:2)
479 lam_t_out(1:2) = trial(1:2)
490 if( norm_trial > 1.0d-20 )
then
491 alpha = min( 1.0d0, radius / norm_trial )
495 lam_t_out(1:2) = alpha * trial(1:2)
504 lambda_node, lam_t_cur, fric_state_cur )
506 integer(kind=kint),
intent(in) :: master_idxs(:)
507 integer(kind=kint),
intent(in) :: unique_count
508 integer(kind=kint),
intent(in) :: nnode_s
509 integer(kind=kint),
intent(out) :: sorted_idx(:)
510 real(kind=kreal),
intent(out) :: lambda_node(:,:)
513 real(kind=kreal),
intent(out),
optional :: lam_t_cur(:,:,:)
514 integer(kind=kint),
intent(out),
optional :: fric_state_cur(:,:)
515 integer(kind=kint) :: r, j, tmp, ib, iw, g, mid
519 do r = 1, unique_count
522 do r = 2, unique_count
526 if( master_idxs(sorted_idx(j)) <= master_idxs(tmp) )
exit
527 sorted_idx(j+1) = sorted_idx(j)
530 sorted_idx(j+1) = tmp
533 do_fric =
present(lam_t_cur) .and.
present(fric_state_cur)
537 do r = 1, unique_count
538 mid = master_idxs(sorted_idx(r))
539 do while( ib <= surf%lam_begin_n .and. surf%lam_begin_id(ib) < mid ); ib = ib + 1;
enddo
540 do while( iw <= surf%lam_work_n .and. surf%lam_work_id(iw) < mid ); iw = iw + 1;
enddo
542 if( iw <= surf%lam_work_n .and. surf%lam_work_id(iw) == mid )
then
543 lambda_node(1:nnode_s,g) = surf%lam_work_val(1:nnode_s,iw)
545 lam_t_cur(1:2,1:nnode_s,g) = surf%lam_work_t(1:2,1:nnode_s,iw)
546 fric_state_cur(1:nnode_s,g) = surf%lam_work_fstate(1:nnode_s,iw)
548 else if( ib <= surf%lam_begin_n .and. surf%lam_begin_id(ib) == mid )
then
549 lambda_node(1:nnode_s,g) = surf%lam_begin_val(1:nnode_s,ib)
551 lam_t_cur(1:2,1:nnode_s,g) = surf%lam_begin_t(1:2,1:nnode_s,ib)
552 fric_state_cur(1:nnode_s,g) = surf%lam_begin_fstate(1:nnode_s,ib)
555 lambda_node(1:nnode_s,g) = 0.d0
557 lam_t_cur(1:2,1:nnode_s,g) = 0.d0
578 mu, mut, fcoeff, symm, eps_fric_band, unique_count, maplist, master_idxs, &
579 stiff_n, active_n, stiff_t, active_t )
582 real(kind=kreal),
intent(in) :: coord(:)
583 real(kind=kreal),
intent(in) :: disp(:)
584 real(kind=kreal),
intent(in) :: ddisp(:)
585 real(kind=kreal),
intent(in) :: mu, mut
586 real(kind=kreal),
intent(in) :: fcoeff
587 logical,
intent(in) :: symm
588 real(kind=kreal),
intent(in) :: eps_fric_band
589 integer(kind=kint),
intent(in) :: unique_count
590 integer(kind=kint),
intent(in) :: maplist(:)
591 integer(kind=kint),
intent(in) :: master_idxs(:)
592 real(kind=kreal),
intent(out) :: stiff_n(:,:,:,:)
593 logical,
intent(out) :: active_n(:,:)
594 real(kind=kreal),
intent(out),
optional :: stiff_t(:,:,:,:)
595 logical,
intent(out),
optional :: active_t(:,:)
597 integer(kind=kint) :: g, a, j, k, nnode_m, nnode_s
598 integer(kind=kint),
allocatable :: sorted_idx(:)
599 real(kind=kreal),
allocatable :: snode(:,:), nsnode(:,:,:), gapwnode(:,:), lambda_node(:,:)
600 real(kind=kreal) :: ns(24)
602 real(kind=kreal),
allocatable :: lam_t_cur(:,:,:), nacc_node(:,:,:), sigma_node(:,:,:)
603 integer(kind=kint),
allocatable :: fric_state_cur(:,:)
604 real(kind=kreal) :: nhat(3), t1(3), t2(3), nrm, dxi(2)
605 real(kind=kreal) :: alpha, that(2), lam_t_new(2), amat(2,2), t3d(3,2), m3(3,3)
607 real(kind=kreal) :: lam_cone, that3d(3)
608 integer(kind=kint) :: na, nb, fstate
610 nnode_s =
size(slave_surf%nodes)
611 allocate(snode(unique_count,nnode_s), nsnode(unique_count,nnode_s,24), gapwnode(unique_count,nnode_s))
612 call getintgap(slave_surf, master, coord, disp, ddisp, &
613 unique_count, maplist, master_idxs, &
614 snode, nsnode, gapwnode)
616 allocate(sorted_idx(unique_count), lambda_node(nnode_s,unique_count))
619 if( fcoeff /= 0.d0 )
then
620 allocate(lam_t_cur(2,nnode_s,unique_count), fric_state_cur(nnode_s,unique_count))
622 lambda_node, lam_t_cur, fric_state_cur)
629 do g = 1, unique_count
630 nnode_m =
size(master(master_idxs(g))%nodes)
633 if( lambda_node(a,g)+mu*gapwnode(g,a) < 0.d0 ) cycle
634 active_n(a,g) = .true.
636 ns(1:(nnode_s+nnode_m)*3) = nsnode(g, a, 1:(nnode_s+nnode_m)*3)
637 do j = 1, (nnode_s+nnode_m)*3
638 do k = 1, (nnode_s+nnode_m)*3
639 stiff_n(j,k,a,g) = mu*snode(g,a)*ns(j)*ns(k)
645 if( fcoeff /= 0.d0 )
then
652 allocate(sigma_node(unique_count,nnode_s,3), nacc_node(unique_count,nnode_s,3))
654 unique_count, maplist, master_idxs, sigma_node, nacc_node)
655 do g = 1, unique_count
656 nnode_m =
size(master(master_idxs(g))%nodes)
658 if( lambda_node(a,g) <= 0.d0 ) cycle
665 lam_cone = lambda_node(a,g)
667 lam_cone = lambda_node(a,g) + mu*gapwnode(g,a)
669 nrm = sqrt( nacc_node(g,a,1)**2 + nacc_node(g,a,2)**2 + nacc_node(g,a,3)**2 )
670 if( nrm < 1.d-30 ) cycle
671 nhat(1:3) = nacc_node(g,a,1:3) / nrm
674 dxi(1) = dot_product(t1(1:3), sigma_node(g,a,1:3))
675 dxi(2) = dot_product(t2(1:3), sigma_node(g,a,1:3))
676 fstate = fric_state_cur(a,g)
678 eps_fric_band, lam_t_new, fstate, alpha, that)
680 if( alpha <= 1.0d-20 )
then
682 else if( alpha >= 0.999d0 )
then
687 amat(1,1) = alpha * mut * (1.0d0 - that(1)*that(1))
688 amat(1,2) = alpha * mut * (-that(1)*that(2))
689 amat(2,1) = alpha * mut * (-that(2)*that(1))
690 amat(2,2) = alpha * mut * (1.0d0 - that(2)*that(2))
694 m3 = matmul( matmul(t3d, amat), transpose(t3d) )
697 do na = 1, nnode_s + nnode_m
698 wb(na) = dot_product(nsnode(g,a,3*na-2:3*na), nhat(1:3))
700 active_t(a,g) = .true.
701 do nb = 1, nnode_s + nnode_m
702 do na = 1, nnode_s + nnode_m
705 stiff_t(3*na-3+j, 3*nb-3+k, a, g) = snode(g,a) * wb(na) * wb(nb) * m3(j,k)
719 if( .not.symm .and. alpha > 1.0d-20 .and. alpha < 0.999d0 )
then
720 that3d(1:3) = that(1)*t1(1:3) + that(2)*t2(1:3)
721 do nb = 1, nnode_s + nnode_m
722 do na = 1, nnode_s + nnode_m
725 stiff_t(3*na-3+j, 3*nb-3+k, a, g) = stiff_t(3*na-3+j, 3*nb-3+k, a, g) &
726 + fcoeff * mu * snode(g,a) * wb(na) * that3d(j) * nsnode(g,a,3*nb-3+k)
735 deallocate(sigma_node, nacc_node, lam_t_cur, fric_state_cur)
738 deallocate(sorted_idx)
739 deallocate(snode, nsnode, gapwnode, lambda_node)
755 mu, mut, fcoeff, symm, eps_fric_band, unique_count, maplist, master_idxs, &
756 ctNForce, active_n, ctTForce, active_t )
757 integer(kind=kint),
intent(in) :: purpose
760 real(kind=kreal),
intent(in) :: coord(:)
761 real(kind=kreal),
intent(in) :: disp(:)
762 real(kind=kreal),
intent(in) :: ddisp(:)
763 real(kind=kreal),
intent(in) :: mu, mut
764 real(kind=kreal),
intent(in) :: fcoeff
765 logical,
intent(in) :: symm
766 real(kind=kreal),
intent(in) :: eps_fric_band
767 integer(kind=kint),
intent(in) :: unique_count
768 integer(kind=kint),
intent(in) :: maplist(:)
769 integer(kind=kint),
intent(in) :: master_idxs(:)
770 real(kind=kreal),
intent(out) :: ctnforce(:,:,:)
771 logical,
intent(out) :: active_n(:,:)
772 real(kind=kreal),
intent(out),
optional :: cttforce(:,:,:)
773 logical,
intent(out),
optional :: active_t(:,:)
775 integer(kind=kint) :: g, a, j, nnode_m, nnode_s
776 integer(kind=kint),
allocatable :: sorted_idx(:)
777 real(kind=kreal),
allocatable :: snode(:,:), nsnode(:,:,:), gapwnode(:,:), lambda_node(:,:)
778 real(kind=kreal) :: nrlforce
779 real(kind=kreal) :: ns(24)
781 real(kind=kreal),
allocatable :: lam_t_cur(:,:,:), nacc_node(:,:,:), sigma_node(:,:,:)
782 integer(kind=kint),
allocatable :: fric_state_cur(:,:)
783 real(kind=kreal) :: nhat(3), t1(3), t2(3), nrm, fvec(3), wbar
784 real(kind=kreal) :: dxi(2), alpha, that(2), lam_t_new(2), lam_cone
785 integer(kind=kint) :: fstate
787 nnode_s =
size(slave_surf%nodes)
788 allocate(snode(unique_count,nnode_s), nsnode(unique_count,nnode_s,24), gapwnode(unique_count,nnode_s))
789 call getintgap(slave_surf, master, coord, disp, ddisp, &
790 unique_count, maplist, master_idxs, &
791 snode, nsnode, gapwnode)
793 allocate(sorted_idx(unique_count), lambda_node(nnode_s,unique_count))
796 if( fcoeff /= 0.d0 )
then
797 allocate(lam_t_cur(2,nnode_s,unique_count), fric_state_cur(nnode_s,unique_count))
799 lambda_node, lam_t_cur, fric_state_cur)
807 do g = 1, unique_count
808 nnode_m =
size(master(master_idxs(g))%nodes)
810 nrlforce = lambda_node(a,g) + mu*gapwnode(g,a)
812 if( nrlforce < 0.d0 ) cycle
813 active_n(a,g) = .true.
815 ns(1:(nnode_s+nnode_m)*3) = nsnode(g, a, 1:(nnode_s+nnode_m)*3)
816 do j = 1, nnode_s + nnode_m
818 ctnforce(3*j-2:3*j,a,g) = -nrlforce*ns(3*j-2:3*j)
821 ctnforce(3*j-2:3*j,a,g) = -lambda_node(a,g)*ns(3*j-2:3*j)
827 if( fcoeff /= 0.d0 )
then
836 allocate(sigma_node(unique_count,nnode_s,3), nacc_node(unique_count,nnode_s,3))
838 unique_count, maplist, master_idxs, sigma_node, nacc_node)
839 do g = 1, unique_count
840 nnode_m =
size(master(master_idxs(g))%nodes)
842 if( lambda_node(a,g) <= 0.d0 ) cycle
849 lam_cone = lambda_node(a,g)
851 lam_cone = lambda_node(a,g) + mu*gapwnode(g,a)
853 nrm = sqrt( nacc_node(g,a,1)**2 + nacc_node(g,a,2)**2 + nacc_node(g,a,3)**2 )
854 if( nrm < 1.d-30 ) cycle
855 nhat(1:3) = nacc_node(g,a,1:3) / nrm
859 dxi(1) = dot_product(t1(1:3), sigma_node(g,a,1:3))
860 dxi(2) = dot_product(t2(1:3), sigma_node(g,a,1:3))
861 fstate = fric_state_cur(a,g)
863 eps_fric_band, lam_t_new, fstate, alpha, that)
864 fvec(1:3) = lam_t_new(1)*t1(1:3) + lam_t_new(2)*t2(1:3)
867 fvec(1:3) = lam_t_cur(1,a,g)*t1(1:3) + lam_t_cur(2,a,g)*t2(1:3)
870 active_t(a,g) = .true.
871 do j = 1, nnode_s + nnode_m
873 wbar = dot_product(nsnode(g,a,3*j-2:3*j), nhat(1:3))
874 cttforce(3*j-2:3*j,a,g) = -fvec(1:3) * wbar
879 deallocate(sigma_node, nacc_node, lam_t_cur, fric_state_cur)
882 deallocate(sorted_idx)
883 deallocate(snode, nsnode, gapwnode, lambda_node)
886 subroutine getcontactnodalforce_alag(ctState,tSurf,ndCoord,ndDu,mu,mut,fcoeff,symm,lagrange,ctNForce,ctTForce,cflag, &
892 integer(kind=kint) :: nnode
893 integer(kind=kint) :: j
894 real(kind=kreal),
intent(in) :: mu, mut
895 real(kind=kreal) :: fcoeff
896 logical,
intent(in) :: symm
897 real(kind=kreal) :: lagrange
898 real(kind=kreal) :: ndcoord(:), nddu(:)
899 real(kind=kreal) :: ctnforce(:)
900 real(kind=kreal) :: cttforce(:)
902 integer(kind=kint),
optional,
intent(in) :: smoothing_type
904 real(kind=kreal) :: normal(3)
909 real(kind=kreal) :: dgn, nrlforce
910 real(kind=kreal) :: lam_cone
911 real(kind=kreal) :: metric(2,2)
912 integer(kind=kint) :: edof
914 nnode =
size(tsurf%nodes)
920 normal(1:3) = ctstate%direction(1:3)
924 elemcrd(1:3, j) = ndcoord(j*3+1:j*3+3) - nddu(j*3+1:j*3+3)
929 bn, metric, ht, gt, smoothing_type)
932 dgn = dot_product( bn(1:edof), ndcoord(1:edof) )
935 nrlforce = ctstate%multiplier(1) + mu*dgn
938 ctnforce(1:edof) = -nrlforce * bn(1:edof)
941 ctnforce((nnode+1)*3+1) = 0.d0
943 if( fcoeff == 0.d0 )
return
948 edisp(1:3) = nddu(1:3)
950 edisp(j*3+1:j*3+3) = nddu(j*3+1:j*3+3)
957 lam_cone = ctstate%multiplier(1)
959 lam_cone = max( 0.d0, nrlforce )
962 ht, gt, edisp, edof, cttforce, &
966 cttforce((nnode+1)*3+1) = 0.d0
971 & mu,mut,fcoeff,tSurf,lgnt,ctchanged,ctNForce,ctTForce,jump_ratio,smoothing_type)
974 integer(kind=kint),
intent(in) :: ndlocal(:)
975 real(kind=kreal),
intent(in) :: coord(:)
976 real(kind=kreal),
intent(in) :: disp(:)
977 real(kind=kreal),
intent(in) :: ddisp(:)
978 real(kind=kreal),
intent(in) :: mu, mut
979 real(kind=kreal),
intent(in) :: fcoeff
981 real(kind=kreal),
intent(inout) :: lgnt(2)
982 logical,
intent(inout) :: ctchanged
983 real(kind=kreal),
intent(out) :: ctnforce(:)
984 real(kind=kreal),
intent(out) :: cttforce(:)
985 real(kind=kreal),
intent(out) :: jump_ratio
986 integer(kind=kint),
optional,
intent(in) :: smoothing_type
988 integer(kind=kint) :: nnode
989 integer(kind=kint) :: slave, j
995 real(kind=kreal) :: dgn, nrlforce
996 real(kind=kreal) :: metric(2,2)
997 real(kind=kreal) :: dxy(2)
998 integer(kind=kint) :: edof
1000 nnode =
size(ndlocal) - 1
1008 curpos(1:3) = coord(3*slave-2:3*slave) + disp(3*slave-2:3*slave) + ddisp(3*slave-2:3*slave)
1009 edisp(1:3) = ddisp(3*slave-2:3*slave)
1011 elemcrd(1:3,j) = coord(3*ndlocal(j+1)-2:3*ndlocal(j+1)) + disp(3*ndlocal(j+1)-2:3*ndlocal(j+1))
1012 curpos(j*3+1:j*3+3) = elemcrd(1:3,j) + ddisp(3*ndlocal(j+1)-2:3*ndlocal(j+1))
1013 edisp(j*3+1:j*3+3) = ddisp(3*ndlocal(j+1)-2:3*ndlocal(j+1))
1018 bn, metric, ht, gt, smoothing_type)
1021 dgn = dot_product( bn(1:edof), curpos(1:edof) )
1024 ctstate%wkdist = -dgn
1025 ctstate%multiplier(1) = ctstate%multiplier(1) - mu*ctstate%wkdist
1026 ctstate%distance = ctstate%wkdist
1027 lgnt(1) = lgnt(1) - ctstate%wkdist
1030 nrlforce = ctstate%multiplier(1)
1033 ctnforce(1:edof) = -nrlforce * bn(1:edof)
1035 if( fcoeff == 0.d0 )
return
1042 ht, gt, edisp, edof, cttforce, &
1044 update_multiplier=.true., slave_id=slave, ctchanged=ctchanged, &
1045 jump_ratio=jump_ratio)
1048 dxy = matmul( gt(:,1:edof), curpos(1:edof) )
1049 lgnt(2) = lgnt(2) + dsqrt( dxy(1)*dxy(1) + dxy(2)*dxy(2) )
1057 real(kind=kreal),
intent(in) :: mu
1058 real(kind=kreal),
intent(out) :: stiff(:,:)
1059 real(kind=kreal),
intent(out) :: force(:)
1061 integer :: i, j, nnode, edof
1065 nnode =
size(tsurf%nodes)
1076 stiff(i,j) = mu * dot_product(tm(1:3,i), tm(1:3,j))
1079 force(1:edof) = 0.d0
1088 integer(kind=kint) :: nnode
1089 real(kind=kreal) :: ndu(:)
1090 real(kind=kreal),
intent(in) :: mu
1091 real(kind=kreal) :: ctnforce(:)
1092 real(kind=kreal) :: cttforce(:)
1094 integer(kind=kint) :: edof
1097 real(kind=kreal) :: dg(3)
1098 real(kind=kreal) :: nrlforce(3)
1100 nnode =
size(tsurf%nodes)
1110 dg(1:3) = matmul(tm(1:3, 1:edof), ndu(1:edof))
1113 nrlforce(1:3) = ctstate%multiplier(1:3) + mu*dg(1:3)
1116 ctnforce(1:edof) = -matmul(transpose(tm(1:3, 1:edof)), nrlforce(1:3))
1119 ctnforce((nnode+1)*3+1) = 0.d0
1120 cttforce((nnode+1)*3+1) = 0.d0
This module encapsulate the basic functions of all elements provide by this software.
subroutine getshapefunc(fetype, localcoord, func)
Calculate the shape function in natural coordinate system.
subroutine get_intp_weights(etype, nn, n_intp, elecoord, weight)
subroutine getintpoint4ss(fetype, np, pos, n_intp, shapefunc)
This module manages surface elements in 3D It provides basic definition of surface elements (triangla...
integer(kind=kint), parameter l_max_elem_node
integer(kind=kint), parameter l_max_surface_node
Structure to define surface group.