FrontISTR  5.9.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 
28  implicit none
29 
30 contains
31 
32  subroutine fstr_init_newton(hecMESH, hecMAT, fstrSOLID, &
33  & ctime, tincr, iter, cstep, dtime, fstrPARAM, hecLagMAT, ndof, ctAlgo, conMAT)
34  use m_fstr_update
35  implicit none
36  type (hecmwST_local_mesh) :: hecMESH
37  type (hecmwST_matrix) :: hecMAT
38  type (fstr_solid) :: fstrSOLID
39  real(kind=kreal), intent(in) :: ctime
40  real(kind=kreal), intent(in) :: dtime
41  type (fstr_param) :: fstrPARAM
42  real(kind=kreal), intent(inout) :: tincr
43  integer(kind=kint) :: iter
44  integer, intent(in) :: cstep
45  type (hecmwST_matrix_lagrange) :: hecLagMAT
46  integer(kind=kint), intent(inout) :: ndof
47  integer(kind=kint), intent(in) :: ctAlgo
48  type (hecmwST_matrix) :: conMAT
49 
50  hecmat%NDOF = hecmesh%n_dof
51  ndof = hecmat%ndof
52 
53  tincr = dtime
54  if( fstrsolid%step_ctrl(cstep)%solution == stepstatic ) tincr = 0.d0
55 
56  fstrsolid%dunode(:) = 0.0d0
57  fstrsolid%NRstat_i(:) = 0 ! logging newton iteration(init)
58 
59  call fstr_ass_load(cstep, ctime+dtime, hecmesh, hecmat, fstrsolid, fstrparam)
60 
61  if( fstrsolid%elemact%ELEMACT_egrp_tot > 0 ) then
62  call fstr_updatenewton(hecmesh, hecmat, fstrsolid, ctime, tincr, 0)
63  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid)
64  endif
65 
66  if( fstr_is_contact_active() ) then
67  call hecmw_mat_clear_b(conmat)
68  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
69  ! Consider SPC condition
70  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
71  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
72  endif
73 
74  end subroutine fstr_init_newton
75 
78  subroutine fstr_newton( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, &
79  restrt_step_num, sub_step, ctime, dtime )
80 
81  integer, intent(in) :: cstep
82  type (hecmwST_local_mesh) :: hecMESH
83  type (hecmwST_matrix) :: hecMAT
84  type (fstr_solid) :: fstrSOLID
85  integer, intent(in) :: sub_step
86  real(kind=kreal), intent(in) :: ctime
87  real(kind=kreal), intent(in) :: dtime
88  type (fstr_param) :: fstrPARAM
89  type (hecmwST_matrix_lagrange) :: hecLagMAT
90 
91  type (hecmwST_local_mesh), pointer :: hecMESHmpc
92  type (hecmwST_matrix), pointer :: hecMATmpc
93  integer(kind=kint) :: ndof
94  integer(kind=kint) :: i, iter
95  integer(kind=kint) :: stepcnt
96  integer(kind=kint) :: restrt_step_num
97  real(kind=kreal) :: tt0, tt, res, qnrm, rres, tincr, xnrm, dunrm, rxnrm
98  real(kind=kreal), allocatable :: coord(:), p(:)
99  logical :: isLinear = .false.
100  integer(kind=kint) :: iterStatus
101 
102  call hecmw_mpc_mat_init(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
103 
104  if(.not. fstrpr%nlgeom)then
105  islinear = .true.
106  endif
107 
108  call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof, 0, hecmat)
109 
110  allocate(p(hecmesh%n_node*ndof))
111  allocate(coord(hecmesh%n_node*ndof))
112  p = 0.0d0
113  stepcnt = 0
114 
115  ! ----- Inner Iteration, lagrange multiplier constant
116  do iter=1,fstrsolid%step_ctrl(cstep)%max_iter
117  stepcnt = stepcnt+1
118 
119  call fstr_creatematrix_and_dampingforce( hecmesh, hecmat, fstrsolid, ctime, tincr )
120  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
121 
122  ! ----- Set Boundary condition
123  call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, stepcnt)
124  call hecmw_mpc_mat_ass(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
125  call hecmw_mpc_trans_rhs(hecmesh, hecmat, hecmatmpc)
126 
127  !----- SOLVE [Kt]{du}={R}
128  if( sub_step == restrt_step_num .and. iter == 1 ) hecmatmpc%Iarray(98) = 1
129  if( iter == 1 ) then
130  hecmatmpc%Iarray(97) = 2 !Force numerical factorization
131  else
132  hecmatmpc%Iarray(97) = 1 !Need numerical factorization
133  endif
134  hecmatmpc%X = 0.0d0
135  call fstr_set_current_config_to_mesh(hecmeshmpc,fstrsolid,coord)
136  call solve_lineq(hecmeshmpc,hecmatmpc)
137  call fstr_recover_initial_config_to_mesh(hecmeshmpc,fstrsolid,coord)
138  ! ----- check matrix solver error
139  if( hecmw_mat_get_flag_converged(hecmatmpc) == kno ) then
140  if( hecmesh%my_rank == 0) then
141  write( *,'(a,i5,a,i5)') ' ### Fail to Converge : at total_step=', cstep, ' sub_step=', sub_step
142  end if
143  fstrsolid%NRstat_i(knstdresn) = 4
144  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
145  return
146  end if
147  call hecmw_mpc_tback_sol(hecmesh, hecmat, hecmatmpc)
148 
149  ! ----- update the small displacement and the displacement for 1step
150  ! \delta u^k => solver's solution
151  ! \Delta u_{n+1}^{k} = \Delta u_{n+1}^{k-1} + \delta u^k
152  call fstr_apply_solution_increment( hecmesh, fstrsolid, ndof, hecmat%X )
153 
154  call fstr_calc_residual_vector(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam)
155 
156  if( islinear ) exit
157 
158  ! ----- check convergence
159  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrpr, &
160  ndof, iter, sub_step, cstep, &
161  hecmat%B, 0, &
162  res, res, &
163  0, &
164  iterstatus)
165  if (iterstatus == kitrconverged) exit
166  if (iterstatus == kitrdiverged .or. iterstatus==kitrfloatingerror) return
167  enddo
168  ! ----- end of inner loop
169 
170  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
171  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
172 
173  ! ----- update the total displacement
174  ! u_{n+1} = u_{n} + \Delta u_{n+1}
175  call fstr_commit_solution_increment( hecmesh, fstrsolid, ndof )
176 
177  call fstr_updatestate( hecmesh, fstrsolid, tincr )
178  ! Update REACTION using current QFORCE
179  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
180 
181  fstrsolid%CutBack_stat = 0
182  deallocate(coord)
183  deallocate(p)
184  call hecmw_mpc_mat_finalize(hecmesh, hecmat, hecmeshmpc, hecmatmpc)
185  end subroutine fstr_newton
186 
190  subroutine fstr_newton_contactalag( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, &
191  restart_step_num, restart_substep_num, sub_step, ctime, dtime, infoCTChange, conMAT )
192 
193  integer, intent(in) :: cstep
194  type (hecmwST_local_mesh) :: hecMESH
195  type (hecmwST_matrix) :: hecMAT
196  type (fstr_solid) :: fstrSOLID
197  integer, intent(in) :: sub_step
198  real(kind=kreal), intent(in) :: ctime
199  real(kind=kreal), intent(in) :: dtime
200  type (fstr_param) :: fstrPARAM
201  type (fstr_info_contactChange) :: infoCTChange
202  type (hecmwST_matrix_lagrange) :: hecLagMAT
203  type (hecmwST_matrix) :: conMAT
204 
205  integer(kind=kint) :: ndof
206  integer(kind=kint) :: ctAlgo
207  integer(kind=kint) :: i, iter
208  integer(kind=kint) :: al_step, n_al_step, stepcnt, count_step
209  real(kind=kreal) :: tt0, tt, res, res0, res1, relres, tincr
210  integer(kind=kint) :: restart_step_num, restart_substep_num
211  logical :: convg, ctchange
212  integer(kind=kint) :: n_node_global
213  integer(kind=kint) :: contact_changed_global
214  real(kind=kreal), allocatable :: coord(:)
215  integer(kind=kint) :: istat
216  logical :: is_first_Stiffmatrixcall
217  integer(kind=kint) :: iterStatus, nresid
218  real(kind=kreal), allocatable :: resid_work(:)
219 
220 
221  ! sum of n_node among all subdomains (to be used to calc res)
222  n_node_global = hecmesh%nn_internal
223  call hecmw_allreduce_i1(hecmesh,n_node_global,hecmw_sum)
224 
225  ctalgo = fstrparam%contact_algo
226 
227  call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof, ctalgo, conmat)
228 
229  if( cstep == 1 .and. sub_step == restart_substep_num ) then
231  if( restart_step_num > 1 .or. restart_substep_num > 1 ) then
232  call fstr_set_contact_active( infoctchange%contactNode_previous > 0 )
233  infoctchange%contactNode_current = infoctchange%contactNode_previous
234  else
235  if(hecmesh%my_rank==0) write(*,*) "---Scanning initial contact state---"
236  call fstr_scan_contact_state( cstep, sub_step, 0, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
237  endif
238  call hecmw_mat_copy_profile( hecmat, conmat )
239  if ( fstr_is_contact_active() ) then
240  call fstr_mat_con_contact(cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
241  elseif( hecmat%Iarray(99)==4 ) then
242  write(*, *) ' This type of direct solver is not yet available in such case ! '
243  write(*, *) ' Please change the solver type to intel MKL direct solver !'
244  call hecmw_abort(hecmw_comm_get_comm())
245  endif
246  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, .true.)
247  endif
248 
249  hecmat%X = 0.0d0
250 
251  stepcnt = 0
252  allocate(coord(hecmesh%n_node*ndof))
253  allocate(resid_work(hecmesh%n_node*ndof + conmat%NP*ndof))
254 
255  ! ----- Augmentation loop. In case of no contact, it is inactive
256  n_al_step = fstrparam%augiter
257  count_step = 0
258  is_first_stiffmatrixcall = .true.
259 
260  loopforcontactanalysis: do while( .true. )
261  count_step = count_step + 1
262 
263  do al_step = 1, n_al_step
264 
265  if( hecmesh%my_rank == 0) then
266  write(*,*) "Contact iter: ", count_step, " Augmentation iter: ", al_step
267  end if
268 
269  ! ----- Inner Iteration, lagrange multiplier constant
270  res0 = 0.0d0
271  res1 = 0.0d0
272  relres = 1.0d0
273 
274  do iter = 1,fstrsolid%step_ctrl(cstep)%max_iter
275  stepcnt = stepcnt+1
276 
277  call fstr_creatematrix_and_dampingforce( hecmesh, hecmat, fstrsolid, ctime, tincr )
278  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
279 
280  call hecmw_mat_clear( conmat )
281  conmat%X = 0.0d0
282 
283  ! ----- Contact
284  if( is_first_stiffmatrixcall ) then
285  call fstr_calc_contact_refstiff(cstep, hecmesh, hecmat, fstrsolid)
286  is_first_stiffmatrixcall = .false.
287  endif
288  if( fstr_is_contact_active() ) then
289  call fstr_addcontactstiffness(cstep,ctalgo,iter,hecmesh,conmat,heclagmat,fstrsolid)
290  endif
291 
292  ! ----- Set Boundary condition
293  call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, stepcnt, conmat)
294 
295  !----- SOLVE [Kt]{du}={R}
296  ! ---- For Parallel Contact with Multi-Partition Domains
297  hecmat%X = 0.0d0
298  call fstr_set_current_config_to_mesh(hecmesh,fstrsolid,coord)
299  call solve_lineq_contact(hecmesh, hecmat, heclagmat, conmat, istat, 1.0d0, fstr_is_contact_active())
300  call fstr_recover_initial_config_to_mesh(hecmesh,fstrsolid,coord)
301 
302  call hecmw_update_r (hecmesh, hecmat%X, hecmat%NP, hecmesh%n_dof)
303 
304  ! ----- update the small displacement and the displacement for 1step
305  ! \delta u^k => solver's solution
306  ! \Delta u_{n+1}^{k} = \Delta u_{n+1}^{k-1} + \delta u^k
307  call fstr_apply_solution_increment( hecmesh, fstrsolid, ndof, hecmat%X )
308 
309  ! ----- update the strain, stress, and internal force
310  call fstr_updatenewton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter)
311 
312  if( fstrsolid%elemact%ELEMACT_egrp_tot > 0 ) then
313  call fstr_update_elemact_solid_by_value( hecmesh, fstrsolid, cstep, ctime )
314  endif
315 
316  ! ----- Set residual
317  if( fstrsolid%DLOAD_follow /= 0 .or. fstrsolid%CLOAD_ngrp_rot /= 0 ) &
318  call fstr_ass_load(cstep, ctime+dtime, hecmesh, hecmat, fstrsolid, fstrparam)
319 
320  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid, conmat)
321  call hecmw_mat_clear_b( conmat )
322  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
323 
324  ! Consider SPC condition
325  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
326  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
327 
328  !res = fstr_get_residual(hecMAT%B, hecMESH)
329  call fstr_assemble_residual_contact(hecmat, heclagmat, conmat, hecmesh, resid_work, nresid)
330  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrpr, &
331  ndof, iter, sub_step, cstep, &
332  resid_work, nresid, &
333  res0, res1, &
334  n_node_global, &
335  iterstatus)
336  if (iterstatus == kitrconverged) exit
337  if (iterstatus == kitrdiverged .or. iterstatus == kitrfloatingerror) then
338  fstrsolid%NRstat_i(knstciter) = al_step
339  return
340  endif
341 
342  enddo
343  ! ----- end of inner loop
344 
345  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
346  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
347 
348  call fstr_update_contact_multiplier( cstep, ctalgo, hecmesh, heclagmat, fstrsolid, ctchange )
349 
350  ! ----- Set residual for next newton iteration
351  call fstr_update_ndforce(cstep, hecmesh, hecmat, fstrsolid, conmat)
352  ! ----- deal with contact boundary
353  call hecmw_mat_clear_b( conmat )
354  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
355  ! Consider SPC condition
356  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
357  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
358 
359  enddo
360  ! ----- end of augmentation loop
361 
362  ! ----- compute CONT_NFORCE/CONT_FRIC for output
363  if( fstr_is_contact_active() ) &
364  call fstr_calc_contact_output_force(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
365 
366  ! ----- deal with contact boundary
367  call fstr_scan_contact_state( cstep, sub_step, count_step, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
368 
369  contact_changed_global = 0
370  if( fstr_is_matrixstructure_changed(infoctchange) ) then
371  call fstr_mat_con_contact( cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
372  contact_changed_global = 1
373  endif
374  call hecmw_allreduce_i1(hecmesh, contact_changed_global, hecmw_max)
375  if (contact_changed_global > 0) then
376  call hecmw_mat_clear_b( hecmat )
377  call hecmw_mat_clear_b( conmat )
378  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, .true.)
379  endif
380 
381  if( fstr_is_contact_conv(ctalgo,infoctchange,hecmesh) .and. .not. ctchange ) exit loopforcontactanalysis
382 
383  ! ----- check divergence
384  if( count_step >= fstrsolid%step_ctrl(cstep)%max_contiter ) then
385  if( hecmesh%my_rank == 0) then
386  write( *,'(a,i5,a,i5)') ' ### Contact failed to Converge : at total_step=', cstep, ' sub_step=', sub_step
387  end if
388  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
389  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
390  fstrsolid%NRstat_i(knstdresn) = 3
391  return
392  end if
393 
394  ! ----- Set residual for next newton iteration
395  call fstr_update_ndforce(cstep,hecmesh,hecmat,fstrsolid,conmat )
396 
397  if( fstr_is_contact_active() ) then
398  call hecmw_mat_clear_b( conmat )
399  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
400  ! Consider SPC condition
401  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
402  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
403  endif
404 
405  enddo loopforcontactanalysis
406 
407  ! ----- update the total displacement
408  ! u_{n+1} = u_{n} + \Delta u_{n+1}
409  call fstr_commit_solution_increment( hecmesh, fstrsolid, ndof )
410 
411  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
412 
413  call fstr_updatestate( hecmesh, fstrsolid, tincr )
414 
415  ! Update REACTION using current QFORCE
416  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
417 
418  deallocate(coord)
419  deallocate(resid_work)
420  fstrsolid%CutBack_stat = 0
421  end subroutine fstr_newton_contactalag
422 
425  subroutine fstr_newton_contactslag( cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, hecLagMAT, &
426  restart_step_num, restart_substep_num, sub_step, ctime, dtime, infoCTChange, conMAT )
427 
428  integer, intent(in) :: cstep
429  type (hecmwST_local_mesh) :: hecMESH
430  type (hecmwST_matrix) :: hecMAT
431  type (fstr_solid) :: fstrSOLID
432  integer, intent(in) :: sub_step
433  real(kind=kreal), intent(in) :: ctime
434  real(kind=kreal), intent(in) :: dtime
435  type (fstr_param) :: fstrPARAM
436  type (fstr_info_contactChange) :: infoCTChange
437  type (hecmwST_matrix_lagrange) :: hecLagMAT
438  type (hecmwST_matrix) :: conMAT
439 
440  integer(kind=kint) :: ndof
441  integer(kind=kint) :: ctAlgo
442  integer(kind=kint) :: i, iter, max_iter_contact
443  integer(kind=kint) :: stepcnt, count_step
444  real(kind=kreal) :: tt0, tt, res, res0, res1, relres, tincr, resx
445  integer(kind=kint) :: restart_step_num, restart_substep_num
446  logical :: is_mat_symmetric
447  integer(kind=kint) :: n_node_global
448  integer(kind=kint) :: contact_changed_global
449  integer(kint) :: nndof
450  real(kreal) :: q_residual,x_residual
451  real(kind=kreal), allocatable :: coord(:)
452  integer(kind=kint) :: istat
453  integer(kind=kint) :: iterStatus, nresid
454  real(kind=kreal), allocatable :: resid_work(:)
455 
456  ctalgo = fstrparam%contact_algo
457 
458  ! sum of n_node among all subdomains (to be used to calc res)
459  n_node_global = hecmesh%nn_internal
460  call hecmw_allreduce_i1(hecmesh,n_node_global,hecmw_sum)
461 
462  if( hecmat%Iarray(99) == 4 .and. .not. fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh) ) then
463  write(*, *) ' This type of direct solver is not yet available in such case ! '
464  write(*, *) ' Please use intel MKL direct solver !'
465  call hecmw_abort( hecmw_comm_get_comm() )
466  endif
467 
468  do i=1,fstrsolid%n_contacts
469  fstrsolid%contacts(i)%ctime = ctime + dtime
470  enddo
471 
472  if( cstep==1 .and. sub_step==restart_substep_num ) then
474  if( restart_step_num > 1 .or. restart_substep_num > 1 ) then
475  call fstr_set_contact_active( infoctchange%contactNode_previous > 0 )
476  infoctchange%contactNode_current = infoctchange%contactNode_previous
477  else
478  call fstr_scan_contact_state( cstep, sub_step, 0, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
479  endif
480  call hecmw_mat_copy_profile( hecmat, conmat )
481  if ( fstr_is_contact_active() ) then
482  call fstr_mat_con_contact(cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
483  elseif( hecmat%Iarray(99)==4 ) then
484  write(*, *) ' This type of direct solver is not yet available in such case ! '
485  write(*, *) ' Please change the solver type to intel MKL direct solver !'
486  call hecmw_abort(hecmw_comm_get_comm())
487  endif
488  is_mat_symmetric = fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh)
489  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, is_mat_symmetric)
490  endif
491 
492  call fstr_init_newton(hecmesh, hecmat, fstrsolid, ctime, tincr, iter, cstep, dtime, fstrparam, heclagmat, ndof, ctalgo, conmat)
493 
494  stepcnt = 0
495  count_step = 0
496  allocate(coord(hecmesh%n_node*ndof))
497  allocate(resid_work(hecmesh%n_node*ndof + conmat%NP*ndof))
498 
499  loopforcontactanalysis: do while( .true. )
500  count_step = count_step+1
501 
502  ! ----- Inner Iteration
503  res0 = 0.d0
504  res1 = 0.d0
505  relres = 1.d0
506 
507  do iter = 1, fstrsolid%step_ctrl(cstep)%max_iter
508  call hecmw_barrier(hecmesh)
509  if( myrank == 0 ) print *,'-------------------------------------------------'
510  call hecmw_barrier(hecmesh)
511  stepcnt = stepcnt+1
512 
513  call fstr_creatematrix_and_dampingforce(hecmesh, hecmat, fstrsolid, ctime, tincr)
514  call fstr_addspring(cstep, hecmesh, hecmat, fstrsolid, fstrparam)
515 
516  call hecmw_mat_clear( conmat )
517  conmat%X = 0.0d0
518 
519  if( fstr_is_contact_active() ) then
520  call fstr_addcontactstiffness(cstep,ctalgo,iter,hecmesh,conmat,heclagmat,fstrsolid)
521  endif
522 
523  ! ----- Set Boundary condition
524  call fstr_addbc(cstep, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, stepcnt, conmat)
525 
526  nndof = hecmat%N*hecmat%ndof
527 
528  !----- SOLVE [Kt]{du}={R}
529  ! ---- For Parallel Contact with Multi-Partition Domains
530  hecmat%X = 0.0d0
531  call fstr_set_current_config_to_mesh(hecmesh,fstrsolid,coord)
532  q_residual = fstr_get_norm_para_contact(hecmat,heclagmat,conmat,hecmesh)
533  call solve_lineq_contact(hecmesh, hecmat, heclagmat, conmat, istat, 1.0d0, fstr_is_contact_active())
534  call fstr_recover_initial_config_to_mesh(hecmesh,fstrsolid,coord)
535  ! ----- check matrix solver error
536  if( istat /= 0 ) then
537  if( hecmesh%my_rank == 0) then
538  write( *,'(a,i5,a,i5)') ' ### Fail to Converge : at total_step=', cstep, ' sub_step=', sub_step
539  end if
540  fstrsolid%NRstat_i(knstdresn) = 4
541  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
542  return
543  end if
544 
545  x_residual = fstr_get_x_norm_contact(hecmat,heclagmat,hecmesh)
546 
547  call hecmw_innerproduct_r(hecmesh,ndof,hecmat%X,hecmat%X,resx)
548  resx = sqrt(resx)/n_node_global
549 
550  if( hecmesh%my_rank==0 ) then
551  write(*,'(a,i3,a,e15.7)') ' - ResidualX (',iter,') =',resx
552  write(*,'(a,i3,a,e15.7)') ' - ResidualX+LAG(',iter,') =',sqrt(x_residual)/n_node_global
553  write(*,'(a,i3,a,e15.7)') ' - ResidualQ (',iter,') =',sqrt(q_residual)/n_node_global
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, 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 )
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  res = fstr_get_norm_para_contact(hecmat,heclagmat,conmat,hecmesh)
588 
589  call fstr_assemble_residual_contact(hecmat, heclagmat, conmat, hecmesh, resid_work, nresid)
590  call fstr_check_convergence(hecmesh, hecmat, fstrsolid, fstrpr, &
591  ndof, iter, sub_step, cstep, &
592  resid_work, nresid, &
593  res0, res1, &
594  n_node_global, &
595  iterstatus)
596  if (iterstatus == kitrconverged) then
597  exit
598  endif
599  if (iterstatus == kitrdiverged .or. iterstatus == kitrfloatingerror) then
600  fstrsolid%NRstat_i(knstciter) = count_step
601  return
602  endif
603 
604  enddo
605  ! ----- end of inner loop
606 
607  ! ----- compute CONT_NFORCE/CONT_FRIC for output
608  if( fstr_is_contact_active() ) &
609  call fstr_calc_contact_output_force(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
610 
611  fstrsolid%NRstat_i(knstmaxit) = max(fstrsolid%NRstat_i(knstmaxit),iter) ! logging newton iteration(maxtier)
612  fstrsolid%NRstat_i(knstsumit) = fstrsolid%NRstat_i(knstsumit) + iter ! logging newton iteration(sum of iter)
613 
614  call fstr_scan_contact_state( cstep, sub_step, count_step, dtime, ctalgo, hecmesh, fstrsolid, infoctchange )
615 
616  if( hecmat%Iarray(99) == 4 .and. .not. fstr_is_contact_active() ) then
617  write(*, *) ' This type of direct solver is not yet available in such case ! '
618  write(*, *) ' Please use intel MKL direct solver !'
619  call hecmw_abort( hecmw_comm_get_comm() )
620  endif
621 
622  is_mat_symmetric = fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh)
623  contact_changed_global = 0
624  if( fstr_is_matrixstructure_changed(infoctchange) ) then
625  call fstr_mat_con_contact( cstep, ctalgo, hecmat, fstrsolid, heclagmat, infoctchange, conmat, fstr_is_contact_active())
626  contact_changed_global = 1
627  endif
628 
629  if( fstr_is_contact_conv(ctalgo,infoctchange,hecmesh) ) exit loopforcontactanalysis
630 
631  call hecmw_allreduce_i1(hecmesh, contact_changed_global, hecmw_max)
632  if (contact_changed_global > 0) then
633  call hecmw_mat_clear_b( hecmat )
634  call hecmw_mat_clear_b( conmat )
635  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, is_mat_symmetric)
636  endif
637 
638  ! ----- check divergence
639  if( count_step >= fstrsolid%step_ctrl(cstep)%max_contiter ) then
640  if( hecmesh%my_rank == 0) then
641  write( *,'(a,i5,a,i5)') ' ### Contact failed to Converge : at total_step=', cstep, ' sub_step=', sub_step
642  end if
643  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
644  fstrsolid%CutBack_stat = fstrsolid%CutBack_stat + 1
645  fstrsolid%NRstat_i(knstdresn) = 3
646  return
647  end if
648 
649  ! ----- Set residual for next newton iteration
650  call fstr_update_ndforce(cstep,hecmesh,hecmat,fstrsolid,conmat )
651 
652  if( fstr_is_contact_active() ) then
653  call hecmw_mat_clear_b( conmat )
654  call fstr_update_ndforce_contact(cstep,ctalgo,hecmesh,heclagmat,fstrsolid,conmat)
655  ! Consider SPC condition
656  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, hecmat%B)
657  call fstr_update_ndforce_spc(cstep, hecmesh, fstrsolid, conmat%B)
658  endif
659 
660  enddo loopforcontactanalysis
661 
662  fstrsolid%NRstat_i(knstciter) = count_step ! logging contact iteration
663 
664  ! ----- update the total displacement
665  ! u_{n+1} = u_{n} + \Delta u_{n+1}
666  call fstr_commit_solution_increment( hecmesh, fstrsolid, ndof )
667 
668  call fstr_updatestate(hecmesh, fstrsolid, tincr)
669  call fstr_update_contact_tangentforce( cstep, fstrsolid )
670  if( fstrsolid%n_embeds > 0 .and. paracontactflag ) then
671  call fstr_setup_parancon_contactvalue(hecmesh,ndof,fstrsolid%EMBED_NFORCE,1)
672  call fstr_update_ndforce_spc( cstep, hecmesh, fstrsolid, hecmat%B )
673  endif
674  ! Update REACTION using current QFORCE
675  call fstr_update_reaction_spc( cstep, hecmesh, fstrsolid )
676 
677  deallocate(coord)
678  deallocate(resid_work)
679  fstrsolid%CutBack_stat = 0
680  end subroutine fstr_newton_contactslag
681 
682 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
subroutine, public fstr_save_originalmatrixstructure(hecMAT)
This subroutine saves original matrix structure constructed originally by hecMW_matrix.
logical function, public fstr_is_matrixstruct_symmetric(fstrSOLID, hecMESH)
this function judges whether sitiffness matrix is symmetric or not
This module provides a function to deal with prescribed displacement.
Definition: fstr_AddBC.f90:7
subroutine fstr_addbc(cstep, hecMESH, hecMAT, fstrSOLID, fstrPARAM, hecLagMAT, iter, 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_convergence(hecMESH, hecMAT, fstrSOLID, fstrPR, ndof, iter, sub_step, cstep, residual_vec, nresid, resb, res_prev, n_node_global, iterStatus, maxDLag, converg_dlag)
Wrapper that calls fstr_check_convergence_main and applies the common divergence/NaN handling (status...
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)
real(kind=kreal) function, public fstr_get_norm_para_contact(hecMAT, hecLagMAT, conMAT, hecMESH)
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.
real(kind=kreal) function, public fstr_get_x_norm_contact(hecMAT, hecLagMAT, hecMESH)
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, 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:99
subroutine fstr_recover_initial_config_to_mesh(hecMESH, fstrSOLID, coord)
Definition: m_fstr.F90:1170
integer(kind=kint), parameter kitrfloatingerror
Definition: m_fstr.F90:95
integer(kind=kint), parameter kitrconverged
Definition: m_fstr.F90:93
subroutine fstr_set_current_config_to_mesh(hecMESH, fstrSOLID, coord)
Definition: m_fstr.F90:1157
type(fstr_param), target fstrpr
GLOBAL VARIABLE INITIALIZED IN FSTR_SETUP.
Definition: m_fstr.F90:213
integer(kind=kint), parameter kno
Definition: m_fstr.F90:33
integer(kind=kint), parameter kitrdiverged
Definition: m_fstr.F90:94
logical paracontactflag
PARALLEL CONTACT FLAG.
Definition: m_fstr.F90:103
This module provides functions to solve sparse system of \linear equitions in the case of contact ana...
subroutine, public solve_lineq_contact_init(hecMESH, hecMAT, hecLagMAT, is_sym)
This subroutine.
subroutine, public solve_lineq_contact(hecMESH, hecMAT, hecLagMAT, conMAT, istat, rf, is_contact_active)
This subroutine.
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_set_contact_active(a)
subroutine fstr_update_ndforce_contact(cstep, ctAlgo, hecMESH, hecLagMAT, fstrSOLID, conMAT)
Compute contact forces for residual vector (conMATB).
logical function fstr_is_matrixstructure_changed(infoCTChange)
logical function fstr_is_contact_conv(ctAlgo, infoCTChange, hecMESH)
subroutine fstr_addcontactstiffness(cstep, ctAlgo, iter, hecMESH, conMAT, hecLagMAT, fstrSOLID)
subroutine fstr_calc_contact_output_force(cstep, ctAlgo, hecMESH, hecLagMAT, fstrSOLID, conMAT)
Compute contact forces for output (CONT_NFORCE/CONT_FRIC).
subroutine fstr_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_scan_contact_state(cstep, sub_step, cont_step, dt, ctAlgo, hecMESH, fstrSOLID, infoCTChange)
Scanning contact state.
logical function fstr_is_contact_active()
subroutine fstr_update_contact_tangentforce(cstep, fstrSOLID)
Update tangent force.