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 maplist, Sigma_node, nacc_node)
348 real(kind=kreal),
intent(in) :: coord(:), disp(:), ddisp(:)
349 integer(kind=kint),
intent(in) :: maplist(:)
350 real(kind=kreal),
intent(out) :: sigma_node(:,:,:)
351 real(kind=kreal),
intent(out) :: nacc_node(:,:,:)
353 integer(kind=kint) :: i, j, g, a, nnode_s, nnode_m, etype, slave, n_intp, ctsurf, nd
354 real(kind=kreal) :: snode_pos(3,4), weight(
max_n_intp)
355 real(kind=kreal) :: ncoord(2), shapefunc_s(4), shapefunc_m(4), direction(3)
356 real(kind=kreal) :: du_rel(3), du_master(3)
358 nnode_s =
size(slave_surf%nodes)
366 slave = slave_surf%nodes(i)
367 snode_pos(:,i) = coord(3*slave-2:3*slave) + disp(3*slave-2:3*slave)
369 n_intp = slave_surf%n_intp
371 call get_intp_weights(slave_surf%etype, nnode_s, n_intp, snode_pos, weight(1:n_intp))
374 if( slave_surf%states(i)%state ==
contactfree ) cycle
375 ctsurf = slave_surf%states(i)%surface
376 etype = master(ctsurf)%etype
377 nnode_m =
size(master(ctsurf)%nodes)
378 direction = slave_surf%states(i)%direction(1:3)
379 call getintpoint4ss(slave_surf%etype, i, ncoord, n_intp, shapefunc_s)
380 call getshapefunc(etype, slave_surf%states(i)%lpos(1:2), shapefunc_m)
387 nd = slave_surf%nodes(j)
388 du_rel(1:3) = du_rel(1:3) + shapefunc_s(j) * ddisp(3*nd-2:3*nd)
390 du_master(1:3) = 0.d0
392 nd = master(ctsurf)%nodes(j)
393 du_master(1:3) = du_master(1:3) + shapefunc_m(j) * ddisp(3*nd-2:3*nd)
395 du_rel(1:3) = du_rel(1:3) - du_master(1:3)
399 sigma_node(g, a, 1:3) = sigma_node(g, a, 1:3) + shapefunc_s(a) * weight(i) * du_rel(1:3)
400 nacc_node(g, a, 1:3) = nacc_node(g, a, 1:3) + shapefunc_s(a) * weight(i) * direction(1:3)
413 lam_t_out, fric_state, alpha, that, update_state)
414 real(kind=kreal),
intent(in) :: lam_t_in(2)
415 real(kind=kreal),
intent(in) :: rho_t
416 real(kind=kreal),
intent(in) :: dxi(2)
417 real(kind=kreal),
intent(in) :: fcoeff
418 real(kind=kreal),
intent(in) :: lam_n
419 real(kind=kreal),
intent(in) :: eps_fric_band
420 real(kind=kreal),
intent(out) :: lam_t_out(2)
421 integer(kind=kint),
intent(inout) :: fric_state
422 real(kind=kreal),
intent(out) :: alpha
423 real(kind=kreal),
intent(out) :: that(2)
424 logical,
optional,
intent(in) :: update_state
426 real(kind=kreal) :: trial(2), norm_trial, radius
427 logical :: is_stick, do_update
430 if(
present(update_state) ) do_update = update_state
432 trial(1:2) = lam_t_in(1:2) + rho_t * dxi(1:2)
433 norm_trial = sqrt( trial(1)*trial(1) + trial(2)*trial(2) )
434 radius = fcoeff * lam_n
436 if( norm_trial > 1.0d-20 )
then
437 that(1:2) = trial(1:2) / norm_trial
442 if( lam_n <= 0.0d0 )
then
444 lam_t_out(1:2) = 0.0d0
446 else if( do_update )
then
454 if( norm_trial > (1.0d0 + eps_fric_band) * radius ) is_stick = .false.
456 if( norm_trial <= (1.0d0 - eps_fric_band) * radius ) is_stick = .true.
461 lam_t_out(1:2) = trial(1:2)
466 alpha = radius / norm_trial
467 lam_t_out(1:2) = alpha * trial(1:2)
478 lam_t_out(1:2) = trial(1:2)
489 if( norm_trial > 1.0d-20 )
then
490 alpha = min( 1.0d0, radius / norm_trial )
494 lam_t_out(1:2) = alpha * trial(1:2)
503 lambda_node, lam_t_cur, fric_state_cur )
505 integer(kind=kint),
intent(in) :: master_idxs(:)
506 integer(kind=kint),
intent(in) :: unique_count
507 integer(kind=kint),
intent(in) :: nnode_s
508 integer(kind=kint),
intent(out) :: sorted_idx(:)
509 real(kind=kreal),
intent(out) :: lambda_node(:,:)
512 real(kind=kreal),
intent(out),
optional :: lam_t_cur(:,:,:)
513 integer(kind=kint),
intent(out),
optional :: fric_state_cur(:,:)
514 integer(kind=kint) :: r, j, tmp, ib, iw, g, mid
515 logical :: do_fric, hit_work, hit_begin
518 do r = 1, unique_count
521 do r = 2, unique_count
525 if( master_idxs(sorted_idx(j)) <= master_idxs(tmp) )
exit
526 sorted_idx(j+1) = sorted_idx(j)
529 sorted_idx(j+1) = tmp
532 do_fric =
present(lam_t_cur) .and.
present(fric_state_cur)
536 do r = 1, unique_count
537 mid = master_idxs(sorted_idx(r))
538 do while( ib <= surf%lam_begin_n )
539 if( surf%lam_begin_id(ib) >= mid )
exit
542 do while( iw <= surf%lam_work_n )
543 if( surf%lam_work_id(iw) >= mid )
exit
548 if( iw <= surf%lam_work_n ) hit_work = surf%lam_work_id(iw) == mid
550 if( ib <= surf%lam_begin_n ) hit_begin = surf%lam_begin_id(ib) == mid
552 lambda_node(1:nnode_s,g) = surf%lam_work_val(1:nnode_s,iw)
554 lam_t_cur(1:2,1:nnode_s,g) = surf%lam_work_t(1:2,1:nnode_s,iw)
555 fric_state_cur(1:nnode_s,g) = surf%lam_work_fstate(1:nnode_s,iw)
557 else if( hit_begin )
then
558 lambda_node(1:nnode_s,g) = surf%lam_begin_val(1:nnode_s,ib)
560 lam_t_cur(1:2,1:nnode_s,g) = surf%lam_begin_t(1:2,1:nnode_s,ib)
561 fric_state_cur(1:nnode_s,g) = surf%lam_begin_fstate(1:nnode_s,ib)
564 lambda_node(1:nnode_s,g) = 0.d0
566 lam_t_cur(1:2,1:nnode_s,g) = 0.d0
587 mu, mut, fcoeff, symm, eps_fric_band, unique_count, maplist, master_idxs, &
588 stiff_n, active_n, stiff_t, active_t )
591 real(kind=kreal),
intent(in) :: coord(:)
592 real(kind=kreal),
intent(in) :: disp(:)
593 real(kind=kreal),
intent(in) :: ddisp(:)
594 real(kind=kreal),
intent(in) :: mu, mut
595 real(kind=kreal),
intent(in) :: fcoeff
596 logical,
intent(in) :: symm
597 real(kind=kreal),
intent(in) :: eps_fric_band
598 integer(kind=kint),
intent(in) :: unique_count
599 integer(kind=kint),
intent(in) :: maplist(:)
600 integer(kind=kint),
intent(in) :: master_idxs(:)
601 real(kind=kreal),
intent(out) :: stiff_n(:,:,:,:)
602 logical,
intent(out) :: active_n(:,:)
603 real(kind=kreal),
intent(out),
optional :: stiff_t(:,:,:,:)
604 logical,
intent(out),
optional :: active_t(:,:)
606 integer(kind=kint) :: g, a, j, k, nnode_m, nnode_s
607 integer(kind=kint),
allocatable :: sorted_idx(:)
608 real(kind=kreal),
allocatable :: snode(:,:), nsnode(:,:,:), gapwnode(:,:), lambda_node(:,:)
609 real(kind=kreal) :: ns(24)
611 real(kind=kreal),
allocatable :: lam_t_cur(:,:,:), nacc_node(:,:,:), sigma_node(:,:,:)
612 integer(kind=kint),
allocatable :: fric_state_cur(:,:)
613 real(kind=kreal) :: nhat(3), t1(3), t2(3), nrm, dxi(2)
614 real(kind=kreal) :: alpha, that(2), lam_t_new(2), amat(2,2), t3d(3,2), m3(3,3)
616 real(kind=kreal) :: lam_cone, that3d(3)
617 integer(kind=kint) :: na, nb, fstate
619 nnode_s =
size(slave_surf%nodes)
620 allocate(snode(unique_count,nnode_s), nsnode(unique_count,nnode_s,24), gapwnode(unique_count,nnode_s))
621 call getintgap(slave_surf, master, coord, disp, ddisp, &
622 unique_count, maplist, master_idxs, &
623 snode, nsnode, gapwnode)
625 allocate(sorted_idx(unique_count), lambda_node(nnode_s,unique_count))
628 if( fcoeff /= 0.d0 )
then
629 allocate(lam_t_cur(2,nnode_s,unique_count), fric_state_cur(nnode_s,unique_count))
631 lambda_node, lam_t_cur, fric_state_cur)
638 do g = 1, unique_count
639 nnode_m =
size(master(master_idxs(g))%nodes)
642 if( lambda_node(a,g)+mu*gapwnode(g,a) < 0.d0 ) cycle
643 active_n(a,g) = .true.
645 ns(1:(nnode_s+nnode_m)*3) = nsnode(g, a, 1:(nnode_s+nnode_m)*3)
646 do j = 1, (nnode_s+nnode_m)*3
647 do k = 1, (nnode_s+nnode_m)*3
648 stiff_n(j,k,a,g) = mu*snode(g,a)*ns(j)*ns(k)
654 if( fcoeff /= 0.d0 )
then
661 allocate(sigma_node(unique_count,nnode_s,3), nacc_node(unique_count,nnode_s,3))
663 maplist, sigma_node, nacc_node)
664 do g = 1, unique_count
665 nnode_m =
size(master(master_idxs(g))%nodes)
667 if( lambda_node(a,g) <= 0.d0 ) cycle
674 lam_cone = lambda_node(a,g)
676 lam_cone = lambda_node(a,g) + mu*gapwnode(g,a)
678 nrm = sqrt( nacc_node(g,a,1)**2 + nacc_node(g,a,2)**2 + nacc_node(g,a,3)**2 )
679 if( nrm < 1.d-30 ) cycle
680 nhat(1:3) = nacc_node(g,a,1:3) / nrm
683 dxi(1) = dot_product(t1(1:3), sigma_node(g,a,1:3))
684 dxi(2) = dot_product(t2(1:3), sigma_node(g,a,1:3))
685 fstate = fric_state_cur(a,g)
687 eps_fric_band, lam_t_new, fstate, alpha, that)
689 if( alpha <= 1.0d-20 )
then
691 else if( alpha >= 0.999d0 )
then
696 amat(1,1) = alpha * mut * (1.0d0 - that(1)*that(1))
697 amat(1,2) = alpha * mut * (-that(1)*that(2))
698 amat(2,1) = alpha * mut * (-that(2)*that(1))
699 amat(2,2) = alpha * mut * (1.0d0 - that(2)*that(2))
703 m3 = matmul( matmul(t3d, amat), transpose(t3d) )
706 do na = 1, nnode_s + nnode_m
707 wb(na) = dot_product(nsnode(g,a,3*na-2:3*na), nhat(1:3))
709 active_t(a,g) = .true.
710 do nb = 1, nnode_s + nnode_m
711 do na = 1, nnode_s + nnode_m
714 stiff_t(3*na-3+j, 3*nb-3+k, a, g) = snode(g,a) * wb(na) * wb(nb) * m3(j,k)
728 if( .not.symm .and. alpha > 1.0d-20 .and. alpha < 0.999d0 )
then
729 that3d(1:3) = that(1)*t1(1:3) + that(2)*t2(1:3)
730 do nb = 1, nnode_s + nnode_m
731 do na = 1, nnode_s + nnode_m
734 stiff_t(3*na-3+j, 3*nb-3+k, a, g) = stiff_t(3*na-3+j, 3*nb-3+k, a, g) &
735 + fcoeff * mu * snode(g,a) * wb(na) * that3d(j) * nsnode(g,a,3*nb-3+k)
744 deallocate(sigma_node, nacc_node, lam_t_cur, fric_state_cur)
747 deallocate(sorted_idx)
748 deallocate(snode, nsnode, gapwnode, lambda_node)
764 mu, mut, fcoeff, symm, eps_fric_band, unique_count, maplist, master_idxs, &
765 ctNForce, active_n, ctTForce, active_t )
766 integer(kind=kint),
intent(in) :: purpose
769 real(kind=kreal),
intent(in) :: coord(:)
770 real(kind=kreal),
intent(in) :: disp(:)
771 real(kind=kreal),
intent(in) :: ddisp(:)
772 real(kind=kreal),
intent(in) :: mu, mut
773 real(kind=kreal),
intent(in) :: fcoeff
774 logical,
intent(in) :: symm
775 real(kind=kreal),
intent(in) :: eps_fric_band
776 integer(kind=kint),
intent(in) :: unique_count
777 integer(kind=kint),
intent(in) :: maplist(:)
778 integer(kind=kint),
intent(in) :: master_idxs(:)
779 real(kind=kreal),
intent(out) :: ctnforce(:,:,:)
780 logical,
intent(out) :: active_n(:,:)
781 real(kind=kreal),
intent(out),
optional :: cttforce(:,:,:)
782 logical,
intent(out),
optional :: active_t(:,:)
784 integer(kind=kint) :: g, a, j, nnode_m, nnode_s
785 integer(kind=kint),
allocatable :: sorted_idx(:)
786 real(kind=kreal),
allocatable :: snode(:,:), nsnode(:,:,:), gapwnode(:,:), lambda_node(:,:)
787 real(kind=kreal) :: nrlforce
788 real(kind=kreal) :: ns(24)
790 real(kind=kreal),
allocatable :: lam_t_cur(:,:,:), nacc_node(:,:,:), sigma_node(:,:,:)
791 integer(kind=kint),
allocatable :: fric_state_cur(:,:)
792 real(kind=kreal) :: nhat(3), t1(3), t2(3), nrm, fvec(3), wbar
793 real(kind=kreal) :: dxi(2), alpha, that(2), lam_t_new(2), lam_cone
794 integer(kind=kint) :: fstate
796 nnode_s =
size(slave_surf%nodes)
797 allocate(snode(unique_count,nnode_s), nsnode(unique_count,nnode_s,24), gapwnode(unique_count,nnode_s))
798 call getintgap(slave_surf, master, coord, disp, ddisp, &
799 unique_count, maplist, master_idxs, &
800 snode, nsnode, gapwnode)
802 allocate(sorted_idx(unique_count), lambda_node(nnode_s,unique_count))
805 if( fcoeff /= 0.d0 )
then
806 allocate(lam_t_cur(2,nnode_s,unique_count), fric_state_cur(nnode_s,unique_count))
808 lambda_node, lam_t_cur, fric_state_cur)
816 do g = 1, unique_count
817 nnode_m =
size(master(master_idxs(g))%nodes)
819 nrlforce = lambda_node(a,g) + mu*gapwnode(g,a)
821 if( nrlforce < 0.d0 ) cycle
822 active_n(a,g) = .true.
824 ns(1:(nnode_s+nnode_m)*3) = nsnode(g, a, 1:(nnode_s+nnode_m)*3)
825 do j = 1, nnode_s + nnode_m
827 ctnforce(3*j-2:3*j,a,g) = -nrlforce*ns(3*j-2:3*j)
830 ctnforce(3*j-2:3*j,a,g) = -lambda_node(a,g)*ns(3*j-2:3*j)
836 if( fcoeff /= 0.d0 )
then
845 allocate(sigma_node(unique_count,nnode_s,3), nacc_node(unique_count,nnode_s,3))
847 maplist, sigma_node, nacc_node)
848 do g = 1, unique_count
849 nnode_m =
size(master(master_idxs(g))%nodes)
851 if( lambda_node(a,g) <= 0.d0 ) cycle
858 lam_cone = lambda_node(a,g)
860 lam_cone = lambda_node(a,g) + mu*gapwnode(g,a)
862 nrm = sqrt( nacc_node(g,a,1)**2 + nacc_node(g,a,2)**2 + nacc_node(g,a,3)**2 )
863 if( nrm < 1.d-30 ) cycle
864 nhat(1:3) = nacc_node(g,a,1:3) / nrm
868 dxi(1) = dot_product(t1(1:3), sigma_node(g,a,1:3))
869 dxi(2) = dot_product(t2(1:3), sigma_node(g,a,1:3))
870 fstate = fric_state_cur(a,g)
872 eps_fric_band, lam_t_new, fstate, alpha, that)
873 fvec(1:3) = lam_t_new(1)*t1(1:3) + lam_t_new(2)*t2(1:3)
876 fvec(1:3) = lam_t_cur(1,a,g)*t1(1:3) + lam_t_cur(2,a,g)*t2(1:3)
879 active_t(a,g) = .true.
880 do j = 1, nnode_s + nnode_m
882 wbar = dot_product(nsnode(g,a,3*j-2:3*j), nhat(1:3))
883 cttforce(3*j-2:3*j,a,g) = -fvec(1:3) * wbar
888 deallocate(sigma_node, nacc_node, lam_t_cur, fric_state_cur)
891 deallocate(sorted_idx)
892 deallocate(snode, nsnode, gapwnode, lambda_node)
895 subroutine getcontactnodalforce_alag(ctState,tSurf,ndCoord,ndDu,mu,mut,fcoeff,symm,ctNForce,ctTForce, &
901 integer(kind=kint) :: nnode
902 integer(kind=kint) :: j
903 real(kind=kreal),
intent(in) :: mu, mut
904 real(kind=kreal) :: fcoeff
905 logical,
intent(in) :: symm
906 real(kind=kreal) :: ndcoord(:), nddu(:)
907 real(kind=kreal) :: ctnforce(:)
908 real(kind=kreal) :: cttforce(:)
909 integer(kind=kint),
optional,
intent(in) :: smoothing_type
911 real(kind=kreal) :: normal(3)
916 real(kind=kreal) :: dgn, nrlforce
917 real(kind=kreal) :: lam_cone
918 real(kind=kreal) :: metric(2,2)
919 integer(kind=kint) :: edof
921 nnode =
size(tsurf%nodes)
927 normal(1:3) = ctstate%direction(1:3)
931 elemcrd(1:3, j) = ndcoord(j*3+1:j*3+3) - nddu(j*3+1:j*3+3)
936 bn, metric, ht, gt, smoothing_type)
939 dgn = dot_product( bn(1:edof), ndcoord(1:edof) )
942 nrlforce = ctstate%multiplier(1) + mu*dgn
945 ctnforce(1:edof) = -nrlforce * bn(1:edof)
948 ctnforce((nnode+1)*3+1) = 0.d0
950 if( fcoeff == 0.d0 )
return
955 edisp(1:3) = nddu(1:3)
957 edisp(j*3+1:j*3+3) = nddu(j*3+1:j*3+3)
964 lam_cone = ctstate%multiplier(1)
966 lam_cone = max( 0.d0, nrlforce )
969 ht, gt, edisp, edof, cttforce, &
973 cttforce((nnode+1)*3+1) = 0.d0
978 & mu,mut,fcoeff,tSurf,lgnt,ctchanged,ctNForce,ctTForce,jump_ratio,smoothing_type)
981 integer(kind=kint),
intent(in) :: ndlocal(:)
982 real(kind=kreal),
intent(in) :: coord(:)
983 real(kind=kreal),
intent(in) :: disp(:)
984 real(kind=kreal),
intent(in) :: ddisp(:)
985 real(kind=kreal),
intent(in) :: mu, mut
986 real(kind=kreal),
intent(in) :: fcoeff
988 real(kind=kreal),
intent(inout) :: lgnt(2)
989 logical,
intent(inout) :: ctchanged
990 real(kind=kreal),
intent(out) :: ctnforce(:)
991 real(kind=kreal),
intent(out) :: cttforce(:)
992 real(kind=kreal),
intent(out) :: jump_ratio
993 integer(kind=kint),
optional,
intent(in) :: smoothing_type
995 integer(kind=kint) :: nnode
996 integer(kind=kint) :: slave, j
1002 real(kind=kreal) :: dgn, nrlforce
1003 real(kind=kreal) :: metric(2,2)
1004 real(kind=kreal) :: dxy(2)
1005 integer(kind=kint) :: edof
1007 nnode =
size(ndlocal) - 1
1016 curpos(1:3) = coord(3*slave-2:3*slave) + disp(3*slave-2:3*slave) + ddisp(3*slave-2:3*slave)
1017 edisp(1:3) = ddisp(3*slave-2:3*slave)
1019 elemcrd(1:3,j) = coord(3*ndlocal(j+1)-2:3*ndlocal(j+1)) + disp(3*ndlocal(j+1)-2:3*ndlocal(j+1))
1020 curpos(j*3+1:j*3+3) = elemcrd(1:3,j) + ddisp(3*ndlocal(j+1)-2:3*ndlocal(j+1))
1021 edisp(j*3+1:j*3+3) = ddisp(3*ndlocal(j+1)-2:3*ndlocal(j+1))
1026 bn, metric, ht, gt, smoothing_type)
1029 dgn = dot_product( bn(1:edof), curpos(1:edof) )
1032 ctstate%wkdist = -dgn
1033 ctstate%multiplier(1) = ctstate%multiplier(1) - mu*ctstate%wkdist
1034 ctstate%distance = ctstate%wkdist
1035 lgnt(1) = lgnt(1) - ctstate%wkdist
1038 nrlforce = ctstate%multiplier(1)
1041 ctnforce(1:edof) = -nrlforce * bn(1:edof)
1043 if( fcoeff == 0.d0 )
return
1050 ht, gt, edisp, edof, cttforce, &
1052 update_multiplier=.true., slave_id=slave, ctchanged=ctchanged, &
1053 jump_ratio=jump_ratio)
1056 dxy = matmul( gt(:,1:edof), curpos(1:edof) )
1057 lgnt(2) = lgnt(2) + dsqrt( dxy(1)*dxy(1) + dxy(2)*dxy(2) )
1065 real(kind=kreal),
intent(in) :: mu
1066 real(kind=kreal),
intent(out) :: stiff(:,:)
1067 real(kind=kreal),
intent(out) :: force(:)
1069 integer :: i, j, nnode, edof
1073 nnode =
size(tsurf%nodes)
1084 stiff(i,j) = mu * dot_product(tm(1:3,i), tm(1:3,j))
1087 force(1:edof) = 0.d0
1096 integer(kind=kint) :: nnode
1097 real(kind=kreal) :: ndu(:)
1098 real(kind=kreal),
intent(in) :: mu
1099 real(kind=kreal) :: ctnforce(:)
1100 real(kind=kreal) :: cttforce(:)
1102 integer(kind=kint) :: edof
1105 real(kind=kreal) :: dg(3)
1106 real(kind=kreal) :: nrlforce(3)
1108 nnode =
size(tsurf%nodes)
1118 dg(1:3) = matmul(tm(1:3, 1:edof), ndu(1:edof))
1121 nrlforce(1:3) = ctstate%multiplier(1:3) + mu*dg(1:3)
1124 ctnforce(1:edof) = -matmul(transpose(tm(1:3, 1:edof)), nrlforce(1:3))
1127 ctnforce((nnode+1)*3+1) = 0.d0
1128 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.