FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
fstr_solve_NLGEOM.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
9  use m_static_lib
10  use m_static_output
14  use m_fstr_restart
16  use m_fstr_timeinc
17  use m_fstr_cutback
18  use mcontact
20 
21  implicit none
22 
23 contains
24 
25  !======================================================================!
31  subroutine fstr_solve_nlgeom(hecMESH,hecMAT,fstrSOLID,hecLagMAT,fstrPARAM,conMAT)
32  type (hecmwST_local_mesh) :: hecMESH
33  type (hecmwST_matrix ) :: hecMAT
34  type (fstr_param ) :: fstrPARAM
35  type (fstr_solid ) :: fstrSOLID
36  type (hecmwST_matrix_lagrange) :: hecLagMAT
37  type (fstr_info_contactChange) :: infoCTChange, infoCTChange_bak
38  type (hecmwST_matrix ) :: conMAT
39 
40  integer(kind=kint) :: ndof, nn
41  integer(kind=kint) :: j, i, tot_step, step_count, tot_step_print, CBbound
42  integer(kind=kint) :: sub_step
43  integer(kind=kint) :: restart_step_num, restart_substep_num
44  real(kind=kreal) :: ctime, dtime, endtime, factor
45  real(kind=kreal) :: time_1, time_2
46  logical :: ctchanged, is_OutPoint, is_interaction_active
47  logical :: contact_active_bak ! last scan-set contact_active, retained across cutback restore
48 
49  if(hecmesh%my_rank==0) call fstr_timeinc_printstatus_init
50 
51  hecmat%NDOF = hecmesh%n_dof
52 
53  ndof = hecmat%NDOF
54  nn = ndof*ndof
55 
56  is_interaction_active = ( associated( fstrsolid%contacts ) .or. associated( fstrsolid%embeds ) )
57 
58  if( fstrsolid%TEMP_ngrp_tot>0 .and. hecmesh%hecmw_flag_initcon==1 ) then
59  fstrsolid%last_temp = 0.0d0
60  fstrsolid%temperature = 0.0d0
61  do j=1, size(hecmesh%node_init_val_item)
62  i = hecmesh%node_init_val_index(j)
63  fstrsolid%last_temp(j) = hecmesh%node_init_val_item(i)
64  fstrsolid%temperature(j) = hecmesh%node_init_val_item(i)
65  end do
66  endif
67  if( fstrsolid%TEMP_ngrp_tot>0 .and. associated(g_initialcnd) ) then
68  fstrsolid%last_temp = 0.0d0
69  fstrsolid%temperature = 0.0d0
70  do j=1,size(g_initialcnd)
71  if( g_initialcnd(j)%cond_name=="temperature" ) then
72  if( .not. associated(fstrsolid%temperature) ) then
73  allocate( fstrsolid%temperature( hecmesh%n_node ) )
74  allocate( fstrsolid%temp_bak( hecmesh%n_node ) )
75  allocate( fstrsolid%last_temp( hecmesh%n_node ) )
76  endif
77  do i= 1, hecmesh%n_node
78  fstrsolid%last_temp(i) = g_initialcnd(j)%realval(i)
79  fstrsolid%temperature(i) = fstrsolid%last_temp(i)
80  enddo
81  endif
82  end do
83  endif
84 
85  if( associated( fstrsolid%contacts ) ) then
86  call initialize_contact_output_vectors(fstrsolid,hecmat)
87  call setup_contact_elesurf_for_area( 1, hecmesh, fstrsolid )
88  endif
89  if( fstrsolid%n_embeds > 0 ) call initialize_embed_vectors(fstrsolid,hecmat)
90 
91  restart_step_num = 1
92  restart_substep_num = 1
93  fstrsolid%unode = 0.0d0
94  step_count = 0 !**
95  infoctchange%contactNode_previous = 0
96  infoctchange%contactNode_current = 0
97  if( fstrsolid%restart_nout < 0 ) then
98  call fstr_read_restart(restart_step_num,restart_substep_num,step_count,ctime,dtime,hecmesh,fstrsolid, &
99  fstrparam,infoctchange%contactNode_previous)
100  hecmat%Iarray(98) = 1
101  call fstr_set_time( ctime )
102  call fstr_set_timeinc_base( dtime )
103  fstrsolid%restart_nout = - fstrsolid%restart_nout
104  else
105  call fstr_static_output( 1, 0, 0.d0, hecmesh, fstrsolid, fstrparam, fstrpr%solution_type, .true., 0.d0 )
106  endif
107 
108  fstrsolid%FACTOR = 0.0d0
109  call fstr_begin_nodal_kinematics_step( hecmesh, fstrsolid, hecmat%NDOF )
110  call fstr_cutback_init( hecmesh, fstrsolid, fstrparam )
111  call fstr_cutback_save( fstrsolid, infoctchange, infoctchange_bak )
112  contact_active_bak = .true.
113 
114  do tot_step=1, fstrsolid%nstep_tot
115  tot_step_print = tot_step+restart_step_num-1
116  if(hecmesh%my_rank==0) write(*,*) ''
117  if(hecmesh%my_rank==0) write(*,'(a,i5)') ' loading step=',tot_step_print
118 
119  if( fstrsolid%TEMP_ngrp_tot>0 ) then
120  do j=1, hecmesh%n_node
121  fstrsolid%temp_bak(j) = fstrsolid%temperature(j)
122  end do
123  endif
124  call fstr_updatestate( hecmesh, fstrsolid, 0.0d0 )
125 
126  call fstr_begin_nodal_kinematics_step( hecmesh, fstrsolid, hecmat%NDOF )
127  fstrsolid%unode_bak(:) = fstrsolid%unode(:)
128 
129  ! -------------------------------------------------------------------------
130  ! STEP LOOP
131  ! -------------------------------------------------------------------------
132  sub_step = restart_substep_num
133  do while(.true.)
134 
135  ! ----- time history of factor
136  call fstr_timeinc_settimeincrement( fstrsolid%step_ctrl(tot_step), fstrparam, sub_step, &
137  & fstrsolid%NRstat_i, fstrsolid%NRstat_r, fstrsolid%AutoINC_stat, fstrsolid%CutBack_stat )
138  if( fstrsolid%TEMP_irres > 0 ) then
139  fstrsolid%FACTOR(1) = 0.d0
140  fstrsolid%FACTOR(2) = 1.d0
141  call table_nlsta(hecmesh,fstrsolid,tot_step,fstr_get_time()+fstr_get_timeinc(), factor)
142  fstrsolid%TEMP_FACTOR = factor
143  else
144  call table_nlsta(hecmesh,fstrsolid,tot_step,fstr_get_time(),factor)
145  fstrsolid%FACTOR(1) = factor
146  call table_nlsta(hecmesh,fstrsolid,tot_step,fstr_get_time()+fstr_get_timeinc(), factor)
147  fstrsolid%FACTOR(2) = factor
148  endif
149 
150  if(hecmesh%my_rank==0) then
151  write(*,'(A,I0,2(A,E12.4))') ' sub_step= ',sub_step,', &
152  & current_time=',fstr_get_time(), ', time_inc=',fstr_get_timeinc()
153  write(*,'(A,2f12.7)') ' loading_factor= ', fstrsolid%FACTOR
154  if( fstrsolid%TEMP_irres > 0 ) write(*,'(A,2f12.7)') ' readtemp_factor= ', fstrsolid%TEMP_FACTOR
155  endif
156 
157  time_1 = hecmw_wtime()
158 
159  ! analysis algorithm ( Newton-Rapshon Method )
160  if( .not. is_interaction_active ) then
161  if( fstrparam%nlsolver_method == knsmnewton ) then
162  call fstr_newton( tot_step, hecmesh, hecmat, fstrsolid, fstrparam, &
163  restart_step_num, sub_step, fstr_get_time(), fstr_get_timeinc() )
164  else if( fstrparam%nlsolver_method == knsmquasinewton ) then
165  call fstr_quasi_newton( tot_step, hecmesh, hecmat, fstrsolid, fstrparam, &
166  restart_step_num, sub_step, fstr_get_time(), fstr_get_timeinc() )
167  endif
168  else
169  if( fstrparam%contact_algo == kcaslagrange ) then
170  call fstr_newton_contactslag( tot_step, hecmesh, hecmat, fstrsolid, fstrparam, heclagmat, &
171  restart_step_num, restart_substep_num, sub_step, fstr_get_time(), fstr_get_timeinc(), infoctchange, conmat )
172  else if( fstrparam%contact_algo == kcaalagrange ) then
173  call fstr_newton_contactalag( tot_step, hecmesh, hecmat, fstrsolid, fstrparam, &
174  restart_step_num, restart_substep_num, sub_step, fstr_get_time(), fstr_get_timeinc(), infoctchange, conmat )
175  endif
176  endif
177 
178  ! Time Increment
179  if( hecmesh%my_rank == 0 ) call fstr_timeinc_printstatus( fstrsolid%step_ctrl(tot_step), fstrparam, &
180  & tot_step_print, sub_step, fstrsolid%NRstat_i, fstrsolid%NRstat_r, &
181  & fstrsolid%AutoINC_stat, fstrsolid%CutBack_stat )
182  if( fstr_cutback_active() ) then
183 
184  if( fstrsolid%CutBack_stat == 0 ) then ! converged
185  call fstr_cutback_save( fstrsolid, infoctchange, infoctchange_bak ) ! save analysis state
186  contact_active_bak = fstr_is_contact_active() ! retain scan-set active for cutback restore
187  call fstr_proceed_time() ! current time += time increment
188 
189  else ! not converged
190  cbbound = fstrparam%ainc(fstrsolid%step_ctrl(tot_step)%AincParam_id)%CBbound
191  if( fstrsolid%CutBack_stat == cbbound ) then
192  if( hecmesh%my_rank == 0 ) then
193  write(*,*) 'Number of successive cutback reached max number: ',cbbound
194  call fstr_timeinc_printstatus_final(.false.)
195  endif
196  call fstr_abort( hecmw_exit_noconv )
197  endif
198  call fstr_cutback_load( fstrsolid, infoctchange, infoctchange_bak ) ! load analysis state
199  call fstr_set_contact_active( contact_active_bak ) ! restore last scan-set active
200 
201  ! restore matrix structure for slagrange contact analysis
202  if( is_interaction_active ) then
203  call fstr_mat_con_contact( tot_step, fstrparam%contact_algo, hecmat, fstrsolid, heclagmat, &
204  & infoctchange, conmat, fstr_is_contact_active())
205  conmat%B(:) = 0.0d0
206  call solve_lineq_contact_init(hecmesh, hecmat, heclagmat, fstr_is_matrixstruct_symmetric(fstrsolid, hecmesh))
207  endif
208  if( hecmesh%my_rank == 0 ) write(*,*) '### State has been restored at time =',fstr_get_time()
209 
210  !stop if # of substeps reached upper bound.
211  if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep ) then
212  if( hecmesh%my_rank == 0 ) then
213  write(*,'(a,i5,a,f6.3)') '### Number of substeps reached max number: at total_step=', &
214  & tot_step_print, ' time=', fstr_get_time()
215  endif
216  call fstr_abort( hecmw_exit_noconv )
217  endif
218 
219  ! output time
220  time_2 = hecmw_wtime()
221  if( hecmesh%my_rank==0) write(imsg,'(a,",",2(I8,","),f10.2)') &
222  & 'step, substep, solve (sec) :', tot_step_print, sub_step, time_2 - time_1
223  cycle
224  endif
225  else
226  if( fstrsolid%CutBack_stat > 0 ) then
227  if( hecmesh%my_rank == 0 ) call fstr_timeinc_printstatus_final(.false.)
228  stop hecmw_exit_noconv
229  endif
230  call fstr_proceed_time() ! current time += time increment
231  endif
232 
233  step_count = step_count + 1
234 
235  ! ----- Restart
236  if( fstrsolid%restart_nout > 0) then
237  if( mod(step_count,fstrsolid%restart_nout) == 0 ) then
238  call fstr_write_restart(tot_step,tot_step_print,sub_step,step_count,fstr_get_time(), &
239  & fstr_get_timeinc_base(), hecmesh,fstrsolid,fstrparam,.false.,infoctchange%contactNode_current)
240  endif
241  endif
242 
243  ! ----- Result output (include visualize output)
244  is_outpoint = fstr_timeinc_istimepoint( fstrsolid%step_ctrl(tot_step), fstrparam ) &
245  & .or. fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) )
246  call fstr_static_output( tot_step, step_count, fstr_get_time(), hecmesh, fstrsolid, fstrparam, &
247  & fstrpr%solution_type, is_outpoint, fstr_get_timeinc() )
248 
249  time_2 = hecmw_wtime()
250  if( hecmesh%my_rank==0 ) then
251  write(imsg,'(A,",",2(I8,","),f10.2)') 'step, substep, solve (sec) :', tot_step_print, sub_step, time_2 - time_1
252  write(imsg,'(A,I0,",",1pE15.8)') '### stepcount (for output), time :', step_count, fstr_get_time()
253  endif
254 
255  !if time reached the end time of step, exit loop.
256  if( fstr_timeinc_isstepfinished( fstrsolid%step_ctrl(tot_step) ) ) exit
257 
258  if( sub_step == fstrsolid%step_ctrl(tot_step)%num_substep ) then
259  if( hecmesh%my_rank == 0 ) then
260  write(*,'(a,i5,a,f6.3)') '### Number of substeps reached max number: at total_step=', &
261  & tot_step_print, ' time=', fstr_get_time()
262  endif
263  if( hecmesh%my_rank == 0 ) call fstr_timeinc_printstatus_final(.false.)
264  stop hecmw_exit_noconv !stop if # of substeps reached upper bound.
265  endif
266 
267  sub_step = sub_step + 1
268  enddo !--- end of substep loop
269 
270  ! ----- Restart at the end of step
271  if( fstrsolid%restart_nout > 0 ) then
272  call fstr_write_restart(tot_step,tot_step_print,sub_step,step_count,fstr_get_time(),fstr_get_timeinc_base(), &
273  & hecmesh,fstrsolid,fstrparam,.true.,infoctchange%contactNode_current)
274  endif
275  restart_substep_num = 1
276  if( fstrsolid%TEMP_irres > 0 ) exit
277  enddo !--- end of tot_step loop
278 
279  call fstr_cutback_finalize( fstrsolid )
280 
281  ! message
282  if(myrank == 0)then
283  call fstr_timeinc_printstatus_final(.true.)
284  write(imsg,'("### FSTR_SOLVE_NLGEOM FINISHED!")')
285  write(*,'("### FSTR_SOLVE_NLGEOM FINISHED!")')
286  endif
287 
288  end subroutine fstr_solve_nlgeom
289 
290  !C================================================================C
293  !C================================================================C
294  subroutine table_nlsta(hecMESH, fstrSOLID, cstep, time, f_t)
295  type ( hecmwST_local_mesh ), intent(in) :: hecMESH
296  type ( fstr_solid ), intent(in) :: fstrSOLID
297  integer(kind=kint), intent(in) :: cstep
298  real(kind=kreal), intent(in) :: time
299  real(kind=kreal), intent(out) :: f_t
300 
301  integer(kind=kint) :: jj_n_amp
302 
303  jj_n_amp = fstrsolid%step_ctrl( cstep )%amp_id
304 
305  if( jj_n_amp <= 0 ) then ! Amplitude not defined
306  f_t = (time-fstrsolid%step_ctrl(cstep)%starttime)/fstrsolid%step_ctrl(cstep)%elapsetime
307  if( f_t>1.d0 ) f_t=1.d0
308  else
309  f_t = 1.0d0
310  call fstr_get_amplitude(hecmesh, fstrsolid, cstep, jj_n_amp, time, f_t)
311  endif
312 
313  end subroutine table_nlsta
314 
315 end module m_fstr_solve_nlgeom
This module provides functions of reconstructing.
subroutine, public fstr_mat_con_contact(cstep, contact_algo, hecMAT, fstrSOLID, hecLagMAT, infoCTChange, conMAT, is_contact_active_flag)
this subroutine reconstructs node-based (stiffness) matrix structure \corresponding to contact state
logical function, public fstr_is_matrixstruct_symmetric(fstrSOLID, hecMESH)
this function judges whether sitiffness matrix is symmetric or not
This module provides functions to deal with cutback.
Definition: fstr_Cutback.f90:7
subroutine fstr_cutback_save(fstrSOLID, infoCTChange, infoCTChange_bak)
Save analysis status.
subroutine fstr_cutback_load(fstrSOLID, infoCTChange, infoCTChange_bak)
Load analysis status.
subroutine fstr_cutback_init(hecMESH, fstrSOLID, fstrPARAM)
Initializer of cutback variables.
subroutine fstr_cutback_finalize(fstrSOLID)
Finalizer of cutback variables.
logical function fstr_cutback_active()
Finite-rotation nodal kinematics for NLGEOM.
subroutine, public fstr_begin_nodal_kinematics_step(hecMESH, fstrSOLID, ndof)
Snapshot the converged rotation state at the start of a load step and reset the Newton trial state to...
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_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 functions on nonlinear analysis.
subroutine fstr_quasi_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 functions to read in and write out restart files.
Definition: fstr_Restart.f90:8
subroutine fstr_read_restart(cstep, substep, step_count, ctime, dtime, hecMESH, fstrSOLID, fstrPARAM, contactNode)
Read in restart file.
subroutine fstr_write_restart(cstep, cstep_ext, substep, step_count, ctime, dtime, hecMESH, fstrSOLID, fstrPARAM, is_StepFinished, contactNode)
write out restart file
This module provides main suboruitne for nonliear calculation.
subroutine table_nlsta(hecMESH, fstrSOLID, cstep, time, f_t)
This subroutine decide the loading increment considering the amplitude definition.
subroutine fstr_solve_nlgeom(hecMESH, hecMAT, fstrSOLID, hecLagMAT, fstrPARAM, conMAT)
This module provides main subroutine for nonlinear calculation.
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)
real(kind=kreal) function fstr_get_timeinc_base()
subroutine fstr_set_timeinc_base(dtime_base)
subroutine fstr_timeinc_settimeincrement(stepinfo, fstrPARAM, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat)
real(kind=kreal) function fstr_get_time()
subroutine fstr_proceed_time()
subroutine fstr_timeinc_printstatus_final(success_flag)
subroutine fstr_timeinc_printstatus_init
subroutine fstr_set_time(time)
logical function fstr_timeinc_isstepfinished(stepinfo)
subroutine fstr_timeinc_printstatus(stepinfo, fstrPARAM, totstep, substep, NRstatI, NRstatR, AutoINC_stat, Cutback_stat)
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:103
integer(kind=kint), parameter imsg
Definition: m_fstr.F90:117
subroutine fstr_get_amplitude(hecMESH, fstrSOLID, cstep, jj_n_amp, time, value)
Evaluate the amplitude-scaled target value a(t) for static analysis.
Definition: m_fstr.F90:1254
subroutine fstr_abort(code)
Terminate the analysis with a classified exit status. MPI_ABORT does not perform the Fortran I/O fina...
Definition: m_fstr.F90:701
integer(kind=kint), parameter kcaslagrange
contact analysis algorithm
Definition: m_fstr.F90:62
integer(kind=kint), parameter knsmnewton
nonlinear solver method (nsm)
Definition: m_fstr.F90:58
integer(kind=kint), parameter knsmquasinewton
Definition: m_fstr.F90:59
integer(kind=kint), parameter kcaalagrange
Definition: m_fstr.F90:63
type(fstr_param), target fstrpr
GLOBAL VARIABLE INITIALIZED IN FSTR_SETUP.
Definition: m_fstr.F90:222
type(tinitialcondition), dimension(:), pointer, save g_initialcnd
Definition: m_fstr.F90:158
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.
This modules just summarizes all modules used in static analysis.
Definition: static_LIB.f90:6
This module provides functions to output result.
subroutine fstr_static_output(cstep, istep, time, hecMESH, fstrSOLID, fstrPARAM, flag, outflag, dtime)
Output result.
Top-level contact analysis module (System level)
subroutine fstr_set_contact_active(a)
logical function fstr_is_contact_active()
Whether contact stiffness and residual have to be assembled. Broader than is_contact_active(state): a...