FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_dynamic_nlimplicit.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
16  use m_fstr_update
17  use m_fstr_restart
19  use m_fstr_residual
21  use mcontact
24  use m_fstr_timeinc
25  use m_fstr_cutback
26  use m_fstr_spring
27 
28  !-------- for couple -------
30  use m_fstr_rcap_io
31 
32  real(kind=kreal), parameter :: pi = 3.14159265358979323846d0
33 
34 contains
35 
38  subroutine fstr_solve_nlgeom_dynamic_implicit_contactslag(hecMESH,hecMAT,fstrSOLID,fstrEIG &
39  ,fstrDYNAMIC,fstrRESULT,fstrPARAM &
40  ,fstrCPL,hecLagMAT,restart_step_num,restart_substep_num,infoCTChange &
41  ,conMAT,restart_step_count )
42  implicit none
43  !C-- global variable
44  type(hecmwst_local_mesh) :: hecmesh
45  type(hecmwst_matrix) :: hecMAT
46  type(hecmwst_matrix), pointer :: hecMAT0
47  type(fstr_eigen) :: fstrEIG
48  type(fstr_solid) :: fstrSOLID
49  type(hecmwst_result_data) :: fstrRESULT ! unused - kept for interface compatibility
50  type(fstr_param) :: fstrPARAM
51  type(fstr_dynamic) :: fstrDYNAMIC
52  type(fstr_couple) :: fstrCPL !for COUPLE
53  type(hecmwst_matrix_lagrange) :: hecLagMAT
54  type(fstr_info_contactchange) :: infoCTChange
55  type(hecmwst_matrix) :: conMAT
56 
57  !C-- local variable
58  integer(kind=kint) :: nnod, ndof, nn
59  integer(kind=kint) :: i, tot_step_print, CBbound
60  real(kind=kreal) :: time_1, time_2, factor
61  integer(kind=kint) :: sub_step
62 
63  integer(kind=kint) :: restart_step_num, restart_substep_num, restart_step_count, tot_step, step_count
64  integer(kind=kint) :: ctAlgo
65  integer(kind=kint) :: max_iter_contact
66  real(kind=kreal) :: converg_dlag
67  type(fstr_info_contactchange) :: infoctchange_bak
68 
69  logical :: is_outpoint
70  integer(kind=kint) :: n_node_global
71  logical :: is_mat_symmetric, is_interaction_active
72 
73  if(hecmesh%my_rank==0) call fstr_timeinc_printstatus_init
74 
75  is_interaction_active = ( associated( fstrsolid%contacts ) .or. associated( fstrsolid%embeds ) )
76 
77  nullify(hecmat0)
78 
79  ! sum of n_node among all subdomains (to be used to calc res)
80  n_node_global = hecmesh%nn_internal
81  call hecmw_allreduce_i1(hecmesh,n_node_global,hecmw_sum)
82 
83  ctalgo = fstrparam%contact_algo
84 
85  if( hecmat%Iarray(99)==4 .and. .not.fstr_is_matrixstruct_symmetric(fstrsolid,hecmesh) ) then
86  write(*,*) ' This type of direct solver is not yet available in such case ! '
87  write(*,*) ' Please use intel MKL direct solver !'
88  call hecmw_abort(hecmw_comm_get_comm())
89  endif
90 
91  hecmat%NDOF=hecmesh%n_dof
92 
93  nnod=hecmesh%n_node
94  ndof=hecmat%NDOF
95  nn=ndof*ndof
96 
97  if( associated( fstrsolid%contacts ) ) then
98  call initialize_contact_output_vectors(fstrsolid,hecmat)
99  call setup_contact_elesurf_for_area( 1, hecmesh, fstrsolid )
100  endif
101 
102  !!-- initial value
103  time_1 = hecmw_wtime()
104 
105  !C-- check parameters
106  if(dabs(fstrdynamic%beta) < 1.0e-20) then
107  if( hecmesh%my_rank == 0 ) then
108  write(imsg,*) 'stop due to Newmark-beta = 0'
109  endif
110  call hecmw_abort( hecmw_comm_get_comm())
111  endif
112 
113  !C-- matrix [M] lumped mass matrix
114  if(fstrdynamic%idx_mas == 1) then
115  call setmass(fstrsolid,hecmesh,hecmat,fstreig)
116 
117  !C-- consistent mass matrix
118  else if(fstrdynamic%idx_mas == 2) then
119  if( hecmesh%my_rank .eq. 0 ) then
120  write(imsg,*) 'stop: consistent mass matrix is not yet available !'
121  endif
122  call hecmw_abort( hecmw_comm_get_comm())
123  endif
124 
125  hecmat%Iarray(98) = 1 !Assembly complete
126  hecmat%Iarray(97) = 1 !Need numerical factorization
127 
128  !C-- initialize variables
129  if( restart_step_num == 1 .and. fstrdynamic%VarInitialize .and. abs(fstrdynamic%ray_m) > 1.0d-15 ) &
130  call dynamic_init_varibles( hecmesh, hecmat, fstrsolid, fstreig, fstrdynamic, fstrparam )
131 
132  !C-- output of initial state
133  if( restart_step_num == 1 ) then
134  call fstr_dynamic_output(1, 0, 0.d0, hecmesh, fstrsolid, fstrdynamic, fstrparam, .true.)
135  call dynamic_output_monit(1, 0, 0.d0, hecmesh, fstrparam, fstrdynamic, fstreig, fstrsolid)
136  endif
137 
138  fstrdynamic%VEC3(:) =0.d0
139  hecmat%X(:) =0.d0
140 
142  call fstr_scan_contact_state(restart_step_num, restart_step_num, 0, fstrdynamic%t_delta, &
143  ctalgo, hecmesh, fstrsolid, infoctchange)
144 
145  call hecmw_mat_copy_profile( hecmat, conmat )
146 
147  if ( fstr_is_contact_active() ) then
148  call fstr_mat_con_contact( restart_step_num, ctalgo, hecmat, fstrsolid, heclagmat, &
149  infoctchange, conmat, fstr_is_contact_active())
150  elseif( hecmat%Iarray(99)==4 ) then
151  write(*,*) ' This type of direct solver is not yet available in such case ! '
152  write(*,*) ' Please change solver type to intel MKL direct solver !'
153  call hecmw_abort(hecmw_comm_get_comm())
154  endif
155  is_mat_symmetric = fstr_is_matrixstruct_symmetric(fstrsolid,hecmesh)
156  call solve_lineq_contact_init(hecmesh,hecmat,heclagmat,is_mat_symmetric)
157 
158  fstrsolid%FACTOR = 0.0d0
159  call fstr_cutback_init( hecmesh, fstrsolid, fstrparam )
160  call fstr_cutback_save( fstrsolid, infoctchange, infoctchange_bak )
161 
162  step_count = restart_step_count
163  do tot_step=1, fstrsolid%nstep_tot
164  tot_step_print = tot_step+restart_step_num-1
165  if(hecmesh%my_rank==0) write(*,*) ''
166  if(hecmesh%my_rank==0) write(*,'(a,i5)') ' loading step=',tot_step_print
167 
168  sub_step = restart_substep_num
169  do while(.true.)
170  if (ndof == 4 .and. hecmesh%my_rank==0) write(*,'(a,i5)')"iter: ",sub_step
171  ! ----- time history of factor
172  call fstr_timeinc_settimeincrement( fstrsolid%step_ctrl(tot_step), fstrparam, sub_step, &
173  & fstrsolid%NRstat_i, fstrsolid%NRstat_r, fstrsolid%AutoINC_stat, fstrsolid%CutBack_stat )
174 
175  fstrdynamic%t_curr = fstr_get_time()
176  fstrdynamic%t_delta = fstr_get_timeinc()
177 
178  call fstr_newton_dynamic_contactslag(tot_step, hecmesh, hecmat, fstrsolid, fstreig, &
179  fstrdynamic, fstrparam, fstrcpl, heclagmat, infoctchange, conmat, &
180  restart_step_num, hecmat0, sub_step, fstrdynamic%t_curr, fstrdynamic%t_delta)
181 
182  ! Time Increment
183  if( hecmesh%my_rank == 0 ) call fstr_timeinc_printstatus( fstrsolid%step_ctrl(tot_step), fstrparam, &
184  & tot_step_print, sub_step, fstrsolid%NRstat_i, fstrsolid%NRstat_r, &
185  & fstrsolid%AutoINC_stat, fstrsolid%CutBack_stat )
186  if( fstr_cutback_active() ) then
187 
188  if( fstrsolid%CutBack_stat == 0 ) then ! converged
189  call fstr_cutback_save( fstrsolid, infoctchange, infoctchange_bak ) ! save analysis state
190  call fstr_proceed_time() ! current time += time increment
191  fstrdynamic%t_curr = fstr_get_time()
192 
193  else ! not converged
194  cbbound = fstrparam%ainc(fstrsolid%step_ctrl(tot_step)%AincParam_id)%CBbound
195  if( fstrsolid%CutBack_stat == cbbound ) then
196  if( hecmesh%my_rank == 0 ) then
197  write(*,*) 'Number of successive cutback reached max number: ',cbbound
198  call fstr_timeinc_printstatus_final(.false.)
199  endif
200  call hecmw_abort( hecmw_comm_get_comm() )
201  endif
202  call fstr_cutback_load( fstrsolid, infoctchange, infoctchange_bak ) ! load analysis state
203  call fstr_set_contact_active( infoctchange%contactNode_current > 0 )
204 
205  ! restore matrix structure for slagrange contact analysis
206  if( is_interaction_active .and. fstrparam%contact_algo == kcaslagrange ) then
207  call fstr_mat_con_contact( tot_step, fstrparam%contact_algo, hecmat, fstrsolid, heclagmat, &
208  & infoctchange, conmat, fstr_is_contact_active())
209  conmat%B(:) = 0.0d0
210  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh))
211  endif
212  if( hecmesh%my_rank == 0 ) write(*,*) '### State has been restored at time =',fstr_get_time()
213 
214  !stop if # of substeps reached upper bound.
215  if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep ) then
216  if( hecmesh%my_rank == 0 ) then
217  write(*,'(a,i5,a,f6.3)') '### Number of substeps reached max number: at total_step=', &
218  & tot_step_print, ' time=', fstr_get_time()
219  endif
220  call hecmw_abort( hecmw_comm_get_comm())
221  endif
222 
223  ! output time
224  time_2 = hecmw_wtime()
225  if( hecmesh%my_rank==0) write(imsg,'(a,",",2(I8,","),f10.2)') &
226  & 'step, substep, solve (sec) :', tot_step_print, sub_step, time_2 - time_1
227  cycle
228  endif
229  else
230  if( fstrsolid%CutBack_stat > 0 ) stop
231  call fstr_proceed_time() ! current time += time increment
232  fstrdynamic%t_curr = fstr_get_time()
233  endif
234 
235  step_count = step_count + 1
236 
237  ! ----- Result output (include visualize output)
238  is_outpoint = fstr_timeinc_istimepoint( fstrsolid%step_ctrl(tot_step), fstrparam ) &
239  & .or. fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) )
240  !C-- output new displacement, velocity and acceleration
241  call fstr_dynamic_output(tot_step, step_count, fstrdynamic%t_curr, hecmesh, fstrsolid, fstrdynamic, fstrparam, is_outpoint)
242 
243  !C-- output result of monitoring node
244  call dynamic_output_monit(tot_step, i, fstrdynamic%t_curr, hecmesh, fstrparam, fstrdynamic, fstreig, fstrsolid)
245 
246  !--- Restart info
247  if( fstrdynamic%restart_nout > 0 ) then
248  if( mod(step_count,fstrdynamic%restart_nout).eq.0 ) then
249  call fstr_write_restart_dyna_nl(tot_step,sub_step,hecmesh,fstrsolid,fstrdynamic,fstrparam,&
250  .false.,infoctchange%contactNode_current,step_count)
251  endif
252  endif
253 
254  !if time reached the end time of step, exit loop.
255  if( fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) ) ) exit
256 
257  if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep ) then
258  if( hecmesh%my_rank == 0 ) then
259  write(*,'(a,i5,a,f6.3)') '### Number of substeps reached max number: at total_step=', &
260  & tot_step_print, ' time=', fstr_get_time()
261  endif
262  if( hecmesh%my_rank == 0 ) call fstr_timeinc_printstatus_final(.false.)
263  stop !stop if # of substeps reached upper bound.
264  endif
265 
266  sub_step = sub_step + 1
267  enddo
268 
269  !--- Restart at the end of step
270  if( fstrdynamic%restart_nout > 0 ) then
271  call fstr_write_restart_dyna_nl(tot_step,sub_step,hecmesh,fstrsolid,fstrdynamic,fstrparam,&
272  .true.,infoctchange%contactNode_current,step_count)
273  endif
274 
275  restart_substep_num = 1
276  !C-- end of time step loop
277  enddo
278 
279  if (associated(hecmat0)) then
280  call hecmw_mat_finalize(hecmat0)
281  deallocate(hecmat0)
282  endif
283 
284  ! message
285  if( hecmesh%my_rank == 0 ) then
286  call fstr_timeinc_printstatus_final(.true.)
287  write(imsg,'("### FSTR_SOLVE_NLGEOM FINISHED!")')
288  write(*,'("### FSTR_SOLVE_NLGEOM FINISHED!")')
289  endif
290 
292 
293  subroutine fstr_newton_dynamic_contactslag(cstep, hecMESH, hecMAT, fstrSOLID, fstrEIG, &
294  fstrDYNAMIC, fstrPARAM, fstrCPL, hecLagMAT, infoCTChange, conMAT, &
295  restart_step_num, hecMAT0, istep, t_curr, t_delta)
296  implicit none
297  !C-- arguments
298  integer(kind=kint), intent(in) :: cstep, restart_step_num, istep
299  real(kind=kreal), intent(in) :: t_curr, t_delta
300  type(hecmwst_local_mesh) :: hecmesh
301  type(hecmwst_matrix) :: hecMAT
302  type(hecmwst_matrix), pointer :: hecMAT0
303  type(fstr_solid) :: fstrSOLID
304  type(fstr_eigen) :: fstrEIG
305  type(fstr_dynamic) :: fstrDYNAMIC
306  type(fstr_param) :: fstrPARAM
307  type(fstr_couple) :: fstrCPL
308  type(hecmwst_matrix_lagrange) :: hecLagMAT
309  type(fstr_info_contactchange) :: infoCTChange
310  type(hecmwst_matrix) :: conMAT
311 
312  !C-- local variables
313  integer(kind=kint) :: j, kk, idm, imm
314  integer(kind=kint) :: iter
315  real(kind=kreal) :: a1, a2, a3, b1, b2, b3, c1, c2
316  real(kind=kreal) :: coef(6)
317  real(kind=kreal) :: res, res1, res0, relres
318  integer(kind=kint) :: count_step, stepcnt
319  real(kind=kreal) :: maxdlag
320  integer(kind=kint) :: contact_changed_global
321  logical :: is_mat_symmetric
322  integer :: istat
323  logical :: is_cycle
324  integer(kind=kint) :: ctAlgo, max_iter_contact
325  integer(kind=kint) :: nnod, ndof, nn
326  real(kind=kreal) :: converg_dlag
327  real(kind=kreal), allocatable :: coord(:)
328  integer(kind=kint) :: iterStatus, nresid, n_node_global
329  real(kind=kreal), allocatable :: resid_work(:)
330 
331  fstrsolid%NRstat_i(:) = 0 ! logging newton iteration(init)
332 
333  !C-- initialize local variables
334  n_node_global = hecmesh%nn_internal
335  call hecmw_allreduce_i1(hecmesh, n_node_global, hecmw_sum)
336  ctalgo = fstrparam%contact_algo
337  max_iter_contact = fstrsolid%step_ctrl(cstep)%max_contiter
338  converg_dlag = fstrsolid%step_ctrl(cstep)%converg_lag
339  nnod = hecmesh%n_node
340  ndof = hecmat%NDOF
341  nn = ndof*ndof
342  allocate(coord(hecmesh%n_node*ndof))
343  allocate(resid_work(hecmesh%n_node*ndof + conmat%NP*ndof))
344 
345  a1 = .5d0/fstrdynamic%beta - 1.d0
346  a2 = 1.d0/(fstrdynamic%beta*t_delta)
347  a3 = 1.d0/(fstrdynamic%beta*t_delta*t_delta)
348  b1 = ( .5d0*fstrdynamic%gamma/fstrdynamic%beta - 1.d0 )*t_delta
349  b2 = fstrdynamic%gamma/fstrdynamic%beta - 1.d0
350  b3 = fstrdynamic%gamma/(fstrdynamic%beta*t_delta)
351  c1 = 1.d0 + fstrdynamic%ray_k*b3
352  c2 = a3 + fstrdynamic%ray_m*b3
353 
354  coef(1) = a1; coef(2) = a2; coef(3) = a3
355  coef(4) = b1; coef(5) = b2; coef(6) = b3
356 
357  if(hecmesh%my_rank==0) then
358  write(*,'(A)')'-------------------------------------------------'
359  write(*,'('' time step='',i10,'' time='',1pe13.4e3)') istep,t_curr
360  endif
361 
362  do j = 1 ,ndof*nnod
363  fstrdynamic%VEC1(j) = a1*fstrdynamic%ACC(j,1) + a2*fstrdynamic%VEL(j,1)
364  fstrdynamic%VEC2(j) = b1*fstrdynamic%ACC(j,1) + b2*fstrdynamic%VEL(j,1)
365  enddo
366 
367  count_step = 0
368  stepcnt = 0
369 
370  !C for couple analysis
371  do
372  fstrsolid%dunode(:) =0.d0
373  ! call fstr_UpdateEPState( hecMESH, fstrSOLID )
374  call fstr_solve_dynamic_nlimplicit_couple_init(fstrparam, fstrcpl)
375 
376  loopforcontactanalysis: do while( .true. )
377  count_step = count_step + 1
378 
379  ! ----- Inner Iteration
380  res0 = 0.d0
381  res1 = 0.d0
382  relres = 1.d0
383 
384  do iter = 1, fstrsolid%step_ctrl(cstep)%max_iter
385  stepcnt=stepcnt+1
386  call fstr_creatematrix_and_dampingforce( hecmesh, hecmat, fstrsolid, t_curr, t_delta, fstrdynamic, coef )
387 
388  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
389 
390  !C-- mechanical boundary condition
391  call dynamic_mat_ass_load (cstep, t_curr+t_delta, hecmesh, hecmat, fstrsolid, fstrdynamic, fstrparam, iter )
392  do j=1, hecmesh%n_node* hecmesh%n_dof
393  hecmat%B(j) = hecmat%B(j) - fstrsolid%QFORCE(j) + fstrsolid%DFORCE(j)
394  enddo
395 
396  call fstr_update_ndforce_spring( cstep, hecmesh, fstrsolid, hecmat%B )
397 
398  !C for couple analysis
399  call fstr_solve_dynamic_nlimplicit_couple_pre(hecmesh, hecmat, fstrsolid, &
400  & fstrparam, fstrdynamic, fstrcpl, restart_step_num, istep)
401 
402  call hecmw_mat_clear( conmat )
403  call hecmw_mat_clear_b( conmat )
404  conmat%X = 0.0d0
405 
406  if( fstr_is_contact_active() ) then
407  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
408  call fstr_addcontactstiffness(cstep,ctalgo,iter,hecmesh,conmat,heclagmat,fstrsolid)
409  endif
410 
411  !C-- geometrical boundary condition
412  call dynamic_mat_ass_bc (cstep, hecmesh, hecmat, fstrsolid, fstrdynamic, &
413  & fstrparam, heclagmat, t_curr+t_delta, stepcnt, conmat=conmat)
414  call dynamic_mat_ass_bc_vl(cstep, hecmesh, hecmat, fstrsolid, fstrdynamic, &
415  & fstrparam, heclagmat, t_curr+t_delta, stepcnt, conmat=conmat)
416  call dynamic_mat_ass_bc_ac(cstep, hecmesh, hecmat, fstrsolid, fstrdynamic, &
417  & fstrparam, heclagmat, t_curr+t_delta, stepcnt, conmat=conmat)
418 
419  ! ----- check convergence
420  call fstr_assemble_residual_contact(hecmat, heclagmat, conmat, hecmesh, resid_work, nresid)
421 
422  if( .not.fstr_is_contact_active() ) then
423  maxdlag = 0.0d0
424  elseif( abs(maxdlag) < 1.0d-15) then
425  maxdlag = 1.0d0
426  endif
427  call hecmw_allreduce_r1(hecmesh, maxdlag, hecmw_max)
428 
429  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrpr, &
430  ndof, iter, istep, cstep, &
431  resid_work, nresid, &
432  res0, res, &
433  n_node_global, &
434  iterstatus, &
435  maxdlag, converg_dlag)
436  if (iterstatus == kitrconverged) exit
437  if (iterstatus == kitrdiverged .or. iterstatus == kitrfloatingerror) then
438  fstrsolid%NRstat_i(knstciter) = count_step
439  return
440  endif
441 
442  ! ---- For Parallel Contact with Multi-Partition Domains
443  hecmat%X = 0.0d0
444  call fstr_set_current_config_to_mesh(hecmesh,fstrsolid,coord)
445  call solve_lineq_contact(hecmesh,hecmat,heclagmat,conmat,istat,1.0d0,fstr_is_contact_active())
446  call fstr_recover_initial_config_to_mesh(hecmesh,fstrsolid,coord)
447  ! ----- check matrix solver error
448  if( istat /= 0 ) then
449  if( hecmesh%my_rank == 0) then
450  write( *,'(a,i5,a,i5)') ' ### Fail to Converge : at total_step=', cstep, ' sub_step=', istep
451  end if
452  fstrsolid%NRstat_i(knstdresn) = 4
453  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
454  return
455  end if
456 
457  ! ----- update external nodal displacement increments
458  call hecmw_update_r (hecmesh, hecmat%X, hecmat%NP, hecmat%NDOF)
459 
460  ! ----- update the strain, stress, and internal force
461  do j=1,hecmesh%n_node*ndof
462  fstrsolid%dunode(j) = fstrsolid%dunode(j)+hecmat%X(j)
463  enddo
464  call fstr_updatenewton( hecmesh, hecmat, fstrsolid, t_curr, &
465  & t_delta,iter, fstrdynamic%strainEnergy )
466 
467  ! ----- update reaction force at constrained DOFs using converged QFORCE
468  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
469 
470  ! ----- update the Lagrange multipliers
471  ! Done before the nlgeom early-exit so the multipliers are accumulated
472  ! even for infinitesimal analysis. Otherwise hecLagMAT%lagrange stays
473  ! zero when NONLINEAR is not specified, and the contact output forces
474  ! CONT_NFORCE/CONT_FRIC (computed from the multipliers) are always zero
475  ! even though contact is enforced. Matches the unconditional update in
476  ! the static path (fstr_solve_NonLinear).
477  if( fstr_is_contact_active() ) then
478  maxdlag = 0.0d0
479  do j=1,heclagmat%num_lagrange
480  heclagmat%lagrange(j) = heclagmat%lagrange(j) + hecmat%X(hecmesh%n_node*ndof+j)
481  if(dabs(hecmat%X(hecmesh%n_node*ndof+j))>maxdlag) maxdlag=dabs(hecmat%X(hecmesh%n_node*ndof+j))
482  enddo
483  endif
484 
485  if(.not. fstrparam%nlgeom) exit
486  enddo
487 
488  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
489  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
490 
491  ! ----- compute CONT_NFORCE/CONT_FRIC for output
492  if( fstr_is_contact_active() ) &
493  call fstr_calc_contact_output_force(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
494 
495  call fstr_scan_contact_state(cstep, istep, count_step, t_delta, ctalgo, &
496  hecmesh, fstrsolid, infoctchange)
497 
498  if( hecmat%Iarray(99)==4 .and. .not. fstr_is_contact_active() ) then
499  write(*,*) ' This type of direct solver is not yet available in such case ! '
500  write(*,*) ' Please use intel MKL direct solver !'
501  call hecmw_abort(hecmw_comm_get_comm())
502  endif
503 
504  is_mat_symmetric = fstr_is_matrixstruct_symmetric(fstrsolid,hecmesh)
505  contact_changed_global=0
506  if( fstr_is_contact_conv(ctalgo,infoctchange,hecmesh) ) then
507  exit loopforcontactanalysis
508  elseif( fstr_is_matrixstructure_changed(infoctchange) ) then
509  call fstr_mat_con_contact( cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
510  contact_changed_global=1
511  endif
512  call hecmw_allreduce_i1(hecmesh,contact_changed_global,hecmw_max)
513  if (contact_changed_global > 0) then
514  call hecmw_mat_clear_b( hecmat )
515  call hecmw_mat_clear_b( conmat )
516  call solve_lineq_contact_init(hecmesh,hecmat,heclagmat,is_mat_symmetric)
517  endif
518 
519  if( count_step > max_iter_contact ) exit loopforcontactanalysis
520 
521  ! ----- check divergence
522  if( count_step >= fstrsolid%step_ctrl(cstep)%max_contiter ) then
523  if( hecmesh%my_rank == 0) then
524  write( *,'(a,i5,a,i5)') ' ### Contact failed to Converge : at total_step=', cstep, ' sub_step=', istep
525  end if
526  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
527  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
528  fstrsolid%NRstat_i(knstdresn) = 3
529  return
530  end if
531 
532  enddo loopforcontactanalysis
533 
534  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
535 
536  !C for couple analysis
537  call fstr_solve_dynamic_nlimplicit_couple_post(hecmesh, hecmat, fstrsolid, &
538  & fstrparam, fstrdynamic, fstrcpl, a1, a2, a3, b1, b2, b3, istep, is_cycle)
539  if(is_cycle) cycle
540  exit
541  enddo
542 
543  !C-- new displacement, velocity and acceleration
544  fstrdynamic%kineticEnergy = 0.0d0
545  do j = 1 ,ndof*nnod
546  fstrdynamic%ACC (j,2) = -a1*fstrdynamic%ACC(j,1) - a2*fstrdynamic%VEL(j,1) + &
547  a3*fstrsolid%dunode(j)
548  fstrdynamic%VEL (j,2) = -b1*fstrdynamic%ACC(j,1) - b2*fstrdynamic%VEL(j,1) + &
549  b3*fstrsolid%dunode(j)
550  fstrdynamic%ACC (j,1) = fstrdynamic%ACC (j,2)
551  fstrdynamic%VEL (j,1) = fstrdynamic%VEL (j,2)
552 
553  fstrsolid%unode(j) = fstrsolid%unode(j)+fstrsolid%dunode(j)
554  fstrdynamic%DISP(j,2) = fstrsolid%unode(j)
555 
556  fstrdynamic%kineticEnergy = fstrdynamic%kineticEnergy + &
557  0.5d0*fstreig%mass(j)*fstrdynamic%VEL(j,2)*fstrdynamic%VEL(j,2)
558  enddo
559 
560  call fstr_updatestate( hecmesh, fstrsolid, t_delta )
561  call fstr_update_contact_tangentforce( cstep, fstrsolid )
562 
563  deallocate(coord)
564  deallocate(resid_work)
565  fstrsolid%CutBack_stat = 0
566  end subroutine fstr_newton_dynamic_contactslag
567 
568  subroutine fstr_solve_dynamic_nlimplicit_couple_init(fstrPARAM, fstrCPL)
569  implicit none
570  type(fstr_param) :: fstrparam
571  type(fstr_couple) :: fstrCPL
572  if( fstrparam%fg_couple == 1) then
573  if( fstrparam%fg_couple_type==1 .or. &
574  fstrparam%fg_couple_type==3 .or. &
575  fstrparam%fg_couple_type==5 ) call fstr_rcap_get( fstrcpl )
576  endif
578 
579  subroutine fstr_solve_dynamic_nlimplicit_couple_pre(hecMESH, hecMAT, fstrSOLID, &
580  & fstrPARAM, fstrDYNAMIC, fstrCPL, restart_step_num, i)
581  implicit none
582  type(hecmwst_local_mesh) :: hecMESH
583  type(hecmwst_matrix) :: hecMAT
584  type(fstr_solid) :: fstrSOLID
585  type(fstr_param) :: fstrPARAM
586  type(fstr_dynamic) :: fstrDYNAMIC
587  type(fstr_couple) :: fstrCPL
588  integer(kint) :: kkk0, kkk1, j, kk, i, restart_step_num
589  real(kreal) :: bsize
590 
591  if( fstrparam%fg_couple == 1) then
592  if( fstrparam%fg_couple_first /= 0 ) then
593  bsize = dfloat( i ) / dfloat( fstrparam%fg_couple_first )
594  if( bsize > 1.0 ) bsize = 1.0
595  do kkk0 = 1, fstrcpl%coupled_node_n
596  kkk1 = 3 * kkk0
597  fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
598  fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
599  fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
600  enddo
601  endif
602  if( fstrparam%fg_couple_window > 0 ) then
603  j = i - restart_step_num + 1
604  kk = fstrdynamic%n_step - restart_step_num + 1
605  bsize = 0.5*(1.0-cos(2.0*pi*dfloat(j)/dfloat(kk)))
606  do kkk0 = 1, fstrcpl%coupled_node_n
607  kkk1 = 3 * kkk0
608  fstrcpl%trac(kkk1-2) = bsize * fstrcpl%trac(kkk1-2)
609  fstrcpl%trac(kkk1-1) = bsize * fstrcpl%trac(kkk1-1)
610  fstrcpl%trac(kkk1 ) = bsize * fstrcpl%trac(kkk1 )
611  enddo
612  endif
613  call dynamic_mat_ass_couple( hecmesh, hecmat, fstrsolid, fstrcpl )
614  endif
616 
617  subroutine fstr_solve_dynamic_nlimplicit_couple_post(hecMESH, hecMAT, fstrSOLID, &
618  & fstrPARAM, fstrDYNAMIC, fstrCPL, a1, a2, a3, b1, b2, b3, i, is_cycle)
619  implicit none
620  type(hecmwst_local_mesh) :: hecMESH ! unused - kept for interface compatibility
621  type(hecmwst_matrix) :: hecMAT ! unused - kept for interface compatibility
622  type(fstr_solid) :: fstrSOLID
623  type(fstr_param) :: fstrPARAM
624  type(fstr_dynamic) :: fstrDYNAMIC
625  type(fstr_couple) :: fstrCPL
626  integer(kint) :: kkk0, kkk1, j, i, revocap_flag
627  real(kreal) :: a1, a2, a3, b1, b2, b3
628  logical :: is_cycle
629 
630  is_cycle = .false.
631 
632  if( fstrparam%fg_couple == 1 ) then
633  if( fstrparam%fg_couple_type>1 ) then
634  do j=1, fstrcpl%coupled_node_n
635  if( fstrcpl%dof == 3 ) then
636  kkk0 = j*3
637  kkk1 = fstrcpl%coupled_node(j)*3
638 
639  fstrcpl%disp (kkk0-2) = fstrsolid%unode(kkk1-2) + fstrsolid%dunode(kkk1-2)
640  fstrcpl%disp (kkk0-1) = fstrsolid%unode(kkk1-1) + fstrsolid%dunode(kkk1-1)
641  fstrcpl%disp (kkk0 ) = fstrsolid%unode(kkk1 ) + fstrsolid%dunode(kkk1 )
642 
643  fstrcpl%velo (kkk0-2) = -b1*fstrdynamic%ACC(kkk1-2,1) - b2*fstrdynamic%VEL(kkk1-2,1) + &
644  b3*fstrsolid%dunode(kkk1-2)
645  fstrcpl%velo (kkk0-1) = -b1*fstrdynamic%ACC(kkk1-1,1) - b2*fstrdynamic%VEL(kkk1-1,1) + &
646  b3*fstrsolid%dunode(kkk1-1)
647  fstrcpl%velo (kkk0 ) = -b1*fstrdynamic%ACC(kkk1,1) - b2*fstrdynamic%VEL(kkk1,1) + &
648  b3*fstrsolid%dunode(kkk1)
649  fstrcpl%accel(kkk0-2) = -a1*fstrdynamic%ACC(kkk1-2,1) - a2*fstrdynamic%VEL(kkk1-2,1) + &
650  a3*fstrsolid%dunode(kkk1-2)
651  fstrcpl%accel(kkk0-1) = -a1*fstrdynamic%ACC(kkk1-1,1) - a2*fstrdynamic%VEL(kkk1-1,1) + &
652  a3*fstrsolid%dunode(kkk1-1)
653  fstrcpl%accel(kkk0 ) = -a1*fstrdynamic%ACC(kkk1,1) - a2*fstrdynamic%VEL(kkk1,1) + &
654  a3*fstrsolid%dunode(kkk1)
655  else
656  kkk0 = j*2
657  kkk1 = fstrcpl%coupled_node(j)*2
658 
659  fstrcpl%disp (kkk0-1) = fstrsolid%unode(kkk1-1) + fstrsolid%dunode(kkk1-1)
660  fstrcpl%disp (kkk0 ) = fstrsolid%unode(kkk1 ) + fstrsolid%dunode(kkk1 )
661 
662  fstrcpl%velo (kkk0-1) = -b1*fstrdynamic%ACC(kkk1-1,1) - b2*fstrdynamic%VEL(kkk1-1,1) + &
663  b3*fstrsolid%dunode(kkk1-1)
664  fstrcpl%velo (kkk0 ) = -b1*fstrdynamic%ACC(kkk1,1) - b2*fstrdynamic%VEL(kkk1,1) + &
665  b3*fstrsolid%dunode(kkk1)
666  fstrcpl%accel(kkk0-1) = -a1*fstrdynamic%ACC(kkk1-1,1) - a2*fstrdynamic%VEL(kkk1-1,1) + &
667  a3*fstrsolid%dunode(kkk1-1)
668  fstrcpl%accel(kkk0 ) = -a1*fstrdynamic%ACC(kkk1,1) - a2*fstrdynamic%VEL(kkk1,1) + &
669  a3*fstrsolid%dunode(kkk1)
670  endif
671  enddo
672  call fstr_rcap_send( fstrcpl )
673  endif
674 
675  select case ( fstrparam%fg_couple_type )
676  case (4)
677  call fstr_rcap_get( fstrcpl )
678  case (5)
679  call fstr_get_convergence( revocap_flag )
680  if( revocap_flag==0 ) is_cycle = .true.
681  case (6)
682  call fstr_get_convergence( revocap_flag )
683  if( revocap_flag==0 ) then
684  call fstr_rcap_get( fstrcpl )
685  is_cycle = .true.
686  else
687  if( i /= fstrdynamic%n_step ) call fstr_rcap_get( fstrcpl )
688  endif
689  end select
690  endif
692 
693 end module fstr_dynamic_nlimplicit
This module contains subroutines for nonlinear implicit dynamic analysis.
subroutine fstr_solve_nlgeom_dynamic_implicit_contactslag(hecMESH, hecMAT, fstrSOLID, fstrEIG, fstrDYNAMIC, fstrRESULT, fstrPARAM, fstrCPL, hecLagMAT, restart_step_num, restart_substep_num, infoCTChange, conMAT, restart_step_count)
This subroutine provides function of nonlinear implicit dynamic analysis using the Newmark method....
subroutine fstr_solve_dynamic_nlimplicit_couple_init(fstrPARAM, fstrCPL)
subroutine fstr_solve_dynamic_nlimplicit_couple_pre(hecMESH, hecMAT, fstrSOLID, fstrPARAM, fstrDYNAMIC, fstrCPL, restart_step_num, i)
subroutine fstr_solve_dynamic_nlimplicit_couple_post(hecMESH, hecMAT, fstrSOLID, fstrPARAM, fstrDYNAMIC, fstrCPL, a1, a2, a3, b1, b2, b3, i, is_cycle)
real(kind=kreal), parameter pi
subroutine fstr_newton_dynamic_contactslag(cstep, hecMESH, hecMAT, fstrSOLID, fstrEIG, fstrDYNAMIC, fstrPARAM, fstrCPL, hecLagMAT, infoCTChange, conMAT, restart_step_num, hecMAT0, istep, t_curr, t_delta)
This module provides functions of reconstructing.
subroutine, public fstr_mat_con_contact(cstep, contact_algo, hecMAT, fstrSOLID, hecLagMAT, infoCTChange, conMAT, is_contact_active_flag)
this subroutine reconstructs node-based (stiffness) matrix structure \corresponding to contact state
subroutine, public fstr_save_originalmatrixstructure(hecMAT)
This subroutine saves original matrix structure constructed originally by hecMW_matrix.
logical function, public fstr_is_matrixstruct_symmetric(fstrSOLID, hecMESH)
this function judges whether sitiffness matrix is symmetric or not
This module provides functions to initialize variables when initial velocity or acceleration boundary...
subroutine dynamic_init_varibles(hecMESH, hecMAT, fstrSOLID, fstrEIG, fstrDYNAMIC, fstrPARAM)
This module contains functions to set acceleration boundary condition in dynamic analysis.
subroutine dynamic_mat_ass_bc_ac(cstep, hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, fstrPARAM, hecLagMAT, t_curr, iter, conMAT)
This subrouitne set acceleration boundary condition in dynamic analysis.
This module contains functions to set velocity boundary condition in dynamic analysis.
subroutine dynamic_mat_ass_bc_vl(cstep, hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, fstrPARAM, hecLagMAT, t_curr, iter, conMAT)
This subrouitne set velocity boundary condition in dynamic analysis.
This module contains functions to set displacement boundary condition in dynamic analysis.
subroutine dynamic_mat_ass_bc(cstep, hecMESH, hecMAT, fstrSOLID, fstrDYNAMIC, fstrPARAM, hecLagMAT, t_curr, iter, conMAT)
This subroutine setup disp bundary 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)
This module assembles the tangent stiffness matrix and, in the implicit dynamic case,...
subroutine, public fstr_creatematrix_and_dampingforce(hecMESH, hecMAT, fstrSOLID, time, tincr, fstrDYNAMIC, coef)
Assemble the system matrix and, optionally, the dynamic damping force.
This module provides functions to deal with cutback.
Definition: fstr_Cutback.f90:7
subroutine fstr_cutback_save(fstrSOLID, infoCTChange, infoCTChange_bak)
Save analysis status.
subroutine fstr_cutback_load(fstrSOLID, infoCTChange, infoCTChange_bak)
Load analysis status.
subroutine fstr_cutback_init(hecMESH, fstrSOLID, fstrPARAM)
Initializer of cutback variables.
logical function fstr_cutback_active()
Set up lumped mass matrix.
subroutine setmass(fstrSOLID, hecMESH, hecMAT, fstrEIG)
This module provides a unified convergence check for Newton iteration.
subroutine, public fstr_check_convergence(hecMESH, hecMAT, fstrSOLID, fstrPR, ndof, iter, sub_step, cstep, residual_vec, nresid, resb, res_prev, n_node_global, iterStatus, maxDLag, converg_dlag)
Wrapper that calls fstr_check_convergence_main and applies the common divergence/NaN handling (status...
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_assemble_residual_contact(hecMAT, hecLagMAT, conMAT, hecMESH, resid_vec, nresid)
Assemble contact residual vector (hecMATB + conMATB + Lagrange) into a single vector.
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 spring force.
Definition: fstr_Spring.f90:7
subroutine fstr_update_ndforce_spring(cstep, hecMESH, fstrSOLID, B)
Definition: fstr_Spring.f90:58
subroutine fstr_addspring(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM)
Definition: fstr_Spring.f90:13
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()
subroutine fstr_timeinc_printstatus_final(success_flag)
subroutine fstr_timeinc_printstatus_init
logical function fstr_timeinc_isstepfinished(stepinfo)
subroutine fstr_timeinc_printstatus(stepinfo, fstrPARAM, totstep, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat)
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
subroutine fstr_recover_initial_config_to_mesh(hecMESH, fstrSOLID, coord)
Definition: m_fstr.F90:1170
integer(kind=kint), parameter imsg
Definition: m_fstr.F90:113
integer(kind=kint), parameter kitrfloatingerror
Definition: m_fstr.F90:95
integer(kind=kint), parameter kitrconverged
Definition: m_fstr.F90:93
integer(kind=kint), parameter kcaslagrange
contact analysis algorithm
Definition: m_fstr.F90:61
subroutine fstr_set_current_config_to_mesh(hecMESH, fstrSOLID, coord)
Definition: m_fstr.F90:1157
type(fstr_param), target fstrpr
GLOBAL VARIABLE INITIALIZED IN FSTR_SETUP.
Definition: m_fstr.F90:213
integer(kind=kint), parameter kitrdiverged
Definition: m_fstr.F90:94
This module provides functions to solve sparse system of \linear equitions in the case of contact ana...
subroutine, public solve_lineq_contact_init(hecMESH, hecMAT, hecLagMAT, is_sym)
This subroutine.
subroutine, public solve_lineq_contact(hecMESH, hecMAT, hecLagMAT, conMAT, istat, rf, is_contact_active)
This subroutine.
Top-level contact analysis module (System level)
subroutine fstr_set_contact_active(a)
subroutine fstr_update_ndforce_contact(cstep, ctAlgo, hecMESH, hecLagMAT, fstrSOLID, conMAT)
Compute contact forces for residual vector (conMATB).
logical function fstr_is_matrixstructure_changed(infoCTChange)
logical function fstr_is_contact_conv(ctAlgo, infoCTChange, hecMESH)
subroutine fstr_addcontactstiffness(cstep, ctAlgo, iter, hecMESH, conMAT, hecLagMAT, fstrSOLID)
subroutine fstr_calc_contact_output_force(cstep, ctAlgo, hecMESH, hecLagMAT, fstrSOLID, conMAT)
Compute contact forces for output (CONT_NFORCE/CONT_FRIC).
subroutine fstr_scan_contact_state(cstep, sub_step, cont_step, dt, ctAlgo, hecMESH, fstrSOLID, infoCTChange)
Scanning contact state.
logical function fstr_is_contact_active()
subroutine fstr_update_contact_tangentforce(cstep, fstrSOLID)
Update tangent force.
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