31 ,fstrDYN,fstrPARAM,infoCTChange &
32 ,fstrCPL, restrt_step_num, restrt_step_count )
34 type(hecmwst_local_mesh) :: hecMESH
35 type(hecmwst_matrix) :: hecMAT
40 type(fstr_info_contactchange) :: infoCTChange
42 type(hecmwst_matrix),
pointer :: hecMATmpc
43 integer(kind=kint) :: nnod, ndof, nn
44 integer(kind=kint) :: ierror
45 real(kind=kreal),
allocatable :: prevb(:)
46 integer(kind=kint) :: restrt_step_num
47 integer(kind=kint) :: restrt_step_count
48 real(kind=kreal),
parameter :: pi = 3.14159265358979323846d0
49 integer(kind=kint) :: tot_step, sub_step, step_count
50 logical :: is_OutPoint
52 call hecmw_mpc_mat_init_explicit(hecmesh, hecmat, hecmatmpc)
54 hecmat%NDOF=hecmesh%n_dof
59 if( fstrparam%fg_couple == 1)
then
60 if( fstrparam%fg_couple_type==5 .or. &
61 fstrparam%fg_couple_type==6 )
then
62 allocate( prevb(hecmat%NP*ndof) ,stat=ierror )
64 if( ierror /= 0 )
then
65 write(
idbg,*)
'stop due to allocation error <fstr_solve_NONLINEAR_DYNAMIC, prevB>'
66 write(
idbg,*)
' rank = ', hecmesh%my_rank,
' ierror = ',ierror
68 call hecmw_abort( hecmw_comm_get_comm())
73 fstrsolid%dunode(:) =0.d0
76 & ndof, nnod, restrt_step_count )
78 if(
associated( fstrsolid%contacts ) )
then
80 if( hecmesh%my_rank == 0 )
write(*,*)
'Explicit contact analysis requires three displacement DOFs per node'
81 call hecmw_abort(hecmw_comm_get_comm())
83 call initialize_contact_output_vectors(fstrsolid,hecmat)
84 call setup_contact_elesurf_for_area( hecmesh, fstrsolid )
86 & fstrsolid%ddunode,restrt_step_count == 0)
89 if( restrt_step_count == 0 )
then
94 step_count = restrt_step_count
95 do tot_step = 1, fstrsolid%nstep_tot
96 if(hecmesh%my_rank==0)
write(*,
'(a,i5)')
' loading step=',tot_step
98 sub_step = restrt_step_num
105 step_count = step_count + 1
108 hecmesh, hecmat, hecmatmpc, fstrsolid, fstreig, fstrdyn, fstrparam, &
109 fstrcpl, infoctchange, &
110 restrt_step_num, ndof, nnod, prevb, &
118 call dynamic_output_monit(tot_step, sub_step, fstrdyn%t_curr, hecmesh, fstrdyn, fstreig, fstrsolid)
120 if( fstrdyn%restart_nout > 0 )
then
121 if ( mod(step_count,fstrdyn%restart_nout).eq.0 )
then
123 .false.,infoctchange%contactNode_current,step_count)
134 call fstr_dynamic_output(tot_step, step_count, fstrdyn%t_curr, hecmesh, fstrsolid, fstrdyn, fstrparam, is_outpoint)
138 if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep )
then
139 if( hecmesh%my_rank == 0 )
then
140 write(*,
'(a,i5,a,f6.3)')
'### Number of substeps reached max number: at total_step=', &
146 sub_step = sub_step + 1
149 if( fstrdyn%restart_nout > 0 )
then
151 .true.,infoctchange%contactNode_current,step_count)
156 if( fstrparam%fg_couple == 1)
then
157 if( fstrparam%fg_couple_type==5 .or. &
158 fstrparam%fg_couple_type==6 )
then
159 deallocate( prevb ,stat=ierror )
160 if( ierror /= 0 )
then
161 write(
idbg,*)
'stop due to deallocation error <fstr_solve_NONLINEAR_DYNAMIC, prevB>'
162 write(
idbg,*)
' rank = ', hecmesh%my_rank,
' ierror = ',ierror
164 call hecmw_abort( hecmw_comm_get_comm())
169 call hecmw_mpc_mat_finalize_explicit(hecmesh, hecmat, hecmatmpc)
180 ndof, nnod, restrt_step_count )
182 type(hecmwst_local_mesh),
intent(inout) :: hecMESH
183 type(hecmwst_matrix),
intent(inout) :: hecMAT
184 type(hecmwst_matrix),
pointer,
intent(inout) :: hecMATmpc
188 integer(kind=kint),
intent(in) :: ndof
189 integer(kind=kint),
intent(in) :: nnod
190 integer(kind=kint),
intent(in) :: restrt_step_count
192 integer(kind=kint),
allocatable :: mark(:)
193 integer(kind=kint) :: j
194 real(kind=kreal) :: a1, a2
196 a1 = 1.d0/fstrdyn%t_delta**2
197 a2 = 1.d0/(2.d0*fstrdyn%t_delta)
199 call setmass(fstrsolid,hecmesh,hecmat,fstreig)
200 call hecmw_mpc_trans_mass(hecmesh, hecmat, hecmatmpc, fstreig%mass)
202 allocate(mark(hecmat%NP * hecmat%NDOF))
203 call hecmw_mpc_mark_slave(hecmesh, hecmat, mark)
206 fstrdyn%VEC1(j) = (a1 + a2 *fstrdyn%ray_m) * fstreig%mass(j)
207 if(mark(j) == 1) fstrdyn%VEC1(j) = 1.d0
208 if(dabs(fstrdyn%VEC1(j)) < 1.0e-20)
then
209 if( hecmesh%my_rank == 0 )
then
210 write(*,*)
'stop due to fstrDYN%VEC(j) = 0 , j = ', j
211 write(
imsg,*)
'stop due to fstrDYN%VEC(j) = 0 , j = ', j
213 call hecmw_abort( hecmw_comm_get_comm())
220 if( restrt_step_count == 0 )
then
222 fstrdyn%DISP(j,3) = fstrdyn%DISP(j,1) - fstrdyn%VEL (j,1)/(2.d0*a2) + fstrdyn%ACC (j,1)/ (2.d0*a1)
223 fstrdyn%DISP(j,2) = fstrdyn%DISP(j,1) - fstrdyn%VEL (j,1)/ a2 + fstrdyn%ACC (j,1)/ (2.d0*a1) * 4.d0
231 hecMESH, hecMAT, hecMATmpc, fstrSOLID, fstrEIG, fstrDYN, fstrPARAM, &
232 fstrCPL, infoCTChange, &
233 restrt_step_num, ndof, nnod, prevB, &
236 integer(kind=kint),
intent(in) :: cstep
237 integer(kind=kint),
intent(in) :: istep
238 type(hecmwst_local_mesh),
intent(inout) :: hecMESH
239 type(hecmwst_matrix),
intent(inout) :: hecMAT
240 type(hecmwst_matrix),
pointer,
intent(inout) :: hecMATmpc
246 type(fstr_info_contactchange),
intent(inout) :: infoCTChange
247 integer(kind=kint),
intent(in) :: restrt_step_num
248 integer(kind=kint),
intent(in) :: ndof
249 integer(kind=kint),
intent(in) :: nnod
250 real(kind=kreal),
allocatable,
intent(inout) :: prevb(:)
251 logical,
intent(in) :: is_last_step
253 integer(kind=kint) :: j, kk, kkk0, kkk1
254 integer(kind=kint) :: revocap_flag
255 real(kind=kreal) :: bsize
256 real(kind=kreal),
parameter :: pi = 3.14159265358979323846d0
257 real(kind=kreal) :: a1, a2
258 real(kind=kreal) :: b1, b2, b3, a3
261 a1 = 1.d0/fstrdyn%t_delta**2
262 a2 = 1.d0/(2.d0*fstrdyn%t_delta)
265 b1 = 0.d0; b2 = 0.d0; b3 = 0.d0
268 call dynamic_mat_ass_load (cstep, fstrdyn%t_curr, hecmesh, hecmat, fstrsolid, fstrdyn, fstrparam)
269 do j=1, hecmesh%n_node* hecmesh%n_dof
270 hecmat%B(j)=hecmat%B(j)-fstrsolid%QFORCE(j)
275 if( fstrparam%fg_couple == 1 )
then
276 if( fstrparam%fg_couple_type==5 .or. &
277 fstrparam%fg_couple_type==6 )
then
278 do j = 1, hecmat%NP * ndof
279 prevb(j) = hecmat%B(j)
284 if( fstrparam%fg_couple == 1 )
then
285 if( fstrparam%fg_couple_type==1 .or. &
286 fstrparam%fg_couple_type==3 .or. &
288 if( fstrparam%fg_couple_first /= 0 )
then
289 bsize = dfloat( istep ) / dfloat( fstrparam%fg_couple_first )
290 if( bsize > 1.0 ) bsize = 1.0
291 do kkk0 = 1, fstrcpl%coupled_node_n
293 fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
294 fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
295 fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
298 if( fstrparam%fg_couple_window > 0 )
then
299 j = istep - restrt_step_num + 1
300 kk = fstrdyn%n_step - restrt_step_num + 1
301 bsize = 0.5*(1.0-cos(2.0*pi*dfloat(j)/dfloat(kk)))
302 do kkk0 = 1, fstrcpl%coupled_node_n
304 fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
305 fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
306 fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
313 call hecmw_mpc_trans_rhs(hecmesh, hecmat, hecmatmpc)
316 hecmatmpc%B(j) = hecmatmpc%B(j) + 2.d0*a1* fstreig%mass(j) * fstrdyn%DISP(j,1) &
317 + (- a1 + a2 * fstrdyn%ray_m) * fstreig%mass(j) * fstrdyn%DISP(j,3)
329 hecmatmpc%X(j) = hecmatmpc%B(j) / fstrdyn%VEC1(j)
330 if(dabs(hecmatmpc%X(j)) > 1.0d+5)
then
331 if( hecmesh%my_rank == 0 )
then
332 print *,
'Displacement increment too large, please adjust your step size!',istep,hecmatmpc%X(j)
333 write(
imsg,*)
'Displacement increment too large, please adjust your step size!',istep,hecmatmpc%B(j),fstrdyn%VEC1(j)
338 call hecmw_mpc_tback_sol(hecmesh, hecmat, hecmatmpc)
342 if( fstrparam%fg_couple == 1 )
then
343 if( fstrparam%fg_couple_type>1 )
then
344 do j=1, fstrcpl%coupled_node_n
345 if( fstrcpl%dof == 3 )
then
347 kkk1 = fstrcpl%coupled_node(j)*3
349 fstrcpl%disp (kkk0-2) = hecmat%X(kkk1-2)
350 fstrcpl%disp (kkk0-1) = hecmat%X(kkk1-1)
351 fstrcpl%disp (kkk0 ) = hecmat%X(kkk1 )
353 fstrcpl%velo (kkk0-2) = -b1*fstrdyn%ACC(kkk1-2,1) - b2*fstrdyn%VEL(kkk1-2,1) + &
354 b3*( hecmat%X(kkk1-2) - fstrdyn%DISP(kkk1-2,1) )
355 fstrcpl%velo (kkk0-1) = -b1*fstrdyn%ACC(kkk1-1,1) - b2*fstrdyn%VEL(kkk1-1,1) + &
356 b3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
357 fstrcpl%velo (kkk0 ) = -b1*fstrdyn%ACC(kkk1,1) - b2*fstrdyn%VEL(kkk1,1) + &
358 b3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
359 fstrcpl%accel(kkk0-2) = -a1*fstrdyn%ACC(kkk1-2,1) - a2*fstrdyn%VEL(kkk1-2,1) + &
360 a3*( hecmat%X(kkk1-2) - fstrdyn%DISP(kkk1-2,1) )
361 fstrcpl%accel(kkk0-1) = -a1*fstrdyn%ACC(kkk1-1,1) - a2*fstrdyn%VEL(kkk1-1,1) + &
362 a3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
363 fstrcpl%accel(kkk0 ) = -a1*fstrdyn%ACC(kkk1,1) - a2*fstrdyn%VEL(kkk1,1) + &
364 a3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
367 kkk1 = fstrcpl%coupled_node(j)*2
369 fstrcpl%disp (kkk0-1) = hecmat%X(kkk1-1)
370 fstrcpl%disp (kkk0 ) = hecmat%X(kkk1 )
372 fstrcpl%velo (kkk0-1) = -b1*fstrdyn%ACC(kkk1-1,1) - b2*fstrdyn%VEL(kkk1-1,1) + &
373 b3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
374 fstrcpl%velo (kkk0 ) = -b1*fstrdyn%ACC(kkk1,1) - b2*fstrdyn%VEL(kkk1,1) + &
375 b3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
376 fstrcpl%accel(kkk0-1) = -a1*fstrdyn%ACC(kkk1-1,1) - a2*fstrdyn%VEL(kkk1-1,1) + &
377 a3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
378 fstrcpl%accel(kkk0 ) = -a1*fstrdyn%ACC(kkk1,1) - a2*fstrdyn%VEL(kkk1,1) + &
379 a3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
385 select case ( fstrparam%fg_couple_type )
390 if( revocap_flag==0 )
then
391 do j = 1, hecmat%NP * ndof
392 hecmat%B(j) = prevb(j)
398 if( revocap_flag==0 )
then
399 do j = 1, hecmat%NP * ndof
400 hecmat%B(j) = prevb(j)
416 fstrsolid%unode(j) = fstrdyn%DISP(j,1)
417 fstrsolid%dunode(j) = hecmat%X(j)-fstrdyn%DISP(j,1)
419 if(
associated( fstrsolid%contacts ) )
then
422 & fstrsolid%ddunode,.false.)
424 hecmat%X(j) = hecmat%X(j) + fstrsolid%ddunode(j)
430 fstrdyn%ACC (j,1) = a1*(hecmat%X(j) - 2.d0*fstrdyn%DISP(j,1) + fstrdyn%DISP(j,3))
431 fstrdyn%VEL (j,1) = a2*(hecmat%X(j) - fstrdyn%DISP(j,3))
432 fstrsolid%unode(j) = fstrdyn%DISP(j,1)
433 fstrsolid%dunode(j) = hecmat%X(j)-fstrdyn%DISP(j,1)
434 fstrdyn%DISP(j,3) = fstrdyn%DISP(j,1)
435 fstrdyn%DISP(j,1) = hecmat%X(j)
436 hecmat%X(j) = fstrsolid%dunode(j)
437 fstrdyn%kineticEnergy = fstrdyn%kineticEnergy + 0.5d0*fstreig%mass(j)*fstrdyn%VEL(j,1)*fstrdyn%VEL(j,1)
441 call fstr_updatenewton( hecmesh, hecmat, fstrsolid, fstrparam, fstrdyn%t_curr, fstrdyn%t_delta, 0, fstrdyn%strainEnergy )
447 fstrsolid%unode(j) = fstrsolid%unode(j) + fstrsolid%dunode(j)
455 integer,
intent(in) :: cstep
456 integer,
intent(in) :: ndof
457 real(kind=kreal),
intent(in) :: mmat(:)
458 type( hecmwst_local_mesh ),
intent(in) :: hecmesh
460 type(fstr_info_contactchange) :: infoCTChange
461 real(kind=kreal),
intent(out) :: uc(:)
462 logical,
intent(in) :: is_init
463 integer :: i, j, k, slave, nn, iSS, sid, iter, offset
464 real(kind=kreal),
allocatable :: contact_force(:), friction_force(:), compliance(:)
465 real(kind=kreal) :: fdum, conv, dlambda, rel_t(3), tangent(3), friction(3)
466 real(kind=kreal) :: tangent_compliance, friction_limit, friction_norm, rel_t_norm
467 real(kind=kreal) :: element_disp(3*(l_max_surface_node+1))
468 real(kind=kreal) :: tm(3,3*(l_max_surface_node+1)), tt(3,3*(l_max_surface_node+1))
469 real(kind=kreal) :: bn(3*(l_max_surface_node+1))
470 integer,
parameter :: MAX_CONTACT_ITER = 1000
474 if( .not. infoctchange%active )
return
476 allocate(contact_force(hecmesh%n_node*ndof), friction_force(hecmesh%n_node*ndof), &
477 compliance(hecmesh%n_node*ndof))
478 compliance = 1.d0/mmat
481 do i=1,fstrsolid%n_contacts
482 do j=1,
size(fstrsolid%contacts(i)%slave)
483 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
484 fstrsolid%contacts(i)%states(j)%multiplier(:) = 0.d0
485 fstrsolid%contacts(i)%states(j)%wkdist = 0.d0
492 do i=1,fstrsolid%n_contacts
493 do j= 1,
size(fstrsolid%contacts(i)%slave)
494 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
495 if( fstrsolid%contacts(i)%states(j)%distance>epsilon(1.d0) )
then
496 fstrsolid%contacts(i)%states(j)%state = contactfree
499 slave = fstrsolid%contacts(i)%slave(j)
500 sid = fstrsolid%contacts(i)%states(j)%surface
501 nn =
size( fstrsolid%contacts(i)%master(sid)%nodes )
502 if( nn > l_max_surface_node )
then
503 if( hecmesh%my_rank == 0 )
write(*,*)
'Too many nodes on explicit contact surface:', nn
504 call hecmw_abort(hecmw_comm_get_comm())
506 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
507 0.d0, tm, tt, fstrsolid%contacts(i)%smoothing, bn)
508 offset = (slave-1)*ndof
509 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
510 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(1:3)
512 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
513 offset = (iss-1)*ndof
514 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
515 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(3*k+1:3*k+3)
520 call hecmw_assemble_r(hecmesh, contact_force, hecmesh%n_node, ndof)
521 call hecmw_update_r(hecmesh, contact_force, hecmesh%n_node, ndof)
524 do i=1,fstrsolid%n_contacts
525 do j= 1,
size(fstrsolid%contacts(i)%slave)
526 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
527 slave = fstrsolid%contacts(i)%slave(j)
528 sid = fstrsolid%contacts(i)%states(j)%surface
529 nn =
size( fstrsolid%contacts(i)%master(sid)%nodes )
530 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
531 0.d0, tm, tt, fstrsolid%contacts(i)%smoothing, bn)
532 offset = (slave-1)*ndof
533 fstrsolid%contacts(i)%states(j)%wkdist = &
534 dot_product(bn(1:3), contact_force(offset+1:offset+3)*compliance(offset+1:offset+3))
535 fdum = dot_product(bn(1:3), bn(1:3)*compliance(offset+1:offset+3))
537 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
538 offset = (iss-1)*ndof
539 fstrsolid%contacts(i)%states(j)%wkdist = fstrsolid%contacts(i)%states(j)%wkdist &
540 + dot_product(bn(3*k+1:3*k+3), contact_force(offset+1:offset+3)*compliance(offset+1:offset+3))
541 fdum = fdum + dot_product(bn(3*k+1:3*k+3), bn(3*k+1:3*k+3)*compliance(offset+1:offset+3))
544 if( fdum > 1.d-20 ) &
545 dlambda = (fstrsolid%contacts(i)%states(j)%distance-fstrsolid%contacts(i)%states(j)%wkdist)/fdum
546 conv = conv + dlambda*dlambda
547 fstrsolid%contacts(i)%states(j)%multiplier(1) = fstrsolid%contacts(i)%states(j)%multiplier(1) + dlambda
550 call hecmw_allreduce_r1(hecmesh, conv, hecmw_sum)
552 if( dsqrt(conv)<1.d-8 )
exit
553 if( iter >= max_contact_iter )
then
554 if( hecmesh%my_rank == 0 )
write(*,*)
'Explicit contact correction failed to converge'
555 call hecmw_abort(hecmw_comm_get_comm())
560 do i=1,fstrsolid%n_contacts
561 do j=1,
size(fstrsolid%contacts(i)%slave)
562 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
563 slave = fstrsolid%contacts(i)%slave(j)
564 sid = fstrsolid%contacts(i)%states(j)%surface
565 nn =
size(fstrsolid%contacts(i)%master(sid)%nodes)
566 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
567 0.d0, tm, tt, fstrsolid%contacts(i)%smoothing, bn)
568 offset = (slave-1)*ndof
569 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
570 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(1:3)
572 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
573 offset = (iss-1)*ndof
574 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
575 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(3*k+1:3*k+3)
579 call hecmw_assemble_r(hecmesh, contact_force, hecmesh%n_node, ndof)
580 call hecmw_update_r(hecmesh, contact_force, hecmesh%n_node, ndof)
582 do i=1,hecmesh%n_node*ndof
583 uc(i) = contact_force(i)*compliance(i)
586 friction_force = 0.d0
587 do i=1,fstrsolid%n_contacts
588 do j=1,
size(fstrsolid%contacts(i)%slave)
589 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
590 if( fstrsolid%contacts(i)%fcoeff <= 0.d0 )
then
591 fstrsolid%contacts(i)%states(j)%tangentForce_final(:) = 0.d0
592 fstrsolid%contacts(i)%states(j)%reldisp(:) = 0.d0
596 slave = fstrsolid%contacts(i)%slave(j)
597 sid = fstrsolid%contacts(i)%states(j)%surface
598 nn =
size(fstrsolid%contacts(i)%master(sid)%nodes)
599 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
600 fstrsolid%contacts(i)%fcoeff, tm, tt, fstrsolid%contacts(i)%smoothing)
602 offset = (slave-1)*ndof
603 element_disp(1:3) = fstrsolid%dunode(offset+1:offset+3) + uc(offset+1:offset+3)
605 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
606 offset = (iss-1)*ndof
607 element_disp(3*k+1:3*k+3) = fstrsolid%dunode(offset+1:offset+3) + uc(offset+1:offset+3)
609 rel_t = matmul(tt(1:3,1:3*(nn+1)), element_disp(1:3*(nn+1)))
610 fstrsolid%contacts(i)%states(j)%reldisp(:) = rel_t
612 rel_t_norm = dsqrt(dot_product(rel_t,rel_t))
614 if( rel_t_norm > 1.d-20 )
then
615 tangent = rel_t/rel_t_norm
616 offset = (slave-1)*ndof
617 tangent_compliance = sum(matmul(tangent,tt(1:3,1:3))**2*compliance(offset+1:offset+3))
619 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
620 offset = (iss-1)*ndof
621 tangent_compliance = tangent_compliance &
622 + sum(matmul(tangent,tt(1:3,3*k+1:3*k+3))**2*compliance(offset+1:offset+3))
624 if( tangent_compliance > 1.d-20 ) friction = rel_t/tangent_compliance
627 friction_limit = fstrsolid%contacts(i)%fcoeff &
628 * dabs(fstrsolid%contacts(i)%states(j)%multiplier(1))
629 friction_norm = dsqrt(dot_product(friction,friction))
630 if( friction_norm > friction_limit .and. friction_norm > 1.d-20 )
then
631 friction = friction*(friction_limit/friction_norm)
632 fstrsolid%contacts(i)%states(j)%state = contactslip
634 fstrsolid%contacts(i)%states(j)%state = contactstick
636 friction_norm = dsqrt(dot_product(friction,friction))
637 fstrsolid%contacts(i)%states(j)%tangentForce_final(:) = friction
638 fstrsolid%contacts(i)%states(j)%multiplier(2) = friction_norm
639 fstrsolid%contacts(i)%states(j)%multiplier(3) = 0.d0
641 offset = (slave-1)*ndof
642 friction_force(offset+1:offset+3) = friction_force(offset+1:offset+3) &
643 - matmul(transpose(tm(1:3,1:3)), friction)
645 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
646 offset = (iss-1)*ndof
647 friction_force(offset+1:offset+3) = friction_force(offset+1:offset+3) &
648 - matmul(transpose(tm(1:3,3*k+1:3*k+3)), friction)
652 call hecmw_assemble_r(hecmesh, friction_force, hecmesh%n_node, ndof)
653 call hecmw_update_r(hecmesh, friction_force, hecmesh%n_node, ndof)
654 do i=1,hecmesh%n_node*ndof
655 uc(i) = (contact_force(i)+friction_force(i))*compliance(i)
659 deallocate(contact_force, friction_force, compliance)
663 integer(kind=kint),
intent(in) :: ndof
664 type(hecmwst_local_mesh),
intent(in) :: hecMESH
666 real(kind=kreal),
intent(inout) :: compliance(:)
667 integer(kind=kint) :: ig0, ig, ityp, idofS, idofE, iS0, iE0, ik, node, idof
669 do ig0=1,fstrsolid%BOUNDARY_ngrp_tot
670 ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
671 ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
673 idofe = ityp-idofs*10
674 if( fstrsolid%BOUNDARY_ngrp_rotID(ig0) > 0 )
then
678 is0 = hecmesh%node_group%grp_index(ig-1)+1
679 ie0 = hecmesh%node_group%grp_index(ig)
681 node = hecmesh%node_group%grp_item(ik)
682 do idof=idofs,min(idofe,ndof)
683 compliance((node-1)*ndof+idof) = 0.d0
688 if( fstrsolid%VELOCITY_type /=
kbcinitial )
then
689 do ig0=1,fstrsolid%VELOCITY_ngrp_tot
690 ig = fstrsolid%VELOCITY_ngrp_ID(ig0)
691 ityp = fstrsolid%VELOCITY_ngrp_type(ig0)
693 idofe = ityp-idofs*10
694 if( fstrsolid%VELOCITY_ngrp_rotID(ig0) > 0 )
then
698 is0 = hecmesh%node_group%grp_index(ig-1)+1
699 ie0 = hecmesh%node_group%grp_index(ig)
701 node = hecmesh%node_group%grp_item(ik)
702 do idof=idofs,min(idofe,ndof)
703 compliance((node-1)*ndof+idof) = 0.d0
709 if( fstrsolid%ACCELERATION_type /=
kbcinitial )
then
710 do ig0=1,fstrsolid%ACCELERATION_ngrp_tot
711 ig = fstrsolid%ACCELERATION_ngrp_ID(ig0)
712 ityp = fstrsolid%ACCELERATION_ngrp_type(ig0)
714 idofe = ityp-idofs*10
715 is0 = hecmesh%node_group%grp_index(ig-1)+1
716 ie0 = hecmesh%node_group%grp_index(ig)
718 node = hecmesh%node_group%grp_item(ik)
719 do idof=idofs,min(idofe,ndof)
720 compliance((node-1)*ndof+idof) = 0.d0
This module contains subroutines for nonlinear explicit dynamic analysis.
subroutine forward_increment_lagrange(cstep, ndof, mmat, hecMESH, fstrSOLID, infoCTChange, uc, is_init)
subroutine fstr_solve_dynamic_nlexplicit(hecMESH, hecMAT, fstrSOLID, fstrEIG, fstrDYN, fstrPARAM, infoCTChange, fstrCPL, restrt_step_num, restrt_step_count)
subroutine fstr_advance_dynamic_explicit(cstep, istep, hecMESH, hecMAT, hecMATmpc, fstrSOLID, fstrEIG, fstrDYN, fstrPARAM, fstrCPL, infoCTChange, restrt_step_num, ndof, nnod, prevB, is_last_step)
Advance one time step of explicit dynamic analysis.
subroutine fstr_prepare_dynamic_explicit(hecMESH, hecMAT, hecMATmpc, fstrSOLID, fstrEIG, fstrDYN, ndof, nnod, restrt_step_count)
Prepare initial state for explicit dynamic analysis (central difference).
subroutine mask_explicit_contact_constraints(ndof, hecMESH, fstrSOLID, compliance)
This module contains functions to set acceleration boundary condition in dynamic analysis.
subroutine dynamic_explicit_ass_ac(hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, t_curr, iter)
This module contains functions to set velocity boundary condition in dynamic analysis.
subroutine dynamic_explicit_ass_vl(hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, t_curr, iter)
This module contains functions to set displacement boundary condition in dynamic analysis.
subroutine dynamic_explicit_ass_bc(hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, t_curr, iter)
This subroutine setup disp boundary condition.
This module contains functions relates to coupling analysis.
subroutine dynamic_mat_ass_couple(hecMESH, hecMAT, fstrSOLID, fstrCPL)
This module contains function to set boundary condition of external load in dynamic analysis.
subroutine dynamic_mat_ass_load(cstep, t_curr, hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, fstrPARAM, iter)
This function sets boundary condition of external load.
This module provides functions to output result.
subroutine fstr_dynamic_output(cstep, istep, t_curr, hecMESH, fstrSOLID, fstrDYNAMIC, fstrPARAM, outflag)
Output result.
subroutine dynamic_output_monit(cstep, istep, t_curr, hecMESH, fstrDYNAMIC, fstrEIG, fstrSOLID)
Set up lumped mass matrix.
subroutine setmass(fstrSOLID, hecMESH, hecMAT, fstrEIG)
subroutine, public fstr_rcap_send(fstrCPL)
subroutine, public fstr_rcap_get(fstrCPL)
subroutine fstr_get_convergence(revocap_flag)
This module provides function to calculate residual of nodal force.
subroutine, public fstr_update_reaction_spc(cstep, hecMESH, fstrSOLID)
Set fstrSOLIDREACTION at constrained DOFs using current fstrSOLIDQFORCE. Constrained DOFs are enumera...
This module provides functions to read in and write out restart files.
subroutine fstr_write_restart_dyna_nl(cstep, substep, hecMESH, fstrSOLID, fstrDYNAMIC, fstrPARAM, is_StepFinished, contactNode, step_count)
write out restart file for nonlinear dynamic analysis
This module provides functions to deal with time and increment of stress analysis.
real(kind=kreal) function fstr_get_timeinc()
logical function fstr_timeinc_istimepoint(stepinfo, fstrPARAM)
subroutine fstr_timeinc_settimeincrement(stepinfo, fstrPARAM, substep, fstrSOLID)
real(kind=kreal) function fstr_get_time()
subroutine fstr_proceed_time()
logical function fstr_timeinc_isstepfinished(stepinfo)
This module provides function to calculate to do updates.
subroutine fstr_updatestate(hecMESH, fstrSOLID, tincr)
Update elastiplastic status.
subroutine fstr_updatenewton(hecMESH, hecMAT, fstrSOLID, fstrPARAM, time, tincr, iter, strainEnergy)
Update displacement, stress, strain and internal forces.
This module defines common data and basic structures for analysis.
integer(kind=kint), parameter imsg
integer(kind=kint), parameter idbg
subroutine fstr_abort(code)
Terminate the analysis with a classified exit status. MPI_ABORT does not perform the Fortran I/O fina...
integer(kind=kint), parameter kbcinitial
This modules just summarizes all modules used in static analysis.
Data for coupling analysis.
Data for DYNAMIC ANSLYSIS (fstrDYNAMIC)
Package of data used by Lanczos eigenvalue solver.
FSTR INNER CONTROL PARAMETERS (fstrPARAM)