FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
fstr_solve_NonLinear.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 
9  use m_fstr
10  use m_static_lib
11  use m_static_output
12 
13  use m_fstr_spring
15  use m_fstr_update
17  use m_fstr_ass_load
18  use m_fstr_addbc
19  use m_fstr_residual
20  use m_fstr_restart
21  use m_fstr_elemact
24  use mcontact
27  use hecmw_ebc_defer
28 
29  implicit none
30 
31 contains
32 
33  subroutine fstr_init_newton(hecMESH, hecMAT, fstrSOLID, &
34  & ctime, tincr, iter, cstep, dtime, fstrPARAM, hecLagMAT, ndof, ctAlgo, conMAT)
35  use m_fstr_update
36  implicit none
37  type (hecmwST_local_mesh) :: hecMESH
38  type (hecmwST_matrix) :: hecMAT
39  type (fstr_solid) :: fstrSOLID
40  real(kind=kreal), intent(in) :: ctime
41  real(kind=kreal), intent(in) :: dtime
42  type (fstr_param) :: fstrPARAM
43  real(kind=kreal), intent(inout) :: tincr
44  integer(kind=kint) :: iter
45  integer, intent(in) :: cstep
46  type (hecmwST_matrix_lagrange) :: hecLagMAT
47  integer(kind=kint), intent(inout) :: ndof
48  integer(kind=kint), intent(in) :: ctAlgo
49  type (hecmwST_matrix) :: conMAT
50 
51  hecmat%NDOF = hecmesh%n_dof
52  ndof = hecmat%ndof
53 
54  ! direct solvers choose their factorization mode from this flag (default .true.),
55  ! which nothing on the non-contact path would otherwise set; iterative solvers
56  ! overwrite it from the solution method
57  hecmat%symmetric = fstr_is_tangent_symmetric(fstrsolid, hecmesh)
58 
59  tincr = dtime
60  if( fstrsolid%step_ctrl(cstep)%solution == stepstatic ) tincr = 0.d0
61 
62  fstrsolid%dunode(:) = 0.0d0
63  fstrsolid%NRstat_i(:) = 0 ! logging newton iteration(init)
64 
65  call fstr_ass_load(cstep, ctime+dtime, hecmesh, hecmat, fstrsolid, fstrparam)
66 
67  if( fstrsolid%elemact%ELEMACT_egrp_tot > 0 ) then
68  call fstr_updatenewton(hecmesh, hecmat, fstrsolid, fstrparam, ctime, tincr, 0)
69  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid)
70  endif
71 
72  ! conMAT is hecMAT itself for the contact-free callers (fstr_Newton, fstr_Quasi_Newton);
73  ! clearing it there would wipe the external load just assembled by fstr_ass_load.
74  if( associated(conmat%B) .and. .not. associated(conmat%B, hecmat%B) ) call hecmw_mat_clear_b(conmat)
75  if( fstr_is_contact_active() ) then
76  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
77  ! Consider SPC condition
78  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
79  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
80  endif
81 
82  end subroutine fstr_init_newton
83 
86  subroutine fstr_newton( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, &
87  restrt_step_num, sub_step, ctime, dtime )
88 
89  integer, intent(in) :: cstep
90  type (hecmwST_local_mesh) :: hecMESH
91  type (hecmwST_matrix) :: hecMAT
92  type (fstr_solid) :: fstrSOLID
93  integer, intent(in) :: sub_step
94  real(kind=kreal), intent(in) :: ctime
95  real(kind=kreal), intent(in) :: dtime
96  type (fstr_param) :: fstrPARAM
97  type (hecmwST_matrix_lagrange) :: hecLagMAT
98 
99  type (hecmwST_local_mesh), pointer :: hecMESHmpc
100  type (hecmwST_matrix), pointer :: hecMATmpc
101  type (hecmwST_ebc) :: hecEBC
102  integer(kind=kint) :: ndof
103  integer(kind=kint) :: iter
104  integer(kind=kint) :: stepcnt
105  integer(kind=kint) :: restrt_step_num
106  real(kind=kreal) :: tincr
107  real(kind=kreal), allocatable :: coord(:), p(:)
108  logical :: isLinear = .false.
109  integer(kind=kint) :: iterStatus
110  type(fstr_convergence_state) :: cnvstat
111 
112  call hecmw_mpc_mat_init(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
113 
114  if(.not. fstrparam%nlgeom)then
115  islinear = .true.
116  endif
117 
118  call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof, 0, hecmat)
119 
120  allocate(p(hecmesh%n_node*ndof))
121  allocate(coord(hecmesh%n_node*ndof))
122  p = 0.0d0
123  stepcnt = 0
124 
125  ! ----- Inner Iteration, lagrange multiplier constant
126  do iter=1,fstrsolid%step_ctrl(cstep)%max_iter
127  stepcnt = stepcnt+1
128 
129  call fstr_creatematrix_and_dampingforce( hecmesh, hecmat, fstrsolid, ctime, tincr )
130  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
131 
132  ! ----- Set Boundary condition
133  call hecmw_ebc_init(hecmat, hecebc)
134  call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, stepcnt, hecebc)
135  call hecmw_mpc_mat_ass(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
136  call hecmw_mpc_trans_rhs(hecmesh, hecmat, hecmatmpc)
137  call hecmw_ebc_apply(hecmeshmpc, hecmatmpc, hecebc)
138 
139  !----- SOLVE [Kt]{du}={R}
140  if( sub_step == restrt_step_num .and. iter == 1 ) hecmatmpc%Iarray(98) = 1
141  if( iter == 1 ) then
142  hecmatmpc%Iarray(97) = 2 !Force numerical factorization
143  else
144  hecmatmpc%Iarray(97) = 1 !Need numerical factorization
145  endif
146  hecmatmpc%X = 0.0d0
147  call fstr_set_current_config_to_mesh(hecmeshmpc,fstrsolid,coord)
148  call solve_lineq(hecmeshmpc,hecmatmpc)
149  call fstr_recover_initial_config_to_mesh(hecmeshmpc,fstrsolid,coord)
150  ! ----- check matrix solver error
151  call fstr_check_linear_solver(hecmesh, hecmatmpc, fstrsolid, cstep, sub_step, iterstatus)
152  if( iterstatus /= kitrcontinue ) then
153  call hecmw_ebc_finalize(hecebc)
154  call hecmw_mpc_mat_finalize(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
155  return
156  endif
157  call hecmw_mpc_tback_sol(hecmesh, hecmat, hecmatmpc)
158 
159  ! ----- update the small displacement and the displacement for 1step
160  ! \delta u^k => solver's solution
161  ! \Delta u_{n+1}^{k} = \Delta u_{n+1}^{k-1} + \delta u^k
162  call fstr_apply_solution_increment( hecmesh, fstrsolid, ndof, hecmat%X )
163 
164  call fstr_calc_residual_vector(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
165 
166  if( islinear ) exit
167 
168  ! ----- check convergence
169  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrparam, &
170  ndof, iter, sub_step, cstep, &
171  hecmat%B, cnvstat, iterstatus)
172  if (iterstatus == kitrconverged) exit
173  if (iterstatus == kitrdiverged .or. iterstatus==kitrfloatingerror) then
174  call hecmw_ebc_finalize(hecebc)
175  call hecmw_mpc_mat_finalize(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
176  return
177  endif
178  enddo
179  ! ----- end of inner loop
180 
181  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
182  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
183 
184  ! ----- update the total displacement
185  ! u_{n+1} = u_{n} + \Delta u_{n+1}
186  call fstr_commit_solution_increment( hecmesh, fstrsolid, ndof )
187 
188  call fstr_updatestate( hecmesh, fstrsolid, tincr )
189  ! Update REACTION using current QFORCE
190  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
191 
192  fstrsolid%CutBack_stat = 0
193  deallocate(coord)
194  deallocate(p)
195  call hecmw_ebc_finalize(hecebc)
196  call hecmw_mpc_mat_finalize(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
197  end subroutine fstr_newton
198 
202  subroutine fstr_newton_contactalag( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, &
203  restart_step_num, restart_substep_num, sub_step, ctime, dtime, infoCTChange, conMAT )
204 
205  integer, intent(in) :: cstep
206  type (hecmwST_local_mesh) :: hecMESH
207  type (hecmwST_matrix) :: hecMAT
208  type (fstr_solid) :: fstrSOLID
209  integer, intent(in) :: sub_step
210  real(kind=kreal), intent(in) :: ctime
211  real(kind=kreal), intent(in) :: dtime
212  type (fstr_param) :: fstrPARAM
213  type (fstr_info_contactChange) :: infoCTChange
214  type (hecmwST_matrix_lagrange) :: hecLagMAT
215  type (hecmwST_matrix) :: conMAT
216 
217  type (hecmwST_ebc) :: hecEBC
218  integer(kind=kint) :: ndof
219  integer(kind=kint) :: ctAlgo
220  integer(kind=kint) :: iter
221  integer(kind=kint) :: al_step, n_al_step, stepcnt, count_step
222  real(kind=kreal) :: tincr
223  integer(kind=kint) :: restart_step_num, restart_substep_num
224  logical :: ctchange
225  integer(kind=kint) :: contact_changed_global
226  logical :: need_prof_refresh
227  real(kind=kreal), allocatable :: coord(:)
228  integer(kind=kint) :: istat
229  logical :: is_first_Stiffmatrixcall
230  integer(kind=kint) :: iterStatus, nresid
231  real(kind=kreal), allocatable :: resid_work(:)
232  type(fstr_convergence_state) :: cnvstat
233 
234  ctalgo = fstrparam%contact_algo
235 
236  ! ----- BEGIN lambda transaction: clear working before fstr_init_Newton reads the multipliers -----
237  if( ctalgo == kcaalagrange ) call fstr_begin_lambda_txn( fstrsolid, cstep )
238 
239  call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof, ctalgo, conmat)
240 
241  if( cstep == 1 .and. sub_step == restart_substep_num ) then
243  if( restart_step_num > 1 .or. restart_substep_num > 1 ) then
244  call fstr_set_contact_active_restart( cstep, fstrsolid, infoctchange )
245  infoctchange%contactNode_current = infoctchange%contactNode_previous
246  else
247  if(hecmesh%my_rank==0) write(*,*) "---Scanning initial contact state---"
248  call fstr_scan_contact_state( cstep, sub_step, 0, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
249  endif
250  call hecmw_mat_copy_profile( hecmat, conmat )
251  if ( fstr_is_contact_active() ) then
252  call fstr_mat_con_contact(cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
253  elseif( hecmat%Iarray(99)==4 ) then
254  write(*, *) ' This type of direct solver is not yet available in such case ! '
255  write(*, *) ' Please change the solver type to intel MKL direct solver !'
256  call hecmw_abort(hecmw_comm_get_comm())
257  endif
258  ! the ALag contact terms are treated as symmetric here, unless a contact pair
259  ! asks for the friction cone to follow the normal force, which adds the unsymmetric
260  ! coupling block of getContactStiffness_Alag; material-induced asymmetry is propagated
261  ! by the same predicate
262  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, fstr_is_contactalag_symmetric(fstrsolid, hecmesh))
263  endif
264 
265  hecmat%X = 0.0d0
266 
267  stepcnt = 0
268  allocate(coord(hecmesh%n_node*ndof))
269  allocate(resid_work(hecmesh%n_node*ndof + conmat%NP*ndof))
270 
271  ! ----- Augmentation loop. In case of no contact, it is inactive
272  n_al_step = fstrparam%augiter
273  count_step = 0
274  is_first_stiffmatrixcall = .true.
275 
276  loopforcontactanalysis: do while( .true. )
277  count_step = count_step + 1
278 
279  do al_step = 1, n_al_step
280 
281  if( hecmesh%my_rank == 0) then
282  write(*,*) "Contact iter: ", count_step, " Augmentation iter: ", al_step
283  end if
284 
285  ! ----- Inner Iteration, lagrange multiplier constant
286  do iter = 1,fstrsolid%step_ctrl(cstep)%max_iter
287  stepcnt = stepcnt+1
288 
289  call fstr_creatematrix_and_dampingforce( hecmesh, hecmat, fstrsolid, ctime, tincr )
290  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
291 
292  call hecmw_mat_clear( conmat )
293  conmat%X = 0.0d0
294 
295  ! ----- Contact
296  if( is_first_stiffmatrixcall ) then
297  call fstr_calc_contact_refstiff(cstep, hecmesh, hecmat, fstrsolid)
298  is_first_stiffmatrixcall = .false.
299  endif
300  if( fstr_is_contact_active() ) then
301  call fstr_addcontactstiffness(cstep,ctalgo,iter,hecmesh,conmat,heclagmat,fstrsolid)
302  endif
303 
304  ! ----- Set Boundary condition
305  call hecmw_ebc_init(hecmat, hecebc)
306  call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, stepcnt, hecebc, conmat)
307 
308  !----- SOLVE [Kt]{du}={R}
309  ! ---- For Parallel Contact with Multi-Partition Domains
310  hecmat%X = 0.0d0
311  call fstr_set_current_config_to_mesh(hecmesh,fstrsolid,coord)
312  call solve_lineq_contact(hecmesh, hecmat, heclagmat, conmat, hecebc, istat, 1.0d0, fstr_is_contact_active())
313  call fstr_recover_initial_config_to_mesh(hecmesh,fstrsolid,coord)
314  call hecmw_ebc_finalize(hecebc)
315  ! ----- check matrix solver error
316  call fstr_check_linear_solver(hecmesh, hecmat, fstrsolid, cstep, sub_step, iterstatus, istat)
317  if( iterstatus /= kitrcontinue ) then
318  fstrsolid%NRstat_i(knstciter) = count_step
319  return
320  endif
321 
322  call hecmw_update_r (hecmesh, hecmat%X, hecmat%NP, hecmesh%n_dof)
323 
324  ! ----- update the small displacement and the displacement for 1step
325  ! \delta u^k => solver's solution
326  ! \Delta u_{n+1}^{k} = \Delta u_{n+1}^{k-1} + \delta u^k
327  call fstr_apply_solution_increment( hecmesh, fstrsolid, ndof, hecmat%X )
328 
329  ! ----- update the strain, stress, and internal force
330  call fstr_updatenewton(hecmesh, hecmat, fstrsolid, fstrparam, ctime, tincr, iter)
331 
332  if( fstrsolid%elemact%ELEMACT_egrp_tot > 0 ) then
333  call fstr_update_elemact_solid_by_value( hecmesh, fstrsolid, cstep, ctime+dtime )
334  endif
335 
336  ! ----- Set residual
337  if( fstrsolid%DLOAD_follow /= 0 .or. fstrsolid%CLOAD_ngrp_rot /= 0 ) &
338  call fstr_ass_load(cstep, ctime+dtime, hecmesh, hecmat, fstrsolid, fstrparam)
339 
340  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid, conmat)
341  call hecmw_mat_clear_b( conmat )
342  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
343 
344  ! Consider SPC condition
345  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
346  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
347 
348  call fstr_assemble_residual_contact(hecmat, heclagmat, conmat, hecmesh, resid_work, nresid)
349  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrparam, &
350  ndof, iter, sub_step, cstep, &
351  resid_work, cnvstat, iterstatus, heclagmat)
352  if (iterstatus == kitrconverged) exit
353  if (iterstatus == kitrdiverged .or. iterstatus == kitrfloatingerror) then
354  fstrsolid%NRstat_i(knstciter) = count_step
355  return
356  endif
357 
358  enddo
359  ! ----- end of inner loop
360 
361  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
362  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
363 
364  call fstr_update_contact_multiplier( cstep, ctalgo, hecmesh, heclagmat, fstrsolid, ctchange )
365 
366  ! ----- Set residual for next newton iteration
367  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid, conmat)
368  ! ----- deal with contact boundary
369  call hecmw_mat_clear_b( conmat )
370  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
371  ! Consider SPC condition
372  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
373  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
374 
375  enddo
376  ! ----- end of augmentation loop
377 
378  ! ----- compute CONT_NFORCE/CONT_FRIC for output
379  if( fstr_is_contact_active() ) &
380  call fstr_calc_contact_output_force(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
381 
382  ! ----- deal with contact boundary
383  call fstr_scan_contact_state( cstep, sub_step, count_step, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
384 
385  contact_changed_global = 0
386  ! Mortar safety net: force a rebuild when an active pair's coupling is no longer in the
387  ! matrix profile, even if the structural-change counters stayed silent.
388  need_prof_refresh = .false.
389  if( .not. fstr_is_matrixstructure_changed(infoctchange) ) &
390  need_prof_refresh = fstr_s2s_profile_needs_refresh( cstep, ctalgo, fstrsolid, conmat )
391  if( fstr_is_matrixstructure_changed(infoctchange) .or. need_prof_refresh ) then
392  call fstr_mat_con_contact( cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
393  contact_changed_global = 1
394  endif
395  call hecmw_allreduce_i1(hecmesh, contact_changed_global, hecmw_max)
396  if (contact_changed_global > 0) then
397  call hecmw_mat_clear_b( hecmat )
398  call hecmw_mat_clear_b( conmat )
399  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, fstr_is_contactalag_symmetric(fstrsolid, hecmesh))
400  endif
401 
402  if( fstr_is_contact_conv(ctalgo,infoctchange,hecmesh) .and. .not. ctchange ) exit loopforcontactanalysis
403 
404  ! ----- check divergence
405  if( count_step >= fstrsolid%step_ctrl(cstep)%max_contiter ) then
406  if( hecmesh%my_rank == 0) then
407  write( *,'(a,i5,a,i5)') ' ### Contact failed to Converge : at total_step=', cstep, ' sub_step=', sub_step
408  end if
409  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
410  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
411  fstrsolid%NRstat_i(knstdresn) = 3
412  return
413  end if
414 
415  ! ----- Set residual for next newton iteration
416  call fstr_update_ndforce(cstep,hecmesh,hecmat,fstrsolid,conmat )
417 
418  if( fstr_is_contact_active() ) then
419  call hecmw_mat_clear_b( conmat )
420  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
421  ! Consider SPC condition
422  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
423  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
424  endif
425 
426  enddo loopforcontactanalysis
427 
428  ! ----- update the total displacement
429  ! u_{n+1} = u_{n} + \Delta u_{n+1}
430  call fstr_commit_solution_increment( hecmesh, fstrsolid, ndof )
431 
432  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
433 
434  call fstr_updatestate( hecmesh, fstrsolid, tincr )
435 
436  ! Update REACTION using current QFORCE
437  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
438 
439  ! ----- COMMIT lambda transaction (converged exit only; failure returns skip this) -----
440  if( ctalgo == kcaalagrange ) call fstr_commit_lambda_txn( fstrsolid, cstep )
441 
442  deallocate(coord)
443  deallocate(resid_work)
444  fstrsolid%CutBack_stat = 0
445  end subroutine fstr_newton_contactalag
446 
449  subroutine fstr_newton_contactslag( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, hecLagMAT, &
450  restart_step_num, restart_substep_num, sub_step, ctime, dtime, infoCTChange, conMAT )
451 
452  integer, intent(in) :: cstep
453  type (hecmwst_local_mesh) :: hecMESH
454  type (hecmwST_matrix) :: hecMAT
455  type (fstr_solid) :: fstrSOLID
456  integer, intent(in) :: sub_step
457  real(kind=kreal), intent(in) :: ctime
458  real(kind=kreal), intent(in) :: dtime
459  type (fstr_param) :: fstrPARAM
460  type (fstr_info_contactChange) :: infoCTChange
461  type (hecmwST_matrix_lagrange) :: hecLagMAT
462  type (hecmwST_matrix) :: conMAT
463 
464  type (hecmwST_ebc) :: hecEBC
465  integer(kind=kint) :: ndof
466  integer(kind=kint) :: ctAlgo
467  integer(kind=kint) :: i, iter
468  integer(kind=kint) :: stepcnt, count_step
469  real(kind=kreal) :: tincr
470  integer(kind=kint) :: restart_step_num, restart_substep_num
471  logical :: is_mat_symmetric
472  integer(kind=kint) :: contact_changed_global
473  real(kind=kreal), allocatable :: coord(:)
474  integer(kind=kint) :: istat
475  integer(kind=kint) :: iterStatus, nresid
476  real(kind=kreal), allocatable :: resid_work(:)
477  type(fstr_convergence_state) :: cnvstat
478 
479  ctalgo = fstrparam%contact_algo
480 
481  if( hecmat%Iarray(99) == 4 .and. .not. fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh) ) then
482  write(*, *) ' This type of direct solver is not yet available in such case ! '
483  write(*, *) ' Please use intel MKL direct solver !'
484  call hecmw_abort( hecmw_comm_get_comm() )
485  endif
486 
487  do i=1,fstrsolid%n_contacts
488  fstrsolid%contacts(i)%ctime = ctime + dtime
489  enddo
490 
491  if( cstep==1 .and. sub_step==restart_substep_num ) then
493  if( restart_step_num > 1 .or. restart_substep_num > 1 ) then
494  call fstr_set_contact_active_restart( cstep, fstrsolid, infoctchange )
495  infoctchange%contactNode_current = infoctchange%contactNode_previous
496  else
497  call fstr_scan_contact_state( cstep, sub_step, 0, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
498  endif
499  call hecmw_mat_copy_profile( hecmat, conmat )
500  if ( fstr_is_contact_active() ) then
501  call fstr_mat_con_contact(cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
502  elseif( hecmat%Iarray(99)==4 ) then
503  write(*, *) ' This type of direct solver is not yet available in such case ! '
504  write(*, *) ' Please change the solver type to intel MKL direct solver !'
505  call hecmw_abort(hecmw_comm_get_comm())
506  endif
507  is_mat_symmetric = fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh)
508  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, is_mat_symmetric)
509  endif
510 
511  call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof, ctalgo, conmat)
512 
513  stepcnt = 0
514  count_step = 0
515  allocate(coord(hecmesh%n_node*ndof))
516  allocate(resid_work(hecmesh%n_node*ndof + conmat%NP*ndof))
517 
518  loopforcontactanalysis: do while( .true. )
519  count_step = count_step+1
520 
521  ! ----- Inner Iteration
522  do iter = 1, fstrsolid%step_ctrl(cstep)%max_iter
523  call hecmw_barrier(hecmesh)
524  if( myrank == 0 ) print *,'-------------------------------------------------'
525  call hecmw_barrier(hecmesh)
526  stepcnt = stepcnt+1
527 
528  call fstr_creatematrix_and_dampingforce(hecmesh, hecmat, fstrsolid, ctime, tincr)
529  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
530 
531  call hecmw_mat_clear( conmat )
532  conmat%X = 0.0d0
533 
534  if( fstr_is_contact_active() ) then
535  call fstr_addcontactstiffness(cstep,ctalgo,iter,hecmesh,conmat,heclagmat,fstrsolid)
536  endif
537 
538  ! ----- Set Boundary condition
539  call hecmw_ebc_init(hecmat, hecebc)
540  call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, stepcnt, hecebc, conmat)
541 
542  !----- SOLVE [Kt]{du}={R}
543  ! ---- For Parallel Contact with Multi-Partition Domains
544  hecmat%X = 0.0d0
545  call fstr_set_current_config_to_mesh(hecmesh,fstrsolid,coord)
546  call solve_lineq_contact(hecmesh, hecmat, heclagmat, conmat, hecebc, istat, 1.0d0, fstr_is_contact_active())
547  call fstr_recover_initial_config_to_mesh(hecmesh,fstrsolid,coord)
548  call hecmw_ebc_finalize(hecebc)
549  ! ----- check matrix solver error
550  call fstr_check_linear_solver(hecmesh, hecmat, fstrsolid, cstep, sub_step, iterstatus, istat)
551  if( iterstatus /= kitrcontinue ) then
552  fstrsolid%NRstat_i(knstciter) = count_step
553  return
554  endif
555 
556  ! ----- update the small displacement and the displacement for 1step
557  call fstr_apply_solution_increment( hecmesh, fstrsolid, ndof, hecmat%X )
558 
559  ! ----- update the Lagrange multipliers
560  if( fstr_is_contact_active() ) then
561  do i = 1, heclagmat%num_lagrange
562  heclagmat%lagrange(i) = heclagmat%lagrange(i)+hecmat%X(hecmesh%n_node*ndof+i)
563  enddo
564  endif
565 
566  ! ----- update the strain, stress, and internal force (only QFORCE)
567  call fstr_updatenewton(hecmesh, hecmat, fstrsolid, fstrparam, ctime, tincr, iter)
568 
569  if( fstrsolid%elemact%ELEMACT_egrp_tot > 0 ) then
570  call fstr_update_elemact_solid_by_value( hecmesh, fstrsolid, cstep, ctime+dtime )
571  endif
572 
573  ! ----- Set residual
574  if( fstrsolid%DLOAD_follow /= 0 .or. fstrsolid%CLOAD_ngrp_rot /= 0 ) &
575  call fstr_ass_load(cstep, ctime+dtime, hecmesh, hecmat, fstrsolid, fstrparam)
576 
577  call fstr_update_ndforce(cstep,hecmesh,hecmat,fstrsolid,conmat )
578 
579  if( fstr_is_contact_active() ) then
580  call hecmw_mat_clear_b( conmat )
581  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
582  ! Consider SPC condition
583  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
584  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
585  endif
586 
587  call fstr_assemble_residual_contact(hecmat, heclagmat, conmat, hecmesh, resid_work, nresid)
588  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrparam, &
589  ndof, iter, sub_step, cstep, &
590  resid_work, cnvstat, iterstatus, heclagmat)
591  if (iterstatus == kitrconverged) then
592  exit
593  endif
594  if (iterstatus == kitrdiverged .or. iterstatus == kitrfloatingerror) then
595  fstrsolid%NRstat_i(knstciter) = count_step
596  return
597  endif
598 
599  enddo
600  ! ----- end of inner loop
601 
602  ! ----- compute CONT_NFORCE/CONT_FRIC for output
603  if( fstr_is_contact_active() ) &
604  call fstr_calc_contact_output_force(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
605 
606  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
607  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
608 
609  call fstr_scan_contact_state( cstep, sub_step, count_step, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
610 
611  if( hecmat%Iarray(99) == 4 .and. .not. fstr_is_contact_active() ) then
612  write(*, *) ' This type of direct solver is not yet available in such case ! '
613  write(*, *) ' Please use intel MKL direct solver !'
614  call hecmw_abort( hecmw_comm_get_comm() )
615  endif
616 
617  is_mat_symmetric = fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh)
618  contact_changed_global = 0
619  if( fstr_is_matrixstructure_changed(infoctchange) ) then
620  call fstr_mat_con_contact( cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
621  contact_changed_global = 1
622  endif
623 
624  if( fstr_is_contact_conv(ctalgo,infoctchange,hecmesh) ) exit loopforcontactanalysis
625 
626  call hecmw_allreduce_i1(hecmesh, contact_changed_global, hecmw_max)
627  if (contact_changed_global > 0) then
628  call hecmw_mat_clear_b( hecmat )
629  call hecmw_mat_clear_b( conmat )
630  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, is_mat_symmetric)
631  endif
632 
633  ! ----- check divergence
634  if( count_step >= fstrsolid%step_ctrl(cstep)%max_contiter ) then
635  if( hecmesh%my_rank == 0) then
636  write( *,'(a,i5,a,i5)') ' ### Contact failed to Converge : at total_step=', cstep, ' sub_step=', sub_step
637  end if
638  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
639  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
640  fstrsolid%NRstat_i(knstdresn) = 3
641  return
642  end if
643 
644  ! ----- Set residual for next newton iteration
645  call fstr_update_ndforce(cstep,hecmesh,hecmat,fstrsolid,conmat )
646 
647  if( fstr_is_contact_active() ) then
648  call hecmw_mat_clear_b( conmat )
649  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
650  ! Consider SPC condition
651  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
652  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
653  endif
654 
655  enddo loopforcontactanalysis
656 
657  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
658 
659  ! ----- update the total displacement
660  ! u_{n+1} = u_{n} + \Delta u_{n+1}
661  call fstr_commit_solution_increment( hecmesh, fstrsolid, ndof )
662 
663  call fstr_updatestate(hecmesh, fstrsolid, tincr)
664  call fstr_update_contact_tangentforce( cstep, fstrsolid )
665  if( fstrsolid%n_embeds > 0 .and. paracontactflag ) then
666  call fstr_setup_parancon_contactvalue(hecmesh,ndof,fstrsolid%EMBED_NFORCE,1)
667  call fstr_update_ndforce_spc( cstep, hecmesh, fstrsolid, hecmat%B )
668  endif
669  ! Update REACTION using current QFORCE
670  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
671 
672  deallocate(coord)
673  deallocate(resid_work)
674  fstrsolid%CutBack_stat = 0
675  end subroutine fstr_newton_contactslag
676 
677 end module m_fstr_nonlinearmethod
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_s2s_profile_needs_refresh(cstep, contact_algo, fstrSOLID, conMAT)
S2S mortar profile-invariant check (read-only companion to the reservation in getNewListOFrelatednode...
logical function, public fstr_is_tangent_symmetric(fstrSOLID, hecMESH)
this function judges whether the material and element tangents are symmetric
logical function, public fstr_is_contactalag_symmetric(fstrSOLID, hecMESH)
this function judges whether the ALagrange contact tangent is symmetric or not
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_apply(hecMESH, hecMAT, hecEBC, conMAT)
subroutine, public hecmw_ebc_finalize(hecEBC)
This module provides a function to deal with prescribed displacement.
Definition: fstr_AddBC.f90:7
subroutine fstr_addbc(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, hecLagMAT, iter, hecEBC, conMAT, RHSvector)
Add Essential Boundary Conditions.
Definition: fstr_AddBC.f90:14
This module provides functions to take into account external load.
subroutine fstr_ass_load(cstep, ctime, hecMESH, hecMAT, fstrSOLID, fstrPARAM)
This subroutine assmble following external force into fstrSOLIDGL and hecMATB afterwards.
Contact processing at assembly level (all pairs in one tContact object)
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 provide a function to elemact elements.
subroutine fstr_update_elemact_solid_by_value(hecMESH, fstrSOLID, cstep, ctime)
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...
Finite-rotation nodal kinematics for NLGEOM.
subroutine, public fstr_apply_solution_increment(hecMESH, fstrSOLID, ndof, x)
Apply the linear-solver solution increment x to the step displacement dunode.
subroutine, public fstr_commit_solution_increment(hecMESH, fstrSOLID, ndof)
Commit the converged step increment dunode into the total displacement unode.
This module provides functions on nonlinear analysis.
subroutine fstr_newton_contactslag(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, hecLagMAT, restart_step_num, restart_substep_num, sub_step, ctime, dtime, infoCTChange, conMAT)
This subroutine solve nonlinear solid mechanics problems by Newton-Raphson method....
subroutine fstr_newton_contactalag(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, restart_step_num, restart_substep_num, sub_step, ctime, dtime, infoCTChange, conMAT)
This subroutine solve nonlinear solid mechanics problems by Newton-Raphson method combined with Neste...
subroutine fstr_init_newton(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM, hecLagMAT, ndof, ctAlgo, conMAT)
subroutine fstr_newton(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, restrt_step_num, sub_step, ctime, dtime)
This subroutine solve nonlinear solid mechanics problems by Newton-Raphson method.
This module provides function to calculate residual of nodal force.
subroutine, public fstr_update_ndforce_spc(cstep, hecMESH, fstrSOLID, B)
subroutine, public fstr_update_ndforce(cstep, hecMESH, hecMAT, fstrSOLID, conMAT)
subroutine fstr_calc_residual_vector(hecMESH, hecMAT, fstrSOLID, ctime, tincr, iter, cstep, dtime, fstrPARAM)
\breaf This subroutine calculate residual vector
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
This module provides functions to deal with spring force.
Definition: fstr_Spring.f90:7
subroutine fstr_addspring(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM)
Definition: fstr_Spring.f90:13
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
integer(kind=kint) myrank
PARALLEL EXECUTION.
Definition: m_fstr.F90:107
subroutine fstr_recover_initial_config_to_mesh(hecMESH, fstrSOLID, coord)
Definition: m_fstr.F90:1218
integer(kind=kint), parameter kitrfloatingerror
Definition: m_fstr.F90:103
integer(kind=kint), parameter kitrconverged
Definition: m_fstr.F90:101
subroutine fstr_set_current_config_to_mesh(hecMESH, fstrSOLID, coord)
Definition: m_fstr.F90:1205
integer(kind=kint), parameter kcaalagrange
Definition: m_fstr.F90:63
integer(kind=kint), parameter kitrcontinue
iteration control
Definition: m_fstr.F90:100
integer(kind=kint), parameter kitrdiverged
Definition: m_fstr.F90:102
logical paracontactflag
PARALLEL CONTACT FLAG.
Definition: m_fstr.F90:111
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.
This modules just summarizes all modules used in static analysis.
Definition: static_LIB.f90:6
This module provides functions to output result.
Top-level contact analysis module (System level)
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_set_contact_active_restart(cstep, fstrSOLID, infoCTChange)
Assembly flag on restart. The restart file holds the number of nodes in contact and the slave states ...
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_update_contact_multiplier(cstep, ctAlgo, hecMESH, hecLagMAT, fstrSOLID, ctchanged)
subroutine fstr_calc_contact_refstiff(cstep, hecMESH, hecMAT, fstrSOLID)
Calculate reference stiffness for all contact pairs (System Level)
subroutine fstr_commit_lambda_txn(fstrSOLID, cstep)
COMMIT lambda transaction (MORTAR=YES only): keep the masters with a positive per-node lambda and swa...
subroutine fstr_begin_lambda_txn(fstrSOLID, cstep)
BEGIN lambda transaction (MORTAR=YES only): clear the working buffer. Called at the start of every su...
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.