31 ,fstrDYN,fstrRESULT,fstrPARAM,infoCTChange &
32 ,fstrCPL, restrt_step_num, restrt_step_count )
34 type(hecmwst_local_mesh) :: hecMESH
35 type(hecmwst_matrix) :: hecMAT
38 type(hecmwst_result_data) :: fstrRESULT
41 type(hecmwst_matrix_lagrange) :: hecLagMAT
42 type(fstr_info_contactchange) :: infoCTChange
44 type(hecmwst_matrix),
pointer :: hecMATmpc
45 integer(kind=kint),
allocatable :: mark(:)
46 integer(kind=kint) :: nnod, ndof, nn, numnp
47 integer(kind=kint) :: i, j, ids, ide, kk
48 integer(kind=kint) :: kkk0, kkk1
49 integer(kind=kint) :: ierror
50 integer(kind=kint) :: iiii5, iexit
51 integer(kind=kint) :: revocap_flag
52 real(kind=kreal),
allocatable :: prevb(:)
53 real(kind=kreal) :: bsize, res
54 real(kind=kreal) :: time_1, time_2
55 integer(kind=kint) :: restrt_step_num
56 integer(kind=kint) :: restrt_step_count
57 real(kind=kreal),
parameter :: pi = 3.14159265358979323846d0
58 integer(kind=kint) :: tot_step, sub_step, step_count
59 logical :: is_OutPoint
61 call hecmw_mpc_mat_init_explicit(hecmesh, hecmat, hecmatmpc)
63 hecmat%NDOF=hecmesh%n_dof
68 if( fstrparam%fg_couple == 1)
then
69 if( fstrparam%fg_couple_type==5 .or. &
70 fstrparam%fg_couple_type==6 )
then
71 allocate( prevb(hecmat%NP*ndof) ,stat=ierror )
73 if( ierror /= 0 )
then
74 write(
idbg,*)
'stop due to allocation error <fstr_solve_NONLINEAR_DYNAMIC, prevB>'
75 write(
idbg,*)
' rank = ', hecmesh%my_rank,
' ierror = ',ierror
77 call hecmw_abort( hecmw_comm_get_comm())
82 fstrsolid%dunode(:) =0.d0
85 & ndof, nnod, restrt_step_count )
87 if(
associated( fstrsolid%contacts ) )
then
89 if( hecmesh%my_rank == 0 )
write(*,*)
'Explicit contact analysis requires three displacement DOFs per node'
90 call hecmw_abort(hecmw_comm_get_comm())
92 call initialize_contact_output_vectors(fstrsolid,hecmat)
93 call setup_contact_elesurf_for_area( 1, hecmesh, fstrsolid )
95 & fstrsolid%ddunode,restrt_step_count == 0)
98 if( restrt_step_count == 0 )
then
103 step_count = restrt_step_count
104 do tot_step = 1, fstrsolid%nstep_tot
105 if(hecmesh%my_rank==0)
write(*,
'(a,i5)')
' loading step=',tot_step
107 sub_step = restrt_step_num
110 & fstrsolid%NRstat_i, fstrsolid%NRstat_r, fstrsolid%AutoINC_stat, fstrsolid%CutBack_stat )
115 step_count = step_count + 1
118 hecmesh, hecmat, hecmatmpc, fstrsolid, fstreig, fstrdyn, fstrparam, &
119 fstrcpl, infoctchange, &
120 restrt_step_num, ndof, nnod, prevb, &
128 call dynamic_output_monit(tot_step, sub_step, fstrdyn%t_curr, hecmesh, fstrparam, fstrdyn, fstreig, fstrsolid)
130 if( fstrdyn%restart_nout > 0 )
then
131 if ( mod(step_count,fstrdyn%restart_nout).eq.0 )
then
133 .false.,infoctchange%contactNode_current,step_count)
144 call fstr_dynamic_output(tot_step, step_count, fstrdyn%t_curr, hecmesh, fstrsolid, fstrdyn, fstrparam, is_outpoint)
148 if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep )
then
149 if( hecmesh%my_rank == 0 )
then
150 write(*,
'(a,i5,a,f6.3)')
'### Number of substeps reached max number: at total_step=', &
156 sub_step = sub_step + 1
159 if( fstrdyn%restart_nout > 0 )
then
161 .true.,infoctchange%contactNode_current,step_count)
166 if( fstrparam%fg_couple == 1)
then
167 if( fstrparam%fg_couple_type==5 .or. &
168 fstrparam%fg_couple_type==6 )
then
169 deallocate( prevb ,stat=ierror )
170 if( ierror /= 0 )
then
171 write(
idbg,*)
'stop due to deallocation error <fstr_solve_NONLINEAR_DYNAMIC, prevB>'
172 write(
idbg,*)
' rank = ', hecmesh%my_rank,
' ierror = ',ierror
174 call hecmw_abort( hecmw_comm_get_comm())
179 call hecmw_mpc_mat_finalize_explicit(hecmesh, hecmat, hecmatmpc)
190 ndof, nnod, restrt_step_count )
192 type(hecmwst_local_mesh),
intent(inout) :: hecMESH
193 type(hecmwst_matrix),
intent(inout) :: hecMAT
194 type(hecmwst_matrix),
pointer,
intent(inout) :: hecMATmpc
198 integer(kind=kint),
intent(in) :: ndof
199 integer(kind=kint),
intent(in) :: nnod
200 integer(kind=kint),
intent(in) :: restrt_step_count
202 integer(kind=kint),
allocatable :: mark(:)
203 integer(kind=kint) :: j
204 real(kind=kreal) :: a1, a2
206 a1 = 1.d0/fstrdyn%t_delta**2
207 a2 = 1.d0/(2.d0*fstrdyn%t_delta)
209 call setmass(fstrsolid,hecmesh,hecmat,fstreig)
210 call hecmw_mpc_trans_mass(hecmesh, hecmat, hecmatmpc, fstreig%mass)
212 allocate(mark(hecmat%NP * hecmat%NDOF))
213 call hecmw_mpc_mark_slave(hecmesh, hecmat, mark)
216 fstrdyn%VEC1(j) = (a1 + a2 *fstrdyn%ray_m) * fstreig%mass(j)
217 if(mark(j) == 1) fstrdyn%VEC1(j) = 1.d0
218 if(dabs(fstrdyn%VEC1(j)) < 1.0e-20)
then
219 if( hecmesh%my_rank == 0 )
then
220 write(*,*)
'stop due to fstrDYN%VEC(j) = 0 , j = ', j
221 write(
imsg,*)
'stop due to fstrDYN%VEC(j) = 0 , j = ', j
223 call hecmw_abort( hecmw_comm_get_comm())
230 if( restrt_step_count == 0 )
then
232 fstrdyn%DISP(j,3) = fstrdyn%DISP(j,1) - fstrdyn%VEL (j,1)/(2.d0*a2) + fstrdyn%ACC (j,1)/ (2.d0*a1)
233 fstrdyn%DISP(j,2) = fstrdyn%DISP(j,1) - fstrdyn%VEL (j,1)/ a2 + fstrdyn%ACC (j,1)/ (2.d0*a1) * 4.d0
241 hecMESH, hecMAT, hecMATmpc, fstrSOLID, fstrEIG, fstrDYN, fstrPARAM, &
242 fstrCPL, infoCTChange, &
243 restrt_step_num, ndof, nnod, prevB, &
246 integer(kind=kint),
intent(in) :: cstep
247 integer(kind=kint),
intent(in) :: istep
248 type(hecmwst_local_mesh),
intent(inout) :: hecMESH
249 type(hecmwst_matrix),
intent(inout) :: hecMAT
250 type(hecmwst_matrix),
pointer,
intent(inout) :: hecMATmpc
256 type(fstr_info_contactchange),
intent(inout) :: infoCTChange
257 integer(kind=kint),
intent(in) :: restrt_step_num
258 integer(kind=kint),
intent(in) :: ndof
259 integer(kind=kint),
intent(in) :: nnod
260 real(kind=kreal),
allocatable,
intent(inout) :: prevb(:)
261 logical,
intent(in) :: is_last_step
263 integer(kind=kint) :: j, kk, kkk0, kkk1
264 integer(kind=kint) :: revocap_flag
265 real(kind=kreal) :: bsize
266 real(kind=kreal),
parameter :: pi = 3.14159265358979323846d0
267 real(kind=kreal) :: a1, a2
268 real(kind=kreal) :: b1, b2, b3, a3
271 a1 = 1.d0/fstrdyn%t_delta**2
272 a2 = 1.d0/(2.d0*fstrdyn%t_delta)
275 b1 = 0.d0; b2 = 0.d0; b3 = 0.d0
278 call dynamic_mat_ass_load (cstep, fstrdyn%t_curr, hecmesh, hecmat, fstrsolid, fstrdyn, fstrparam)
279 do j=1, hecmesh%n_node* hecmesh%n_dof
280 hecmat%B(j)=hecmat%B(j)-fstrsolid%QFORCE(j)
285 if( fstrparam%fg_couple == 1 )
then
286 if( fstrparam%fg_couple_type==5 .or. &
287 fstrparam%fg_couple_type==6 )
then
288 do j = 1, hecmat%NP * ndof
289 prevb(j) = hecmat%B(j)
294 if( fstrparam%fg_couple == 1 )
then
295 if( fstrparam%fg_couple_type==1 .or. &
296 fstrparam%fg_couple_type==3 .or. &
298 if( fstrparam%fg_couple_first /= 0 )
then
299 bsize = dfloat( istep ) / dfloat( fstrparam%fg_couple_first )
300 if( bsize > 1.0 ) bsize = 1.0
301 do kkk0 = 1, fstrcpl%coupled_node_n
303 fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
304 fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
305 fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
308 if( fstrparam%fg_couple_window > 0 )
then
309 j = istep - restrt_step_num + 1
310 kk = fstrdyn%n_step - restrt_step_num + 1
311 bsize = 0.5*(1.0-cos(2.0*pi*dfloat(j)/dfloat(kk)))
312 do kkk0 = 1, fstrcpl%coupled_node_n
314 fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
315 fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
316 fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
323 call hecmw_mpc_trans_rhs(hecmesh, hecmat, hecmatmpc)
326 hecmatmpc%B(j) = hecmatmpc%B(j) + 2.d0*a1* fstreig%mass(j) * fstrdyn%DISP(j,1) &
327 + (- a1 + a2 * fstrdyn%ray_m) * fstreig%mass(j) * fstrdyn%DISP(j,3)
339 hecmatmpc%X(j) = hecmatmpc%B(j) / fstrdyn%VEC1(j)
340 if(dabs(hecmatmpc%X(j)) > 1.0d+5)
then
341 if( hecmesh%my_rank == 0 )
then
342 print *,
'Displacement increment too large, please adjust your step size!',istep,hecmatmpc%X(j)
343 write(
imsg,*)
'Displacement increment too large, please adjust your step size!',istep,hecmatmpc%B(j),fstrdyn%VEC1(j)
348 call hecmw_mpc_tback_sol(hecmesh, hecmat, hecmatmpc)
352 if( fstrparam%fg_couple == 1 )
then
353 if( fstrparam%fg_couple_type>1 )
then
354 do j=1, fstrcpl%coupled_node_n
355 if( fstrcpl%dof == 3 )
then
357 kkk1 = fstrcpl%coupled_node(j)*3
359 fstrcpl%disp (kkk0-2) = hecmat%X(kkk1-2)
360 fstrcpl%disp (kkk0-1) = hecmat%X(kkk1-1)
361 fstrcpl%disp (kkk0 ) = hecmat%X(kkk1 )
363 fstrcpl%velo (kkk0-2) = -b1*fstrdyn%ACC(kkk1-2,1) - b2*fstrdyn%VEL(kkk1-2,1) + &
364 b3*( hecmat%X(kkk1-2) - fstrdyn%DISP(kkk1-2,1) )
365 fstrcpl%velo (kkk0-1) = -b1*fstrdyn%ACC(kkk1-1,1) - b2*fstrdyn%VEL(kkk1-1,1) + &
366 b3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
367 fstrcpl%velo (kkk0 ) = -b1*fstrdyn%ACC(kkk1,1) - b2*fstrdyn%VEL(kkk1,1) + &
368 b3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
369 fstrcpl%accel(kkk0-2) = -a1*fstrdyn%ACC(kkk1-2,1) - a2*fstrdyn%VEL(kkk1-2,1) + &
370 a3*( hecmat%X(kkk1-2) - fstrdyn%DISP(kkk1-2,1) )
371 fstrcpl%accel(kkk0-1) = -a1*fstrdyn%ACC(kkk1-1,1) - a2*fstrdyn%VEL(kkk1-1,1) + &
372 a3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
373 fstrcpl%accel(kkk0 ) = -a1*fstrdyn%ACC(kkk1,1) - a2*fstrdyn%VEL(kkk1,1) + &
374 a3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
377 kkk1 = fstrcpl%coupled_node(j)*2
379 fstrcpl%disp (kkk0-1) = hecmat%X(kkk1-1)
380 fstrcpl%disp (kkk0 ) = hecmat%X(kkk1 )
382 fstrcpl%velo (kkk0-1) = -b1*fstrdyn%ACC(kkk1-1,1) - b2*fstrdyn%VEL(kkk1-1,1) + &
383 b3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
384 fstrcpl%velo (kkk0 ) = -b1*fstrdyn%ACC(kkk1,1) - b2*fstrdyn%VEL(kkk1,1) + &
385 b3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
386 fstrcpl%accel(kkk0-1) = -a1*fstrdyn%ACC(kkk1-1,1) - a2*fstrdyn%VEL(kkk1-1,1) + &
387 a3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
388 fstrcpl%accel(kkk0 ) = -a1*fstrdyn%ACC(kkk1,1) - a2*fstrdyn%VEL(kkk1,1) + &
389 a3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
395 select case ( fstrparam%fg_couple_type )
400 if( revocap_flag==0 )
then
401 do j = 1, hecmat%NP * ndof
402 hecmat%B(j) = prevb(j)
408 if( revocap_flag==0 )
then
409 do j = 1, hecmat%NP * ndof
410 hecmat%B(j) = prevb(j)
426 fstrsolid%unode(j) = fstrdyn%DISP(j,1)
427 fstrsolid%dunode(j) = hecmat%X(j)-fstrdyn%DISP(j,1)
429 if(
associated( fstrsolid%contacts ) )
then
432 & fstrsolid%ddunode,.false.)
434 hecmat%X(j) = hecmat%X(j) + fstrsolid%ddunode(j)
440 fstrdyn%ACC (j,1) = a1*(hecmat%X(j) - 2.d0*fstrdyn%DISP(j,1) + fstrdyn%DISP(j,3))
441 fstrdyn%VEL (j,1) = a2*(hecmat%X(j) - fstrdyn%DISP(j,3))
442 fstrsolid%unode(j) = fstrdyn%DISP(j,1)
443 fstrsolid%dunode(j) = hecmat%X(j)-fstrdyn%DISP(j,1)
444 fstrdyn%DISP(j,3) = fstrdyn%DISP(j,1)
445 fstrdyn%DISP(j,1) = hecmat%X(j)
446 hecmat%X(j) = fstrsolid%dunode(j)
447 fstrdyn%kineticEnergy = fstrdyn%kineticEnergy + 0.5d0*fstreig%mass(j)*fstrdyn%VEL(j,1)*fstrdyn%VEL(j,1)
451 call fstr_updatenewton( hecmesh, hecmat, fstrsolid, fstrdyn%t_curr, fstrdyn%t_delta, 0, fstrdyn%strainEnergy )
457 fstrsolid%unode(j) = fstrsolid%unode(j) + fstrsolid%dunode(j)
465 integer,
intent(in) :: cstep
466 integer,
intent(in) :: ndof
467 real(kind=kreal),
intent(in) :: mmat(:)
468 type( hecmwst_local_mesh ),
intent(in) :: hecmesh
470 type(fstr_info_contactchange) :: infoCTChange
471 real(kind=kreal),
intent(out) :: uc(:)
472 logical,
intent(in) :: is_init
473 integer :: i, j, k, slave, nn, iSS, sid, iter, offset
474 real(kind=kreal),
allocatable :: contact_force(:), friction_force(:), compliance(:)
475 real(kind=kreal) :: fdum, conv, dlambda, rel_t(3), tangent(3), friction(3)
476 real(kind=kreal) :: tangent_compliance, friction_limit, friction_norm, rel_t_norm
477 real(kind=kreal) :: element_disp(3*(l_max_surface_node+1))
478 real(kind=kreal) :: tm(3,3*(l_max_surface_node+1)), tt(3,3*(l_max_surface_node+1))
479 real(kind=kreal) :: bn(3*(l_max_surface_node+1))
480 integer,
parameter :: MAX_CONTACT_ITER = 1000
484 if( .not. infoctchange%active )
return
486 allocate(contact_force(hecmesh%n_node*ndof), friction_force(hecmesh%n_node*ndof), &
487 compliance(hecmesh%n_node*ndof))
488 compliance = 1.d0/mmat
491 do i=1,fstrsolid%n_contacts
492 do j=1,
size(fstrsolid%contacts(i)%slave)
493 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
494 fstrsolid%contacts(i)%states(j)%multiplier(:) = 0.d0
495 fstrsolid%contacts(i)%states(j)%wkdist = 0.d0
502 do i=1,fstrsolid%n_contacts
503 do j= 1,
size(fstrsolid%contacts(i)%slave)
504 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
505 if( fstrsolid%contacts(i)%states(j)%distance>epsilon(1.d0) )
then
506 fstrsolid%contacts(i)%states(j)%state = contactfree
509 slave = fstrsolid%contacts(i)%slave(j)
510 sid = fstrsolid%contacts(i)%states(j)%surface
511 nn =
size( fstrsolid%contacts(i)%master(sid)%nodes )
512 if( nn > l_max_surface_node )
then
513 if( hecmesh%my_rank == 0 )
write(*,*)
'Too many nodes on explicit contact surface:', nn
514 call hecmw_abort(hecmw_comm_get_comm())
516 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
517 0.d0, tm, tt, fstrsolid%contacts(i)%smoothing, bn)
518 offset = (slave-1)*ndof
519 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
520 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(1:3)
522 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
523 offset = (iss-1)*ndof
524 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
525 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(3*k+1:3*k+3)
530 call hecmw_assemble_r(hecmesh, contact_force, hecmesh%n_node, ndof)
531 call hecmw_update_r(hecmesh, contact_force, hecmesh%n_node, ndof)
534 do i=1,fstrsolid%n_contacts
535 do j= 1,
size(fstrsolid%contacts(i)%slave)
536 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
537 slave = fstrsolid%contacts(i)%slave(j)
538 sid = fstrsolid%contacts(i)%states(j)%surface
539 nn =
size( fstrsolid%contacts(i)%master(sid)%nodes )
540 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
541 0.d0, tm, tt, fstrsolid%contacts(i)%smoothing, bn)
542 offset = (slave-1)*ndof
543 fstrsolid%contacts(i)%states(j)%wkdist = &
544 dot_product(bn(1:3), contact_force(offset+1:offset+3)*compliance(offset+1:offset+3))
545 fdum = dot_product(bn(1:3), bn(1:3)*compliance(offset+1:offset+3))
547 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
548 offset = (iss-1)*ndof
549 fstrsolid%contacts(i)%states(j)%wkdist = fstrsolid%contacts(i)%states(j)%wkdist &
550 + dot_product(bn(3*k+1:3*k+3), contact_force(offset+1:offset+3)*compliance(offset+1:offset+3))
551 fdum = fdum + dot_product(bn(3*k+1:3*k+3), bn(3*k+1:3*k+3)*compliance(offset+1:offset+3))
554 if( fdum > 1.d-20 ) &
555 dlambda = (fstrsolid%contacts(i)%states(j)%distance-fstrsolid%contacts(i)%states(j)%wkdist)/fdum
556 conv = conv + dlambda*dlambda
557 fstrsolid%contacts(i)%states(j)%multiplier(1) = fstrsolid%contacts(i)%states(j)%multiplier(1) + dlambda
560 call hecmw_allreduce_r1(hecmesh, conv, hecmw_sum)
562 if( dsqrt(conv)<1.d-8 )
exit
563 if( iter >= max_contact_iter )
then
564 if( hecmesh%my_rank == 0 )
write(*,*)
'Explicit contact correction failed to converge'
565 call hecmw_abort(hecmw_comm_get_comm())
570 do i=1,fstrsolid%n_contacts
571 do j=1,
size(fstrsolid%contacts(i)%slave)
572 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
573 slave = fstrsolid%contacts(i)%slave(j)
574 sid = fstrsolid%contacts(i)%states(j)%surface
575 nn =
size(fstrsolid%contacts(i)%master(sid)%nodes)
576 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
577 0.d0, tm, tt, fstrsolid%contacts(i)%smoothing, bn)
578 offset = (slave-1)*ndof
579 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
580 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(1:3)
582 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
583 offset = (iss-1)*ndof
584 contact_force(offset+1:offset+3) = contact_force(offset+1:offset+3) &
585 + fstrsolid%contacts(i)%states(j)%multiplier(1)*bn(3*k+1:3*k+3)
589 call hecmw_assemble_r(hecmesh, contact_force, hecmesh%n_node, ndof)
590 call hecmw_update_r(hecmesh, contact_force, hecmesh%n_node, ndof)
592 do i=1,hecmesh%n_node*ndof
593 uc(i) = contact_force(i)*compliance(i)
596 friction_force = 0.d0
597 do i=1,fstrsolid%n_contacts
598 do j=1,
size(fstrsolid%contacts(i)%slave)
599 if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
600 if( fstrsolid%contacts(i)%fcoeff <= 0.d0 )
then
601 fstrsolid%contacts(i)%states(j)%tangentForce_final(:) = 0.d0
602 fstrsolid%contacts(i)%states(j)%reldisp(:) = 0.d0
606 slave = fstrsolid%contacts(i)%slave(j)
607 sid = fstrsolid%contacts(i)%states(j)%surface
608 nn =
size(fstrsolid%contacts(i)%master(sid)%nodes)
609 call computetm_tt(fstrsolid%contacts(i)%states(j), fstrsolid%contacts(i)%master(sid), &
610 fstrsolid%contacts(i)%fcoeff, tm, tt, fstrsolid%contacts(i)%smoothing)
612 offset = (slave-1)*ndof
613 element_disp(1:3) = fstrsolid%dunode(offset+1:offset+3) + uc(offset+1:offset+3)
615 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
616 offset = (iss-1)*ndof
617 element_disp(3*k+1:3*k+3) = fstrsolid%dunode(offset+1:offset+3) + uc(offset+1:offset+3)
619 rel_t = matmul(tt(1:3,1:3*(nn+1)), element_disp(1:3*(nn+1)))
620 fstrsolid%contacts(i)%states(j)%reldisp(:) = rel_t
622 rel_t_norm = dsqrt(dot_product(rel_t,rel_t))
624 if( rel_t_norm > 1.d-20 )
then
625 tangent = rel_t/rel_t_norm
626 offset = (slave-1)*ndof
627 tangent_compliance = sum(matmul(tangent,tt(1:3,1:3))**2*compliance(offset+1:offset+3))
629 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
630 offset = (iss-1)*ndof
631 tangent_compliance = tangent_compliance &
632 + sum(matmul(tangent,tt(1:3,3*k+1:3*k+3))**2*compliance(offset+1:offset+3))
634 if( tangent_compliance > 1.d-20 ) friction = rel_t/tangent_compliance
637 friction_limit = fstrsolid%contacts(i)%fcoeff &
638 * dabs(fstrsolid%contacts(i)%states(j)%multiplier(1))
639 friction_norm = dsqrt(dot_product(friction,friction))
640 if( friction_norm > friction_limit .and. friction_norm > 1.d-20 )
then
641 friction = friction*(friction_limit/friction_norm)
642 fstrsolid%contacts(i)%states(j)%state = contactslip
644 fstrsolid%contacts(i)%states(j)%state = contactstick
646 friction_norm = dsqrt(dot_product(friction,friction))
647 fstrsolid%contacts(i)%states(j)%tangentForce_final(:) = friction
648 fstrsolid%contacts(i)%states(j)%multiplier(2) = friction_norm
649 fstrsolid%contacts(i)%states(j)%multiplier(3) = 0.d0
651 offset = (slave-1)*ndof
652 friction_force(offset+1:offset+3) = friction_force(offset+1:offset+3) &
653 - matmul(transpose(tm(1:3,1:3)), friction)
655 iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
656 offset = (iss-1)*ndof
657 friction_force(offset+1:offset+3) = friction_force(offset+1:offset+3) &
658 - matmul(transpose(tm(1:3,3*k+1:3*k+3)), friction)
662 call hecmw_assemble_r(hecmesh, friction_force, hecmesh%n_node, ndof)
663 call hecmw_update_r(hecmesh, friction_force, hecmesh%n_node, ndof)
664 do i=1,hecmesh%n_node*ndof
665 uc(i) = (contact_force(i)+friction_force(i))*compliance(i)
669 deallocate(contact_force, friction_force, compliance)
673 integer(kind=kint),
intent(in) :: ndof
674 type(hecmwst_local_mesh),
intent(in) :: hecMESH
676 real(kind=kreal),
intent(inout) :: compliance(:)
677 integer(kind=kint) :: ig0, ig, ityp, idofS, idofE, iS0, iE0, ik, node, idof
679 do ig0=1,fstrsolid%BOUNDARY_ngrp_tot
680 ig = fstrsolid%BOUNDARY_ngrp_ID(ig0)
681 ityp = fstrsolid%BOUNDARY_ngrp_type(ig0)
683 idofe = ityp-idofs*10
684 if( fstrsolid%BOUNDARY_ngrp_rotID(ig0) > 0 )
then
688 is0 = hecmesh%node_group%grp_index(ig-1)+1
689 ie0 = hecmesh%node_group%grp_index(ig)
691 node = hecmesh%node_group%grp_item(ik)
692 do idof=idofs,min(idofe,ndof)
693 compliance((node-1)*ndof+idof) = 0.d0
698 if( fstrsolid%VELOCITY_type /=
kbcinitial )
then
699 do ig0=1,fstrsolid%VELOCITY_ngrp_tot
700 ig = fstrsolid%VELOCITY_ngrp_ID(ig0)
701 ityp = fstrsolid%VELOCITY_ngrp_type(ig0)
703 idofe = ityp-idofs*10
704 if( fstrsolid%VELOCITY_ngrp_rotID(ig0) > 0 )
then
708 is0 = hecmesh%node_group%grp_index(ig-1)+1
709 ie0 = hecmesh%node_group%grp_index(ig)
711 node = hecmesh%node_group%grp_item(ik)
712 do idof=idofs,min(idofe,ndof)
713 compliance((node-1)*ndof+idof) = 0.d0
719 if( fstrsolid%ACCELERATION_type /=
kbcinitial )
then
720 do ig0=1,fstrsolid%ACCELERATION_ngrp_tot
721 ig = fstrsolid%ACCELERATION_ngrp_ID(ig0)
722 ityp = fstrsolid%ACCELERATION_ngrp_type(ig0)
724 idofe = ityp-idofs*10
725 is0 = hecmesh%node_group%grp_index(ig-1)+1
726 ie0 = hecmesh%node_group%grp_index(ig)
728 node = hecmesh%node_group%grp_item(ik)
729 do idof=idofs,min(idofe,ndof)
730 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, fstrRESULT, 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, fstrPARAM, 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, NRstatI, NRstatR, AutoINC_stat, Cutback_stat)
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, 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)