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