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