FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_dynamic_nlexplicit.f90
Go to the documentation of this file.
1 !-------------------------------------------------------------------------------
2 ! Copyright (c) 2019 FrontISTR Commons
3 ! This software is released under the MIT License, see LICENSE.txt
4 !-------------------------------------------------------------------------------
6 
8  use m_fstr
9  use m_static_lib
16  use m_fstr_update
17  use m_fstr_residual
18  use m_fstr_restart
20  use m_fstr_rcap_io
21  use mcontact
22  use m_fstr_timeinc
23 
24 contains
25 
26  !C================================================================C
27  !C-- subroutine fstr_solve_LINEAR_DYNAMIC
28  !C================================================================C
29  subroutine fstr_solve_dynamic_nlexplicit(hecMESH,hecMAT,fstrSOLID,fstrEIG &
30  ,fstrDYN,fstrRESULT,fstrPARAM,infoCTChange &
31  ,fstrCPL, restrt_step_num, restrt_step_count )
32  implicit none
33  type(hecmwst_local_mesh) :: hecMESH
34  type(hecmwst_matrix) :: hecMAT
35  type(fstr_eigen) :: fstrEIG
36  type(fstr_solid) :: fstrSOLID
37  type(hecmwst_result_data) :: fstrRESULT
38  type(fstr_param) :: fstrPARAM
39  type(fstr_dynamic) :: fstrDYN
40  type(hecmwst_matrix_lagrange) :: hecLagMAT
41  type(fstr_info_contactchange) :: infoCTChange
42  type(fstr_couple) :: fstrCPL !for COUPLE
43  type(hecmwst_matrix), pointer :: hecMATmpc
44  integer(kind=kint), allocatable :: mark(:)
45  integer(kind=kint) :: nnod, ndof, nn, numnp
46  integer(kind=kint) :: i, j, ids, ide, kk
47  integer(kind=kint) :: kkk0, kkk1
48  integer(kind=kint) :: ierror
49  integer(kind=kint) :: iiii5, iexit
50  integer(kind=kint) :: revocap_flag
51  real(kind=kreal), allocatable :: prevb(:)
52  real(kind=kreal) :: bsize, res
53  real(kind=kreal) :: time_1, time_2
54  integer(kind=kint) :: restrt_step_num
55  integer(kind=kint) :: restrt_step_count
56  real(kind=kreal), parameter :: pi = 3.14159265358979323846d0
57  integer(kind=kint) :: tot_step, sub_step, step_count
58  logical :: is_OutPoint
59 
60  call hecmw_mpc_mat_init_explicit(hecmesh, hecmat, hecmatmpc)
61 
62  hecmat%NDOF=hecmesh%n_dof
63  nnod=hecmesh%n_node
64  ndof=hecmat%NDOF
65  nn=ndof*ndof
66 
67  if( fstrparam%fg_couple == 1) then
68  if( fstrparam%fg_couple_type==5 .or. &
69  fstrparam%fg_couple_type==6 ) then
70  allocate( prevb(hecmat%NP*ndof) ,stat=ierror )
71  prevb = 0.0d0
72  if( ierror /= 0 ) then
73  write(idbg,*) 'stop due to allocation error <fstr_solve_NONLINEAR_DYNAMIC, prevB>'
74  write(idbg,*) ' rank = ', hecmesh%my_rank,' ierror = ',ierror
75  call flush(idbg)
76  call hecmw_abort( hecmw_comm_get_comm())
77  endif
78  endif
79  endif
80 
81  fstrsolid%dunode(:) =0.d0
82 
83  call fstr_prepare_dynamic_explicit( hecmesh, hecmat, fstrsolid, fstreig, fstrdyn, &
84  & ndof, nnod, restrt_step_count )
85 
86  if( restrt_step_count == 0 ) then
87  call fstr_dynamic_output(1, 0, 0.d0, hecmesh, fstrsolid, fstrdyn, fstrparam, .true.)
88  call dynamic_output_monit(1, 0, 0.d0, hecmesh, fstrparam, fstrdyn, fstreig, fstrsolid)
89  end if
90 
91  if( associated( fstrsolid%contacts ) ) then
92  call initialize_contact_output_vectors(fstrsolid,hecmat)
93  call setup_contact_elesurf_for_area( 1, hecmesh, fstrsolid )
94  call forward_increment_lagrange(1,ndof,fstrdyn%VEC1,hecmesh,fstrsolid,infoctchange,&
95  & fstrdyn%DISP(:,2),fstrsolid%ddunode)
96  endif
97 
98  step_count = restrt_step_count
99  do tot_step = 1, fstrsolid%nstep_tot
100  if(hecmesh%my_rank==0) write(*,'(a,i5)') ' loading step=',tot_step
101 
102  sub_step = restrt_step_num
103  do while(.true.)
104  call fstr_timeinc_settimeincrement( fstrsolid%step_ctrl(tot_step), fstrparam, sub_step, &
105  & fstrsolid%NRstat_i, fstrsolid%NRstat_r, fstrsolid%AutoINC_stat, fstrsolid%CutBack_stat )
106 
107  fstrdyn%t_curr = fstr_get_time()
108  fstrdyn%t_delta = fstr_get_timeinc()
109 
110  step_count = step_count + 1
111 
112  call fstr_advance_dynamic_explicit( tot_step, sub_step, &
113  hecmesh, hecmat, hecmatmpc, fstrsolid, fstreig, fstrdyn, fstrparam, &
114  fstrcpl, infoctchange, &
115  restrt_step_num, ndof, nnod, prevb, &
116  fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) ) )
117 
118  ! ----- Result output (include visualize output)
119  ! Evaluate isTimePoint before time advance, then OR with isStepFinished after
120  is_outpoint = fstr_timeinc_istimepoint( fstrsolid%step_ctrl(tot_step), fstrparam )
121 
122  !C-- output result of monitoring node
123  call dynamic_output_monit(tot_step, sub_step, fstrdyn%t_curr, hecmesh, fstrparam, fstrdyn, fstreig, fstrsolid)
124 
125  if( fstrdyn%restart_nout > 0 ) then
126  if ( mod(step_count,fstrdyn%restart_nout).eq.0 ) then
127  call fstr_write_restart_dyna_nl(tot_step,sub_step,hecmesh,fstrsolid,fstrdyn,fstrparam,&
128  .false.,infoctchange%contactNode_current,step_count)
129  end if
130  end if
131 
132  call fstr_proceed_time()
133  fstrdyn%t_curr = fstr_get_time()
134 
135  ! isStepFinished must be evaluated after fstr_proceed_time
136  is_outpoint = is_outpoint .or. fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) )
137 
138  !C-- output new displacement, velocity and acceleration
139  call fstr_dynamic_output(tot_step, step_count, fstrdyn%t_curr, hecmesh, fstrsolid, fstrdyn, fstrparam, is_outpoint)
140 
141  if( fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) ) ) exit
142 
143  if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep ) then
144  if( hecmesh%my_rank == 0 ) then
145  write(*,'(a,i5,a,f6.3)') '### Number of substeps reached max number: at total_step=', &
146  & tot_step, ' time=', fstr_get_time()
147  endif
148  call hecmw_abort( hecmw_comm_get_comm())
149  endif
150 
151  sub_step = sub_step + 1
152  enddo
153 
154  if( fstrdyn%restart_nout > 0 ) then
155  call fstr_write_restart_dyna_nl(tot_step,sub_step,hecmesh,fstrsolid,fstrdyn,fstrparam,&
156  .true.,infoctchange%contactNode_current,step_count)
157  end if
158  restrt_step_num = 1
159  enddo
160 
161  if( fstrparam%fg_couple == 1) then
162  if( fstrparam%fg_couple_type==5 .or. &
163  fstrparam%fg_couple_type==6 ) then
164  deallocate( prevb ,stat=ierror )
165  if( ierror /= 0 ) then
166  write(idbg,*) 'stop due to deallocation error <fstr_solve_NONLINEAR_DYNAMIC, prevB>'
167  write(idbg,*) ' rank = ', hecmesh%my_rank,' ierror = ',ierror
168  call flush(idbg)
169  call hecmw_abort( hecmw_comm_get_comm())
170  endif
171  endif
172  endif
173 
174  call hecmw_mpc_mat_finalize_explicit(hecmesh, hecmat, hecmatmpc)
175 
176  end subroutine fstr_solve_dynamic_nlexplicit
177 
184  subroutine fstr_prepare_dynamic_explicit( hecMESH, hecMAT, fstrSOLID, fstrEIG, fstrDYN, &
185  ndof, nnod, restrt_step_count )
186  implicit none
187  type(hecmwst_local_mesh), intent(inout) :: hecMESH
188  type(hecmwst_matrix), intent(inout) :: hecMAT
189  type(fstr_solid), intent(inout) :: fstrSOLID
190  type(fstr_eigen), intent(inout) :: fstrEIG
191  type(fstr_dynamic), intent(inout) :: fstrDYN
192  integer(kind=kint), intent(in) :: ndof
193  integer(kind=kint), intent(in) :: nnod
194  integer(kind=kint), intent(in) :: restrt_step_count
195 
196  integer(kind=kint), allocatable :: mark(:)
197  integer(kind=kint) :: j
198  real(kind=kreal) :: a1, a2
199 
200  a1 = 1.d0/fstrdyn%t_delta**2
201  a2 = 1.d0/(2.d0*fstrdyn%t_delta)
202 
203  call setmass(fstrsolid,hecmesh,hecmat,fstreig)
204  call hecmw_mpc_trans_mass(hecmesh, hecmat, fstreig%mass)
205 
206  allocate(mark(hecmat%NP * hecmat%NDOF))
207  call hecmw_mpc_mark_slave(hecmesh, hecmat, mark)
208 
209  do j = 1 ,ndof*nnod
210  fstrdyn%VEC1(j) = (a1 + a2 *fstrdyn%ray_m) * fstreig%mass(j)
211  if(mark(j) == 1) fstrdyn%VEC1(j) = 1.d0
212  if(dabs(fstrdyn%VEC1(j)) < 1.0e-20) then
213  if( hecmesh%my_rank == 0 ) then
214  write(*,*) 'stop due to fstrDYN%VEC(j) = 0 , j = ', j
215  write(imsg,*) 'stop due to fstrDYN%VEC(j) = 0 , j = ', j
216  end if
217  call hecmw_abort( hecmw_comm_get_comm())
218  endif
219  end do
220 
221  deallocate(mark)
222 
223  !C-- virtual past displacements for central-difference startup
224  if( restrt_step_count == 0 ) then
225  do j = 1 ,ndof*nnod
226  fstrdyn%DISP(j,3) = fstrdyn%DISP(j,1) - fstrdyn%VEL (j,1)/(2.d0*a2) + fstrdyn%ACC (j,1)/ (2.d0*a1)
227  fstrdyn%DISP(j,2) = fstrdyn%DISP(j,1) - fstrdyn%VEL (j,1)/ a2 + fstrdyn%ACC (j,1)/ (2.d0*a1) * 4.d0
228  end do
229  endif
230 
231  end subroutine fstr_prepare_dynamic_explicit
232 
234  subroutine fstr_advance_dynamic_explicit( cstep, istep, &
235  hecMESH, hecMAT, hecMATmpc, fstrSOLID, fstrEIG, fstrDYN, fstrPARAM, &
236  fstrCPL, infoCTChange, &
237  restrt_step_num, ndof, nnod, prevB, &
238  is_last_step )
239  implicit none
240  integer(kind=kint), intent(in) :: cstep
241  integer(kind=kint), intent(in) :: istep
242  type(hecmwst_local_mesh), intent(inout) :: hecMESH
243  type(hecmwst_matrix), intent(inout) :: hecMAT
244  type(hecmwst_matrix), pointer, intent(inout) :: hecMATmpc
245  type(fstr_solid), intent(inout) :: fstrSOLID
246  type(fstr_eigen), intent(inout) :: fstrEIG
247  type(fstr_dynamic), intent(inout) :: fstrDYN
248  type(fstr_param), intent(inout) :: fstrPARAM
249  type(fstr_couple), intent(inout) :: fstrCPL
250  type(fstr_info_contactchange), intent(inout) :: infoCTChange
251  integer(kind=kint), intent(in) :: restrt_step_num
252  integer(kind=kint), intent(in) :: ndof
253  integer(kind=kint), intent(in) :: nnod
254  real(kind=kreal), allocatable, intent(inout) :: prevb(:)
255  logical, intent(in) :: is_last_step
256 
257  integer(kind=kint) :: j, kk, kkk0, kkk1
258  integer(kind=kint) :: revocap_flag
259  real(kind=kreal) :: bsize
260  real(kind=kreal), parameter :: pi = 3.14159265358979323846d0
261  real(kind=kreal) :: a1, a2
262  real(kind=kreal) :: b1, b2, b3, a3
263 
264  !C-- central-difference coefficients (depend only on dt)
265  a1 = 1.d0/fstrdyn%t_delta**2
266  a2 = 1.d0/(2.d0*fstrdyn%t_delta)
267  !C-- coupling-only coefficients (kept zero for central difference)
268  a3 = 0.d0
269  b1 = 0.d0; b2 = 0.d0; b3 = 0.d0
270 
271  !C-- mechanical boundary condition
272  call dynamic_mat_ass_load (cstep, fstrdyn%t_curr, hecmesh, hecmat, fstrsolid, fstrdyn, fstrparam)
273  do j=1, hecmesh%n_node* hecmesh%n_dof
274  hecmat%B(j)=hecmat%B(j)-fstrsolid%QFORCE(j)
275  end do
276 
277  !C ********************************************************************************
278  !C for couple analysis
279  if( fstrparam%fg_couple == 1 ) then
280  if( fstrparam%fg_couple_type==5 .or. &
281  fstrparam%fg_couple_type==6 ) then
282  do j = 1, hecmat%NP * ndof
283  prevb(j) = hecmat%B(j)
284  enddo
285  endif
286  endif
287  do
288  if( fstrparam%fg_couple == 1 ) then
289  if( fstrparam%fg_couple_type==1 .or. &
290  fstrparam%fg_couple_type==3 .or. &
291  fstrparam%fg_couple_type==5 ) call fstr_rcap_get( fstrcpl )
292  if( fstrparam%fg_couple_first /= 0 ) then
293  bsize = dfloat( istep ) / dfloat( fstrparam%fg_couple_first )
294  if( bsize > 1.0 ) bsize = 1.0
295  do kkk0 = 1, fstrcpl%coupled_node_n
296  kkk1 = 3 * kkk0
297  fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
298  fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
299  fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
300  enddo
301  endif
302  if( fstrparam%fg_couple_window > 0 ) then
303  j = istep - restrt_step_num + 1
304  kk = fstrdyn%n_step - restrt_step_num + 1
305  bsize = 0.5*(1.0-cos(2.0*pi*dfloat(j)/dfloat(kk)))
306  do kkk0 = 1, fstrcpl%coupled_node_n
307  kkk1 = 3 * kkk0
308  fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
309  fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
310  fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
311  enddo
312  endif
313  call dynamic_mat_ass_couple( hecmesh, hecmat, fstrsolid, fstrcpl )
314  endif
315  !C ********************************************************************************
316 
317  call hecmw_mpc_trans_rhs(hecmesh, hecmat, hecmatmpc)
318 
319  do j = 1 ,ndof*nnod
320  hecmatmpc%B(j) = hecmatmpc%B(j) + 2.d0*a1* fstreig%mass(j) * fstrdyn%DISP(j,1) &
321  + (- a1 + a2 * fstrdyn%ray_m) * fstreig%mass(j) * fstrdyn%DISP(j,3)
322  end do
323 
324  !C
325  !C-- geometrical boundary condition
326 
327  call dynamic_explicit_ass_bc(hecmesh, hecmatmpc, fstrsolid, fstrdyn, fstrdyn%t_curr)
328  call dynamic_explicit_ass_vl(hecmesh, hecmatmpc, fstrsolid, fstrdyn, fstrdyn%t_curr)
329  call dynamic_explicit_ass_ac(hecmesh, hecmatmpc, fstrsolid, fstrdyn, fstrdyn%t_curr)
330 
331  ! Finish the calculation
332  do j = 1 ,ndof*nnod
333  hecmatmpc%X(j) = hecmatmpc%B(j) / fstrdyn%VEC1(j)
334  if(dabs(hecmatmpc%X(j)) > 1.0d+5) then
335  if( hecmesh%my_rank == 0 ) then
336  print *, 'Displacement increment too large, please adjust your step size!',istep,hecmatmpc%X(j)
337  write(imsg,*) 'Displacement increment too large, please adjust your step size!',istep,hecmatmpc%B(j),fstrdyn%VEC1(j)
338  end if
339  call hecmw_abort( hecmw_comm_get_comm())
340  end if
341  end do
342  call hecmw_mpc_tback_sol(hecmesh, hecmat, hecmatmpc)
343 
344  !C *****************************************************
345  !C for couple analysis
346  if( fstrparam%fg_couple == 1 ) then
347  if( fstrparam%fg_couple_type>1 ) then
348  do j=1, fstrcpl%coupled_node_n
349  if( fstrcpl%dof == 3 ) then
350  kkk0 = j*3
351  kkk1 = fstrcpl%coupled_node(j)*3
352 
353  fstrcpl%disp (kkk0-2) = hecmat%X(kkk1-2)
354  fstrcpl%disp (kkk0-1) = hecmat%X(kkk1-1)
355  fstrcpl%disp (kkk0 ) = hecmat%X(kkk1 )
356 
357  fstrcpl%velo (kkk0-2) = -b1*fstrdyn%ACC(kkk1-2,1) - b2*fstrdyn%VEL(kkk1-2,1) + &
358  b3*( hecmat%X(kkk1-2) - fstrdyn%DISP(kkk1-2,1) )
359  fstrcpl%velo (kkk0-1) = -b1*fstrdyn%ACC(kkk1-1,1) - b2*fstrdyn%VEL(kkk1-1,1) + &
360  b3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
361  fstrcpl%velo (kkk0 ) = -b1*fstrdyn%ACC(kkk1,1) - b2*fstrdyn%VEL(kkk1,1) + &
362  b3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
363  fstrcpl%accel(kkk0-2) = -a1*fstrdyn%ACC(kkk1-2,1) - a2*fstrdyn%VEL(kkk1-2,1) + &
364  a3*( hecmat%X(kkk1-2) - fstrdyn%DISP(kkk1-2,1) )
365  fstrcpl%accel(kkk0-1) = -a1*fstrdyn%ACC(kkk1-1,1) - a2*fstrdyn%VEL(kkk1-1,1) + &
366  a3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
367  fstrcpl%accel(kkk0 ) = -a1*fstrdyn%ACC(kkk1,1) - a2*fstrdyn%VEL(kkk1,1) + &
368  a3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
369  else
370  kkk0 = j*2
371  kkk1 = fstrcpl%coupled_node(j)*2
372 
373  fstrcpl%disp (kkk0-1) = hecmat%X(kkk1-1)
374  fstrcpl%disp (kkk0 ) = hecmat%X(kkk1 )
375 
376  fstrcpl%velo (kkk0-1) = -b1*fstrdyn%ACC(kkk1-1,1) - b2*fstrdyn%VEL(kkk1-1,1) + &
377  b3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
378  fstrcpl%velo (kkk0 ) = -b1*fstrdyn%ACC(kkk1,1) - b2*fstrdyn%VEL(kkk1,1) + &
379  b3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
380  fstrcpl%accel(kkk0-1) = -a1*fstrdyn%ACC(kkk1-1,1) - a2*fstrdyn%VEL(kkk1-1,1) + &
381  a3*( hecmat%X(kkk1-1) - fstrdyn%DISP(kkk1-1,1) )
382  fstrcpl%accel(kkk0 ) = -a1*fstrdyn%ACC(kkk1,1) - a2*fstrdyn%VEL(kkk1,1) + &
383  a3*( hecmat%X(kkk1) - fstrdyn%DISP(kkk1,1) )
384  endif
385  end do
386  call fstr_rcap_send( fstrcpl )
387  endif
388 
389  select case ( fstrparam%fg_couple_type )
390  case (4)
391  call fstr_rcap_get( fstrcpl )
392  case (5)
393  call fstr_get_convergence( revocap_flag )
394  if( revocap_flag==0 ) then
395  do j = 1, hecmat%NP * ndof
396  hecmat%B(j) = prevb(j)
397  enddo
398  cycle
399  endif
400  case (6)
401  call fstr_get_convergence( revocap_flag )
402  if( revocap_flag==0 ) then
403  do j = 1, hecmat%NP * ndof
404  hecmat%B(j) = prevb(j)
405  enddo
406  call fstr_rcap_get( fstrcpl )
407  cycle
408  else
409  if( .not. is_last_step ) call fstr_rcap_get( fstrcpl )
410  endif
411  end select
412  endif
413  exit
414  enddo
415 
416  !C *****************************************************
417  !C-- contact corrector
418  !C
419  do j = 1 ,ndof*nnod
420  fstrsolid%unode(j) = fstrdyn%DISP(j,1)
421  fstrsolid%dunode(j) = hecmat%X(j)-fstrdyn%DISP(j,1)
422  enddo
423  if( associated( fstrsolid%contacts ) ) then
424  !call fstr_scan_contact_state( cstep, fstrDYN%t_delta, kcaSLAGRANGE, hecMESH, fstrSOLID, infoCTChange )
425  call forward_increment_lagrange(cstep,ndof,fstrdyn%VEC1,hecmesh,fstrsolid,infoctchange,&
426  & fstrdyn%DISP(:,2),fstrsolid%ddunode)
427  do j = 1 ,ndof*nnod
428  hecmat%X(j) = hecmat%X(j) + fstrsolid%ddunode(j)
429  enddo
430  endif
431 
432  !C-- new displacement, velocity and acceleration
433  do j = 1 ,ndof*nnod
434  fstrdyn%ACC (j,1) = a1*(hecmat%X(j) - 2.d0*fstrdyn%DISP(j,1) + fstrdyn%DISP(j,3))
435  fstrdyn%VEL (j,1) = a2*(hecmat%X(j) - fstrdyn%DISP(j,3))
436  fstrsolid%unode(j) = fstrdyn%DISP(j,1)
437  fstrsolid%dunode(j) = hecmat%X(j)-fstrdyn%DISP(j,1)
438  fstrdyn%DISP(j,3) = fstrdyn%DISP(j,1)
439  fstrdyn%DISP(j,1) = hecmat%X(j)
440  hecmat%X(j) = fstrsolid%dunode(j)
441  fstrdyn%kineticEnergy = fstrdyn%kineticEnergy + 0.5d0*fstreig%mass(j)*fstrdyn%VEL(j,1)*fstrdyn%VEL(j,1)
442  end do
443 
444  ! ----- update strain, stress, and internal force
445  call fstr_updatenewton( hecmesh, hecmat, fstrsolid, fstrdyn%t_curr, fstrdyn%t_delta, 0, fstrdyn%strainEnergy )
446 
447  ! ----- update reaction force at constrained DOFs using converged QFORCE
448  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
449 
450  do j = 1 ,ndof*nnod
451  fstrsolid%unode(j) = fstrsolid%unode(j) + fstrsolid%dunode(j)
452  end do
453  call fstr_updatestate( hecmesh, fstrsolid, fstrdyn%t_delta )
454 
455  end subroutine fstr_advance_dynamic_explicit
456 
457 
458  subroutine forward_increment_lagrange(cstep,ndof,mmat,hecMESH,fstrSOLID,infoCTChange,wkarray,uc)
459  integer, intent(in) :: cstep
460  integer, intent(in) :: ndof
461  real(kind=kreal), intent(in) :: mmat(:)
462  type( hecmwst_local_mesh ), intent(in) :: hecmesh
463  type(fstr_solid), intent(inout) :: fstrSOLID
464  type(fstr_info_contactchange) :: infoCTChange
465  real(kind=kreal), intent(out) :: wkarray(:)
466  real(kind=kreal), intent(out) :: uc(:)
467  integer :: i, j, k, m, grpid, slave, nn, iSS, sid, etype, iter
468  real(kind=kreal) :: fdum, conv, dlambda, shapefunc(l_max_surface_node), lambda(3)
469 
470  call fstr_scan_contact_state_exp( cstep, hecmesh, fstrsolid, infoctchange )
471  if( .not. infoctchange%active ) return
472 
473  uc = 0.0d0
474 
475  iter = 0
476  do
477  wkarray = 0.0d0
478  do i=1,fstrsolid%n_contacts
479  do j= 1, size(fstrsolid%contacts(i)%slave)
480  if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
481  if( fstrsolid%contacts(i)%states(j)%distance>epsilon(1.d0) ) then
482  fstrsolid%contacts(i)%states(j)%state = contactfree
483  cycle
484  endif
485  if( iter==0 ) then
486  fstrsolid%contacts(i)%states(j)%multiplier(:) =0.d0
487  fstrsolid%contacts(i)%states(j)%wkdist =0.d0
488  cycle
489  endif
490  slave = fstrsolid%contacts(i)%slave(j)
491 
492  sid = fstrsolid%contacts(i)%states(j)%surface
493  nn = size( fstrsolid%contacts(i)%master(sid)%nodes )
494  etype = fstrsolid%contacts(i)%master(sid)%etype
495  call getshapefunc( etype, fstrsolid%contacts(i)%states(j)%lpos(:), shapefunc )
496  wkarray( slave ) = -fstrsolid%contacts(i)%states(j)%multiplier(1)
497  do k=1,nn
498  iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
499  wkarray( iss ) = wkarray( iss ) + shapefunc(k) * fstrsolid%contacts(i)%states(j)%multiplier(1)
500  enddo
501  enddo
502  enddo
503 
504  if(iter > 0)then
505  do i=1,fstrsolid%n_contacts
506  do j= 1, size(fstrsolid%contacts(i)%slave)
507  if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
508  slave = fstrsolid%contacts(i)%slave(j)
509  sid = fstrsolid%contacts(i)%states(j)%surface
510  nn = size( fstrsolid%contacts(i)%master(sid)%nodes )
511  etype = fstrsolid%contacts(i)%master(sid)%etype
512  call getshapefunc( etype, fstrsolid%contacts(i)%states(j)%lpos(:), shapefunc )
513  fstrsolid%contacts(i)%states(j)%wkdist = -wkarray( slave )/mmat( (slave-1)*ndof+1 )
514  do k=1,nn
515  iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
516  fstrsolid%contacts(i)%states(j)%wkdist = fstrsolid%contacts(i)%states(j)%wkdist &
517  + shapefunc(k) * wkarray(iss) / mmat( (iss-1)*ndof+1 )
518  enddo
519  enddo
520  enddo
521  endif
522 
523  conv = 0.d0
524  wkarray = 0.d0
525  do i=1,fstrsolid%n_contacts
526  do j= 1, size(fstrsolid%contacts(i)%slave)
527  if( .not. is_contact_active(fstrsolid%contacts(i)%states(j)%state) ) cycle
528  slave = fstrsolid%contacts(i)%slave(j)
529  sid = fstrsolid%contacts(i)%states(j)%surface
530  nn = size( fstrsolid%contacts(i)%master(sid)%nodes )
531  etype = fstrsolid%contacts(i)%master(sid)%etype
532  call getshapefunc( etype, fstrsolid%contacts(i)%states(j)%lpos(:), shapefunc )
533  fdum = 1.d0/mmat( (slave-1)*ndof+1 )
534  do k=1,nn
535  iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
536  fdum = fdum + shapefunc(k)*shapefunc(k)/mmat( (iss-1)*ndof+1 )
537  enddo
538  dlambda= (fstrsolid%contacts(i)%states(j)%distance-fstrsolid%contacts(i)%states(j)%wkdist) /fdum
539  conv = conv + dlambda*dlambda;
540  fstrsolid%contacts(i)%states(j)%multiplier(1) = fstrsolid%contacts(i)%states(j)%multiplier(1) + dlambda
541  if( fstrsolid%contacts(i)%fcoeff>0.d0 ) then
542  if( fstrsolid%contacts(i)%states(j)%state == contactslip ) then
543  fstrsolid%contacts(i)%states(j)%multiplier(2) = &
544  fstrsolid%contacts(i)%fcoeff * fstrsolid%contacts(i)%states(j)%multiplier(1)
545  else ! stick
546  ! fstrSOLID%contacts(i)%states(j)%multiplier(2) =
547  endif
548  endif
549  lambda = fstrsolid%contacts(i)%states(j)%multiplier(1)* fstrsolid%contacts(i)%states(j)%direction
550  wkarray((slave-1)*ndof+1:(slave-1)*ndof+3) = lambda(:)
551  do k=1,nn
552  iss = fstrsolid%contacts(i)%master(sid)%nodes(k)
553  wkarray((iss-1)*ndof+1:(iss-1)*ndof+3) = wkarray((iss-1)*ndof+1:(iss-1)*ndof+3) -lambda(:)*shapefunc(k)
554  enddo
555  enddo
556  enddo
557  if( dsqrt(conv)<1.d-8 ) exit
558  iter = iter+1
559  enddo
560 
561  do i=1,hecmesh%n_node*ndof
562  uc(i) = wkarray(i)/mmat(i)
563  enddo
564  end subroutine forward_increment_lagrange
565 
566 end module fstr_dynamic_nlexplicit
This module contains subroutines for nonlinear explicit dynamic analysis.
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 forward_increment_lagrange(cstep, ndof, mmat, hecMESH, fstrSOLID, infoCTChange, wkarray, uc)
subroutine fstr_prepare_dynamic_explicit(hecMESH, hecMAT, fstrSOLID, fstrEIG, fstrDYN, ndof, nnod, restrt_step_count)
Prepare initial state for explicit dynamic analysis (central difference).
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.
Definition: fstr_Restart.f90:8
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.
Definition: fstr_Update.f90:6
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.
Definition: fstr_Update.f90:28
This module defines common data and basic structures for analysis.
Definition: m_fstr.F90:15
integer(kind=kint), parameter imsg
Definition: m_fstr.F90:113
integer(kind=kint), parameter idbg
Definition: m_fstr.F90:114
This modules just summarizes all modules used in static analysis.
Definition: static_LIB.f90:6
Top-level contact analysis module (System level)
subroutine fstr_scan_contact_state_exp(cstep, hecMESH, fstrSOLID, infoCTChange)
Scanning contact state.
Data for coupling analysis.
Definition: m_fstr.F90:641
Data for DYNAMIC ANSLYSIS (fstrDYNAMIC)
Definition: m_fstr.F90:535
Package of data used by Lanczos eigenvalue solver.
Definition: m_fstr.F90:623
FSTR INNER CONTROL PARAMETERS (fstrPARAM)
Definition: m_fstr.F90:157