FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
fstr_setup_finish.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 !-------------------------------------------------------------------------------
9  use m_fstr
10  use fstr_setup_util, only &
11  : fstr_param_pack &
16  use m_fstr_solid_setup, only &
19  use mcontactparam
21  implicit none
22 
26  integer(kind=kint) :: contact_pairs = 0
27  integer(kind=kint) :: embed_pairs = 0
28  integer(kind=kint) :: contact_interferences = 0
29  integer(kind=kint) :: contact_params = 0
30  integer(kind=kint) :: weld_lines = 0
31  integer(kind=kint) :: initial_conditions = 0
32  integer(kind=kint) :: steps = 0
33  integer(kind=kint) :: local_coords = 0
34  integer(kind=kint) :: autoinc_params = 0
35  integer(kind=kint) :: converg_params = 0
36  integer(kind=kint) :: time_points = 0
37  integer(kind=kint) :: materials = 0
38  end type fstr_setup_counts
39 
40 contains
41 
46  subroutine fstr_setup_prepare( P, counts )
47  use mmaterial
48  implicit none
49  type(fstr_param_pack) :: P
50  type(fstr_setup_counts), intent(in) :: counts
51 
52  type(hecmwst_local_mesh), pointer :: hecMESH
53  type(fstr_param), pointer :: fstrPARAM
54  type(fstr_solid), pointer :: fstrSOLID
55  type(fstr_heat), pointer :: fstrHEAT
56  type(fstr_dynamic), pointer :: fstrDYNAMIC
57  integer(kind=kint) :: n, i, cid, n_totlyr
58  real(kind=kreal) :: ee, pp, rho, alpha, thick, alpha_over_mu
59  real(kind=kreal) :: beam_radius, &
60  beam_angle1, beam_angle2, beam_angle3,&
61  beam_angle4, beam_angle5, beam_angle6
62  type(tshellmat),pointer :: shmat(:)
63  character(len=HECMW_FILENAME_LEN) :: logfilename
64 
65  hecmesh => p%MESH
66  fstrparam => p%PARAM
67  fstrsolid => p%SOLID
68  fstrheat => p%HEAT
69  fstrdynamic => p%DYN
70  write( logfilename, '(i5,''.log'')' ) myrank
71 
72  fstrsolid%n_contacts = counts%contact_pairs
73  if( counts%contact_pairs>0 ) then
74  allocate( fstrsolid%contacts( counts%contact_pairs ) )
75  ! convert SURF_SURF contact to NODE_SURF contact
76  call fstr_convert_contact_type( p%MESH )
77  endif
79  fstrsolid%n_embeds = counts%embed_pairs
80  if( counts%embed_pairs>0 ) allocate( fstrsolid%embeds( counts%embed_pairs ) )
81  if( counts%weld_lines>0 ) allocate( fstrheat%weldline( counts%weld_lines ) )
82  if( counts%initial_conditions>0 ) allocate( g_initialcnd( counts%initial_conditions ) )
83  if( counts%steps>0 ) then
84  allocate( fstrsolid%step_ctrl( counts%steps ) )
85  do i=1, counts%steps
86  call init_stepinfo( fstrsolid%step_ctrl(i) )
87  if( p%PARAM%solution_type==kstdynamic ) then
88  fstrsolid%step_ctrl(i)%num_substep = fstrdynamic%n_step
89  fstrsolid%step_ctrl(i)%initdt = fstrdynamic%t_delta
90  fstrsolid%step_ctrl(i)%elapsetime = dble(fstrdynamic%n_step) * fstrdynamic%t_delta
91  fstrsolid%step_ctrl(i)%mindt = fstrdynamic%t_delta
92  fstrsolid%step_ctrl(i)%maxdt = fstrdynamic%t_delta
93  endif
94  end do
95  endif
96  if( counts%local_coords>0 ) allocate( g_localcoordsys(counts%local_coords) )
97  allocate( fstrparam%ainc(0:counts%autoinc_params) )
98  do i=0,counts%autoinc_params
99  call init_aincparam( fstrparam%ainc(i) )
100  end do
101  allocate( fstrparam%cnvparam(0:counts%converg_params) )
102  do i=0,counts%converg_params
103  call init_convergparam( fstrparam%cnvparam(i) )
104  end do
105  if( counts%time_points>0 ) allocate( fstrparam%timepoints(counts%time_points) )
106  allocate( fstrparam%contactparam(0:counts%contact_params) )
107  do i=0,counts%contact_params
108  call init_contactparam( fstrparam%contactparam(i) )
109  end do
110  if( counts%contact_interferences>0 )then
111  allocate( fstrparam%contact_if( counts%contact_interferences ) )
112  do i=1,counts%contact_interferences
113  call init_contact_if( fstrparam%contact_if(i) )
114  end do
115  end if
116 
117  p%SOLID%is_33shell = 0
118  p%SOLID%is_33beam = 0
119 
120  do i=1,hecmesh%n_elem_type
121  n = hecmesh%elem_type_item(i)
122  if (n == 781 .or. n == 761)then
123  p%SOLID%is_33shell = 1
124  elseif (n == 641)then
125  p%SOLID%is_33beam = 1
126  endif
127  enddo
128 
129  n = counts%materials
130  if( hecmesh%material%n_mat>n ) n= hecmesh%material%n_mat
131  if( n==0 ) stop "material property not defined!"
132  allocate( fstrsolid%materials( n ) )
133  do i = 1, n
134  call initmaterial(fstrsolid%materials(i))
135  enddo
136 
137  ! for section control
138  allocate( fstrsolid%sections(hecmesh%section%n_sect) )
139  do i=1,hecmesh%section%n_sect
140  ! set default 361 element formulation
141  if( p%PARAM%solution_type==kststatic .or. p%PARAM%solution_type==kstdynamic ) then
142  if( p%PARAM%nlgeom ) then
143  fstrsolid%sections(i)%elemopt361 = kel361fbar
144  else
145  fstrsolid%sections(i)%elemopt361 = kel361ic
146  end if
147  else if( p%PARAM%solution_type==ksteigen ) then
148  fstrsolid%sections(i)%elemopt361 = kel361ic
149  else if( p%PARAM%solution_type==kststaticeigen ) then
150  fstrsolid%sections(i)%elemopt361 = kel361fbar
151  else
152  fstrsolid%sections(i)%elemopt361 = kel361fi
153  end if
154  fstrsolid%sections(i)%elemopt341 = kel341fi
155  fstrsolid%sections(i)%elemopt611 = kel611euler
156  ! INTERFACE sections are skipped in the loop below and keep this thickness
157  fstrsolid%sections(i)%thickness = 1.0d0
158  enddo
159 
160  if( hecmesh%section%n_sect >0 ) then
161  do i=1,hecmesh%section%n_sect
162  if( hecmesh%section%sect_type(i) == 4 ) cycle
163  cid = hecmesh%section%sect_mat_ID_item(i)
164  if( cid>n ) stop "Error in material property definition!"
165  if( fstrparam%nlgeom .or. fstrparam%solution_type==kststaticeigen ) &
166  fstrsolid%materials(cid)%nlgeom_flag = 1
167  nullify(shmat)
168  call fstr_get_prop(hecmesh,shmat,i,ee,pp,rho,alpha,thick,&
169  n_totlyr,alpha_over_mu, &
170  beam_radius,beam_angle1,beam_angle2,beam_angle3, &
171  beam_angle4,beam_angle5,beam_angle6)
172  fstrsolid%sections(i)%thickness = thick
173  fstrsolid%materials(cid)%name = hecmesh%material%mat_name(cid)
174  fstrsolid%materials(cid)%variables(m_youngs)=ee
175  fstrsolid%materials(cid)%variables(m_poisson)=pp
176  fstrsolid%materials(cid)%variables(m_density)=rho
177  fstrsolid%materials(cid)%variables(m_expansion)=alpha
178  fstrsolid%materials(cid)%variables(m_alpha_over_mu)= alpha_over_mu
179  fstrsolid%materials(cid)%variables(m_beam_radius)=beam_radius
180  fstrsolid%materials(cid)%variables(m_beam_angle1)=beam_angle1
181  fstrsolid%materials(cid)%variables(m_beam_angle2)=beam_angle2
182  fstrsolid%materials(cid)%variables(m_beam_angle3)=beam_angle3
183  fstrsolid%materials(cid)%variables(m_beam_angle4)=beam_angle4
184  fstrsolid%materials(cid)%variables(m_beam_angle5)=beam_angle5
185  fstrsolid%materials(cid)%variables(m_beam_angle6)=beam_angle6
186  fstrsolid%materials(cid)%mtype = elastic
187  if( hecmesh%section%sect_type(i) == 2 ) then
188  fstrsolid%materials(cid)%totallyr = n_totlyr
189  fstrsolid%materials(cid)%shell_var => shmat
190  endif
191  enddo
192  endif
193 
194  allocate( fstrsolid%output_ctrl( 4 ) )
195  call fstr_init_outctrl(fstrsolid%output_ctrl(1))
196  fstrsolid%output_ctrl( 1 )%filename = trim(logfilename)
197  fstrsolid%output_ctrl( 1 )%filenum = ilog
198  call fstr_init_outctrl(fstrsolid%output_ctrl(2))
199  call fstr_init_outctrl(fstrsolid%output_ctrl(3))
200  call fstr_init_outctrl(fstrsolid%output_ctrl(4))
201  end subroutine fstr_setup_prepare
202 
205  subroutine fstr_setup_finish( P, counts )
206  implicit none
207  type(fstr_param_pack) :: P
208  type(fstr_setup_counts), intent(in) :: counts
209 
210  type(hecmwst_local_mesh), pointer :: hecMESH
211  type(fstr_param), pointer :: fstrPARAM
212  type(fstr_solid), pointer :: fstrSOLID
213  type(fstr_dynamic), pointer :: fstrDYNAMIC
214  integer(kind=kint) :: n, i, cid, ierror, n_totlyr
215 
216  hecmesh => p%MESH
217  fstrparam => p%PARAM
218  fstrsolid => p%SOLID
219  fstrdynamic => p%DYN
220 
221  ! ----- material type judgement. in case of infinitive analysis, nlgeom_flag=0
222  if( .not. p%PARAM%nlgeom ) then
223  do i=1, counts%materials
224  fstrsolid%materials(i)%nlgeom_flag = 0
225  enddo
226  endif
227 
228  if( fstrsolid%TEMP_ngrp_tot > 0 .or. fstrsolid%TEMP_irres > 0 ) then
229  allocate ( fstrsolid%temperature( hecmesh%n_node ) ,stat=ierror )
230  if( ierror /= 0 ) then
231  write(idbg,*) 'stop due to allocation error <FSTR_SOLID, TEMPERATURE>'
232  write(idbg,*) ' rank = ', myrank,' ierror = ',ierror
233  call flush(idbg)
234  call hecmw_abort( hecmw_comm_get_comm())
235  end if
236  fstrsolid%temperature = fstrparam%ref_temp
237  allocate ( fstrsolid%last_temp( hecmesh%n_node ) ,stat=ierror )
238  if( ierror /= 0 ) then
239  write(idbg,*) 'stop due to allocation error <FSTR_SOLID, LAST_TEMP>'
240  write(idbg,*) ' rank = ', myrank,' ierror = ',ierror
241  call flush(idbg)
242  call hecmw_abort( hecmw_comm_get_comm())
243  end if
244  fstrsolid%last_temp = 0.d0
245  allocate ( fstrsolid%temp_bak( hecmesh%n_node ) ,stat=ierror )
246  if( ierror /= 0 ) then
247  write(idbg,*) 'stop due to allocation error <FSTR_SOLID, TEMP_BAK>'
248  write(idbg,*) ' rank = ', myrank,' ierror = ',ierror
249  call flush(idbg)
250  call hecmw_abort( hecmw_comm_get_comm())
251  end if
252  fstrsolid%temp_bak = 0.d0
253  endif
254 
255  if( associated(fstrsolid%step_ctrl) ) then
256  fstrsolid%nstep_tot = size(fstrsolid%step_ctrl)
257  call setup_stepinfo_starttime( fstrsolid%step_ctrl )
258  else
259  if( p%PARAM%solution_type==kststatic .and. p%PARAM%nlgeom ) then
260  write( *,* ) " ERROR: STEP not defined!"
261  write( idbg,* ) "ERROR: STEP not defined!"
262  call flush(idbg)
263  call fstr_abort( hecmw_exit_model )
264  endif
265 
266  if( myrank==0 ) write(*,*)"Step control not defined! Using default step=1"
267  fstrsolid%nstep_tot = 1
268  allocate( fstrsolid%step_ctrl(1) )
269  call init_stepinfo( fstrsolid%step_ctrl(1) )
270  if( p%PARAM%solution_type==kstdynamic ) then
271  fstrsolid%step_ctrl(1)%num_substep = fstrdynamic%n_step
272  fstrsolid%step_ctrl(1)%initdt = fstrdynamic%t_delta
273  fstrsolid%step_ctrl(1)%elapsetime = dble(fstrdynamic%n_step) * fstrdynamic%t_delta
274  fstrsolid%step_ctrl(1)%mindt = fstrdynamic%t_delta
275  fstrsolid%step_ctrl(1)%maxdt = fstrdynamic%t_delta
276  endif
277  n = fstrsolid%BOUNDARY_ngrp_tot
278  if( n>0 ) allocate( fstrsolid%step_ctrl(1)%Boundary(n) )
279  do i = 1, n
280  fstrsolid%step_ctrl(1)%Boundary(i) = fstrsolid%BOUNDARY_ngrp_GRPID(i)
281  enddo
282  n = fstrsolid%CLOAD_ngrp_tot + fstrsolid%DLOAD_ngrp_tot + fstrsolid%TEMP_ngrp_tot + fstrsolid%SPRING_ngrp_tot
283  if( n>0 ) allocate( fstrsolid%step_ctrl(1)%Load(n) )
284  n = 0
285  do i = 1, fstrsolid%CLOAD_ngrp_tot
286  n = n + 1
287  fstrsolid%step_ctrl(1)%Load(n) = fstrsolid%CLOAD_ngrp_GRPID(i)
288  enddo
289  do i = 1, fstrsolid%DLOAD_ngrp_tot
290  n = n + 1
291  fstrsolid%step_ctrl(1)%Load(n) = fstrsolid%DLOAD_ngrp_GRPID(i)
292  enddo
293  do i = 1, fstrsolid%TEMP_ngrp_tot
294  n = n + 1
295  fstrsolid%step_ctrl(1)%Load(n) = fstrsolid%TEMP_ngrp_GRPID(i)
296  enddo
297  do i = 1, fstrsolid%SPRING_ngrp_tot
298  n = n + 1
299  fstrsolid%step_ctrl(1)%Load(n) = fstrsolid%SPRING_ngrp_GRPID(i)
300  enddo
301  n = fstrsolid%elemact%ELEMACT_egrp_tot
302  if( n>0 ) allocate( fstrsolid%step_ctrl(1)%ElemActivation(n) )
303  do i = 1, n
304  fstrsolid%step_ctrl(1)%ElemActivation(i) = fstrsolid%elemact%ELEMACT_egrp_GRPID(i)
305  enddo
306  endif
307 
308  call fstr_element_init( hecmesh, fstrsolid, p%PARAM%solution_type )
309  call fstr_check_shell_j2_inputs(hecmesh, fstrsolid, fstrparam)
310  call fstr_check_up_inputs(hecmesh, fstrsolid)
311  call fstr_check_shell_gauss_output(hecmesh, fstrsolid)
312  if( p%PARAM%solution_type==kststatic .or. p%PARAM%solution_type==kstdynamic .or. &
313  p%PARAM%solution_type==ksteigen .or. p%PARAM%solution_type==kststaticeigen ) &
314  call fstr_solid_alloc( hecmesh, fstrsolid )
315 
316  if( p%PARAM%solution_type == kstheat) then
317  p%PARAM%fg_irres = fstrsolid%output_ctrl(3)%frequency
318  p%PARAM%fg_iwres = fstrsolid%output_ctrl(4)%frequency
319  p%HEAT%elemact = p%SOLID%elemact
320  endif
321 
322  n_totlyr = 1
323  do i=1,hecmesh%section%n_sect
324  cid = hecmesh%section%sect_mat_ID_item(i)
325  n = fstrsolid%materials(cid)%totallyr
326  if (n > n_totlyr)then
327  n_totlyr = n
328  endif
329  enddo
330  p%SOLID%max_lyr = n_totlyr
331 
332  call fstr_setup_post( p )
333  end subroutine fstr_setup_finish
334 
335  subroutine fstr_check_up_inputs(hecMESH, fstrSOLID)
336  type(hecmwst_local_mesh), intent(in) :: hecMESH
337  type(fstr_solid), intent(in) :: fstrSOLID
338  integer(kind=kint) :: i, isect, mtype
339 
340  do i = 1, hecmesh%n_elem
341  if( hecmesh%elem_type(i) /= 361 ) cycle
342  isect = hecmesh%section_ID(i)
343  if( fstrsolid%sections(isect)%elemopt361 /= kel361up ) cycle
344  if( .not.associated(fstrsolid%elements(i)%gausses) ) cycle
345  mtype = fstrsolid%elements(i)%gausses(1)%pMaterial%mtype
346  if( .not.iselastoplastic(mtype) .and. .not.iscreep(mtype) ) cycle
347  write(*,*) '###ERROR### : Elastoplastic and creep materials are not supported by FORM361=UP'
348  write(ilog,*) '###ERROR### : Elastoplastic and creep materials are not supported by FORM361=UP'
349  call hecmw_abort(hecmw_comm_get_comm())
350  enddo
351  end subroutine fstr_check_up_inputs
352 
353  subroutine fstr_check_shell_gauss_output(hecMESH, fstrSOLID)
355  type(hecmwst_local_mesh), intent(in) :: hecMESH
356  type(fstr_solid), intent(in) :: fstrSOLID
357  integer(kind=kint) :: i
358 
359  if( hecmesh%n_dof /= 6 ) return
360  if( .not.any(fstrsolid%output_ctrl(3)%outinfo%on(9:10)) ) return
361  do i=1,hecmesh%n_elem
362  if( fstr_shell_output_point_count(fstrsolid%elements(i))>0 ) cycle
363  write(*,*) '###ERROR### : ISTRAIN/ISTRESS require shell thickness-point output support; element type = ', &
364  hecmesh%elem_type(i)
365  call hecmw_abort(hecmw_comm_get_comm())
366  enddo
367  end subroutine fstr_check_shell_gauss_output
368 
369  subroutine fstr_check_shell_j2_inputs(hecMESH, fstrSOLID, fstrPARAM)
372  use, intrinsic :: ieee_arithmetic, only: ieee_is_finite
373  type(hecmwst_local_mesh), intent(in) :: hecMESH
374  type(fstr_solid), intent(in) :: fstrSOLID
375  type(fstr_param), intent(in) :: fstrPARAM
376  type(tmaterial), pointer :: material
377  integer(kind=kint) :: i, nn, ierr, isect, index, ilayer
378  real(kind=kreal) :: elastic(2)
379  logical :: missing
380  character(len=160) :: message
381 
382  do i = 1, hecmesh%n_elem
383  if( hecmesh%elem_type(i) /= 741 ) cycle
384  if( .not.associated(fstrsolid%elements(i)%gausses) ) cycle
385  material => fstrsolid%elements(i)%gausses(1)%pMaterial
386  if( .not.iselastoplastic(material%mtype) ) cycle
387  nn = hecmesh%elem_node_index(i)-hecmesh%elem_node_index(i-1)
388  message = ''
389  call checkplanestressj2material(material, ierr)
390  if( ierr /= 0 ) then
391  message = planestressj2errormessage(ierr)
392  else if( .not.fstr_uses_plane_stress_j2_shell(741, nn, material) ) then
393  message = 'Elastoplastic MITC4 shells require INFINITESIMAL material kinematics'
394  else if( fstrparam%solution_type /= kststatic .or. .not.fstrparam%nlgeom ) then
395  message = 'Elastoplastic MITC4 shells require !SOLUTION, TYPE=STATIC, NONLINEAR'
396  else if( fstrsolid%TEMP_ngrp_tot > 0 .or. fstrsolid%TEMP_irres > 0 ) then
397  message = 'Temperature loading is not supported in models with elastoplastic MITC4 shells'
398  endif
399  if( len_trim(message) == 0 .and. associated(material%shell_var) ) then
400  ! The J2 return mapping uses the common elastic table, not layer-specific constants.
401  call fetch_tabledata(mc_isoelastic, material%dict, elastic, missing)
402  do ilayer = 1, material%totallyr
403  if( .not.ieee_is_finite(material%shell_var(ilayer)%ee) .or. &
404  .not.ieee_is_finite(material%shell_var(ilayer)%pp) ) then
405  message = 'Invalid elastic properties in J2 shell layer'
406  exit
407  endif
408  if( abs(material%shell_var(ilayer)%ee-elastic(1)) > 1.0d-12*elastic(1) .or. &
409  abs(material%shell_var(ilayer)%pp-elastic(2)) > 1.0d-12 ) then
410  message = 'J2 shell layers must share the !ELASTIC Young modulus and Poisson ratio'
411  exit
412  endif
413  enddo
414  endif
415  if( len_trim(message) == 0 ) then
416  isect = hecmesh%section_ID(i)
417  index = hecmesh%section%sect_I_index(isect-1)
418  if( hecmesh%section%sect_I_index(isect)-index /= 1 ) then
419  message = 'Elastoplastic MITC4 shells require a SHELL section with 2 thickness integration points'
420  else if( hecmesh%section%sect_I_item(index+1) /= numofshellthicknessquadpoints(741) ) then
421  message = 'Elastoplastic MITC4 shells require 2 thickness integration points in !SECTION'
422  endif
423  endif
424  if( len_trim(message) == 0 ) cycle
425  write(*,*) '###ERROR### : ', trim(message)
426  write(ilog,*) '###ERROR### : ', trim(message)
427  call hecmw_abort(hecmw_comm_get_comm())
428  enddo
429  end subroutine fstr_check_shell_j2_inputs
430 
431  !-----------------------------------------------------------------------------!
433 
434  subroutine fstr_setup_post_phys_alloc(phys, NDOF, n_node, n_elem)
435  implicit none
436  type(fstr_solid_physic_val), pointer :: phys
437  integer(kind=kint) :: NDOF, n_node, n_elem, mdof, istat
438  mdof = (ndof*ndof+ndof)/2;
439  allocate ( phys%STRAIN (mdof*n_node), stat=istat)
440  if( istat /= 0 ) stop "Allocation error: phys%STRAIN"
441  allocate ( phys%STRESS (mdof*n_node), stat=istat)
442  if( istat /= 0 ) stop "Allocation error: phys%STRESS"
443  allocate ( phys%MISES ( n_node), stat=istat)
444  if( istat /= 0 ) stop "Allocation error: phys%MISES"
445  allocate ( phys%ESTRAIN (mdof*n_elem), stat=istat)
446  if( istat /= 0 ) stop "Allocation error: phys%ESTRAIN"
447  allocate ( phys%ESTRESS (mdof*n_elem), stat=istat)
448  if( istat /= 0 ) stop "Allocation error: phys%ESTRESS"
449  allocate ( phys%EMISES ( n_elem), stat=istat)
450  if( istat /= 0 ) stop "Allocation error: phys%EMISES"
451  allocate ( phys%EPLSTRAIN ( n_elem), stat=istat)
452  if( istat /= 0 ) stop "Allocation error: phys%EPLSTRAIN"
453  allocate ( phys%ENQM (12*n_elem), stat=istat)
454  if( istat /= 0 ) stop "Allocation error: phys%ENQM"
455  end subroutine fstr_setup_post_phys_alloc
456 
457  subroutine fstr_setup_post( P )
458  implicit none
459  integer(kind=kint) :: i
460  type(fstr_param_pack) :: P
461  type(fstr_solid_physic_val), pointer :: phys => null()
462 
463  if( p%PARAM%solution_type == kststatic &
464  .or. p%PARAM%solution_type == ksteigen &
465  .or. p%PARAM%solution_type == kstdynamic &
466  .or. p%PARAM%solution_type == kststaticeigen ) then
467  ! Memory Allocation for Result Vectors ------------
468  if( p%MESH%n_dof == 6 .or. p%SOLID%is_33shell == 1 ) then
469  allocate ( p%SOLID%SHELL )
470  call fstr_setup_post_phys_alloc(p%SOLID%SHELL,3, p%MESH%n_node,p%MESH%n_elem)
471  allocate ( p%SOLID%SHELL%LAYER(p%SOLID%max_lyr) )
472  do i=1,p%SOLID%max_lyr
473  allocate ( p%SOLID%SHELL%LAYER(i)%PLUS )
474  allocate ( p%SOLID%SHELL%LAYER(i)%MINUS )
475  call fstr_setup_post_phys_alloc(p%SOLID%SHELL%LAYER(i)%PLUS , 3, p%MESH%n_node, p%MESH%n_elem)
476  call fstr_setup_post_phys_alloc(p%SOLID%SHELL%LAYER(i)%MINUS, 3, p%MESH%n_node, p%MESH%n_elem)
477  enddo
478  phys => p%SOLID%SHELL
479  else
480  allocate ( p%SOLID%SOLID )
481  phys => p%SOLID%SOLID
482  call fstr_setup_post_phys_alloc(phys, p%MESH%n_dof, p%MESH%n_node, p%MESH%n_elem)
483  end if
484  p%SOLID%STRAIN => phys%STRAIN
485  p%SOLID%STRESS => phys%STRESS
486  p%SOLID%MISES => phys%MISES
487  p%SOLID%ESTRAIN => phys%ESTRAIN
488  p%SOLID%ESTRESS => phys%ESTRESS
489  p%SOLID%EMISES => phys%EMISES
490  p%SOLID%EPLSTRAIN => phys%EPLSTRAIN
491  p%SOLID%ENQM => phys%ENQM
492  allocate( p%SOLID%REACTION( p%MESH%n_dof*p%MESH%n_node ), stat=i )
493  if( i /= 0 ) stop "Allocation error: REACTION"
494  p%SOLID%REACTION = 0.d0
495  end if
496 
497  call hecmw_barrier( p%MESH ) ! JP-7
498 
499  if( p%HEAT%STEPtot == 0 ) then ! No !HEAT Input
500  if( p%PARAM%analysis_n == 0 ) then ! No !STATIC Input
501  call reallocate_real( p%PARAM%dtime, 1)
502  call reallocate_real( p%PARAM%etime, 1)
503  call reallocate_real( p%PARAM%dtmin, 1)
504  call reallocate_real( p%PARAM%delmax,1)
505  call reallocate_integer( p%PARAM%itmax, 1)
506  call reallocate_real( p%PARAM%eps, 1)
507  p%PARAM%analysis_n = 1
508  p%PARAM%dtime = 0
509  p%PARAM%etime = 0
510  p%PARAM%dtmin = 0
511  p%PARAM%delmax = 0
512  p%PARAM%itmax = 20
513  p%PARAM%eps = 1.0e-6
514  end if
515  p%HEAT%STEPtot = 1
516  call reallocate_real( p%HEAT%STEP_DLTIME, 1)
517  call reallocate_real( p%HEAT%STEP_EETIME, 1)
518  call reallocate_real( p%HEAT%STEP_DELMIN, 1)
519  call reallocate_real( p%HEAT%STEP_DELMAX, 1)
520  p%HEAT%STEP_DLTIME = 0
521  p%HEAT%STEP_EETIME = 0
522  p%HEAT%STEP_DELMIN = 0
523  p%HEAT%STEP_DELMAX = 0
524  end if
525  end subroutine fstr_setup_post
526 
527  !-----------------------------------------------------------------------------!
529  !-----------------------------------------------------------------------------!
530 
531  subroutine fstr_convert_contact_type( hecMESH )
532  implicit none
533  type(hecmwst_local_mesh), pointer :: hecMESH
534  integer(kind=kint) :: n, i, sgrp_id, ngrp_id
535  ! convert SURF_SURF to NODE_SURF
536  n = hecmesh%contact_pair%n_pair
537  do i = 1,n
538  if( hecmesh%contact_pair%type(i) /= hecmw_contact_type_surf_surf ) cycle
539  sgrp_id = hecmesh%contact_pair%slave_grp_id(i)
540  call append_node_grp_from_surf_grp( hecmesh, sgrp_id, ngrp_id )
541  ! change type of contact and slave group ID
542  hecmesh%contact_pair%type(i) = hecmw_contact_type_node_surf
543  hecmesh%contact_pair%slave_grp_id(i) = ngrp_id
544  enddo
545  end subroutine fstr_convert_contact_type
546 
547  !-----------------------------------------------------------------------------!
549  !-----------------------------------------------------------------------------!
550 
558  implicit none
559  type(fstr_param_pack) :: P
560  type(hecmwst_local_mesh), pointer :: hecMESH
561  integer(kind=kint), allocatable :: rot_node(:), n_rot(:), n_rot_all(:), n_explicit(:), rot_grp(:), src(:)
562  integer(kind=kint), allocatable :: new_index(:), new_list(:)
563  character(len=HECMW_NAME_LEN), allocatable :: new_name(:)
564  logical, allocatable :: is_rot(:), in_all(:), is_explicit(:)
565  integer(kind=kint) :: icel, is, ie, nn, i, j, k, m, n, ig, n_new, first_id, ids, ide
566 
567  hecmesh => p%MESH
568  if( hecmesh%n_dof /= 3 ) return
569 
570  ! explicit dummy nodes are in ALL, and the generated ones are not
571  allocate( in_all(hecmesh%n_node) )
572  in_all = .false.
573  ig = get_grp_id( hecmesh, 'node_grp', 'ALL' )
574  if( ig > 0 ) then
575  is = hecmesh%node_group%grp_index(ig-1)
576  in_all(hecmesh%node_group%grp_item(is+1:hecmesh%node_group%grp_index(ig))) = .true.
577  endif
578 
579  allocate( rot_node(hecmesh%n_node), is_explicit(hecmesh%n_node) )
580  rot_node = 0
581  is_explicit = .false.
582  do icel = 1, hecmesh%n_elem
583  if( .not. hecmw_is_etype_33struct(hecmesh%elem_type(icel)) ) cycle
584  nn = hecmw_get_max_node(hecmesh%elem_type(icel))/2
585  is = hecmesh%elem_node_index(icel-1)
586  do j = 1, nn
587  rot_node(hecmesh%elem_node_item(is+j)) = hecmesh%elem_node_item(is+nn+j)
588  if( in_all(hecmesh%elem_node_item(is+nn+j)) ) is_explicit(hecmesh%elem_node_item(is+j)) = .true.
589  enddo
590  enddo
591  ! a rank may hold an external translational node without its 641/761/781 element,
592  ! so the conditions are converted on every rank by the counts over all the ranks
593  n = count( rot_node > 0 )
594  call hecmw_allreduce_i1( hecmesh, n, hecmw_max )
595  if( n == 0 ) return
596 
597  allocate( n_rot(hecmesh%node_group%n_grp), n_rot_all(hecmesh%node_group%n_grp) )
598  allocate( n_explicit(hecmesh%node_group%n_grp) )
599  do ig = 1, hecmesh%node_group%n_grp
600  is = hecmesh%node_group%grp_index(ig-1)
601  n_rot(ig) = count( rot_node(hecmesh%node_group%grp_item(is+1:hecmesh%node_group%grp_index(ig))) > 0 )
602  n_explicit(ig) = count( is_explicit(hecmesh%node_group%grp_item(is+1:hecmesh%node_group%grp_index(ig))) )
603  enddo
604  n_rot_all = n_rot
605  call hecmw_allreduce_i( hecmesh, n_rot_all, hecmesh%node_group%n_grp, hecmw_max )
606 
607  do i = 1, p%SOLID%SPRING_ngrp_tot
608  if( p%SOLID%SPRING_ngrp_DOF(i) > 3 .and. n_rot_all(p%SOLID%SPRING_ngrp_ID(i)) > 0 ) &
609  call rotation_dof_err_stop( '!SPRING' )
610  enddo
611  do i = 1, p%SOLID%VELOCITY_ngrp_tot
612  if( p%SOLID%VELOCITY_ngrp_rotID(i) > 0 ) cycle
613  if( mod(p%SOLID%VELOCITY_ngrp_type(i), 10) > 3 .and. n_rot_all(p%SOLID%VELOCITY_ngrp_ID(i)) > 0 ) &
614  call rotation_dof_err_stop( '!VELOCITY' )
615  enddo
616  do i = 1, p%SOLID%ACCELERATION_ngrp_tot
617  if( mod(p%SOLID%ACCELERATION_ngrp_type(i), 10) > 3 .and. n_rot_all(p%SOLID%ACCELERATION_ngrp_ID(i)) > 0 ) &
618  call rotation_dof_err_stop( '!ACCELERATION' )
619  enddo
620  do i = 1, p%FREQ%FLOAD_ngrp_tot
621  if( p%FREQ%FLOAD_ngrp_TYPE(i) /= kfloadtype_node ) cycle
622  if( p%FREQ%FLOAD_ngrp_DOF(i) > 3 .and. n_rot_all(p%FREQ%FLOAD_ngrp_ID(i)) > 0 ) &
623  call rotation_dof_err_stop( '!FLOAD' )
624  enddo
625  !the rotational DOFs of !FACCELERATION are also not allowed (the end DOF is mod(type,10))
626  do i = 1, p%FREQ%FACC_ngrp_tot
627  if( mod(p%FREQ%FACC_ngrp_type(i), 10) > 3 .and. n_rot_all(p%FREQ%FACC_ngrp_ID(i)) > 0 ) &
628  call rotation_dof_err_stop( '!FACCELERATION' )
629  enddo
630  do i = 1, hecmesh%mpc%n_mpc
631  do j = hecmesh%mpc%mpc_index(i-1)+1, hecmesh%mpc%mpc_index(i)
632  if( hecmesh%mpc%mpc_dof(j) > 3 .and. rot_node(hecmesh%mpc%mpc_item(j)) > 0 ) &
633  call rotation_dof_err_stop( '!EQUATION' )
634  enddo
635  enddo
636 
637  ! node groups whose rotation is moved: rot_grp(ig) = -1, then the id of the dummy node group
638  allocate( rot_grp(hecmesh%node_group%n_grp) )
639  rot_grp = 0
640  do i = 1, p%SOLID%BOUNDARY_ngrp_tot
641  if( p%SOLID%BOUNDARY_ngrp_rotID(i) > 0 ) cycle
642  ig = p%SOLID%BOUNDARY_ngrp_ID(i)
643  if( mod(p%SOLID%BOUNDARY_ngrp_type(i), 10) <= 3 .or. n_rot_all(ig) == 0 ) cycle
644  if( n_explicit(ig) > 0 ) call explicit_dummy_node_err_stop( '!BOUNDARY' )
645  rot_grp(ig) = -1
646  enddo
647  do i = 1, p%SOLID%CLOAD_ngrp_tot
648  if( p%SOLID%CLOAD_ngrp_rotID(i) > 0 .or. p%SOLID%CLOAD_ngrp_DOF(i) <= 3 ) cycle
649  ig = p%SOLID%CLOAD_ngrp_ID(i)
650  is = hecmesh%node_group%grp_index(ig-1)
651  ie = hecmesh%node_group%grp_index(ig)
652  if( any( rot_node(hecmesh%node_group%grp_item(is+1:ie)) == 0 .and. &
653  hecmesh%node_group%grp_item(is+1:ie) <= hecmesh%nn_internal ) ) call fstr_setup_util_err_stop( &
654  '### Error: !CLOAD : dof 4-6 is given to nodes without rotational dof' )
655  if( n_explicit(ig) > 0 ) call explicit_dummy_node_err_stop( '!CLOAD' )
656  rot_grp(ig) = -1
657  enddo
658 
659  n_new = count( rot_grp == -1 )
660  if( n_new == 0 ) return
661  allocate( new_name(n_new), new_index(0:n_new), new_list(sum(n_rot, mask=rot_grp == -1)) )
662  new_index(0) = 0
663  k = 0
664  m = 0
665  do ig = 1, hecmesh%node_group%n_grp
666  if( rot_grp(ig) /= -1 ) cycle
667  k = k + 1
668  write( new_name(k), '(a,i0)' ) 'FSTR_ROT_', ig
669  do j = hecmesh%node_group%grp_index(ig-1)+1, hecmesh%node_group%grp_index(ig)
670  if( rot_node(hecmesh%node_group%grp_item(j)) == 0 ) cycle
671  m = m + 1
672  new_list(m) = rot_node(hecmesh%node_group%grp_item(j))
673  enddo
674  new_index(k) = m
675  rot_grp(ig) = k
676  enddo
677  call append_new_groups( hecmesh, 'node_grp', n_new, new_name, new_index, new_list, first_id )
678  where( rot_grp > 0 ) rot_grp = rot_grp + first_id - 1
679 
680  ! split each !BOUNDARY entry into dof 1-3 of its nodes and dof 1-3 of their dummy nodes
681  n = p%SOLID%BOUNDARY_ngrp_tot
682  if( n > 0 ) then
683  allocate( src(2*n), is_rot(2*n) )
684  m = 0
685  do i = 1, n
686  ide = mod(p%SOLID%BOUNDARY_ngrp_type(i), 10)
687  if( p%SOLID%BOUNDARY_ngrp_rotID(i) <= 0 .and. ide > 3 .and. rot_grp(p%SOLID%BOUNDARY_ngrp_ID(i)) > 0 ) then
688  if( p%SOLID%BOUNDARY_ngrp_type(i)/10 <= 3 ) then
689  m = m + 1
690  src(m) = i
691  is_rot(m) = .false.
692  endif
693  m = m + 1
694  src(m) = i
695  is_rot(m) = .true.
696  else
697  m = m + 1
698  src(m) = i
699  is_rot(m) = .false.
700  endif
701  enddo
702  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_GRPID, src, m )
703  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_ID, src, m )
704  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_type, src, m )
705  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_amp, src, m )
706  call remap_real_array( p%SOLID%BOUNDARY_ngrp_val, src, m )
707  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_istot, src, m )
708  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_rotID, src, m )
709  call remap_integer_array( p%SOLID%BOUNDARY_ngrp_centerID, src, m )
710  p%SOLID%BOUNDARY_ngrp_tot = m
711  do k = 1, m
712  if( p%SOLID%BOUNDARY_ngrp_rotID(k) > 0 ) cycle
713  ig = p%SOLID%BOUNDARY_ngrp_ID(k)
714  ids = p%SOLID%BOUNDARY_ngrp_type(k)/10
715  ide = mod(p%SOLID%BOUNDARY_ngrp_type(k), 10)
716  if( ide <= 3 .or. rot_grp(ig) <= 0 ) cycle
717  if( is_rot(k) ) then
718  p%SOLID%BOUNDARY_ngrp_ID(k) = rot_grp(ig)
719  p%SOLID%BOUNDARY_ngrp_type(k) = 10 * (max(ids, 4) - 3) + (ide - 3)
720  else
721  p%SOLID%BOUNDARY_ngrp_type(k) = 10 * ids + 3
722  endif
723  enddo
724  endif
725 
726  do i = 1, p%SOLID%CLOAD_ngrp_tot
727  if( p%SOLID%CLOAD_ngrp_rotID(i) > 0 .or. p%SOLID%CLOAD_ngrp_DOF(i) <= 3 ) cycle
728  p%SOLID%CLOAD_ngrp_ID(i) = rot_grp(p%SOLID%CLOAD_ngrp_ID(i))
729  p%SOLID%CLOAD_ngrp_DOF(i) = p%SOLID%CLOAD_ngrp_DOF(i) - 3
730  enddo
731  end subroutine fstr_convert_rotation_dof
732 
733  subroutine rotation_dof_err_stop( header_name )
734  implicit none
735  character(len=*) :: header_name
736 
737  call fstr_setup_util_err_stop( '### Error: '//header_name// &
738  ' : dof 4-6 of beam/shell nodes in a mesh with solid elements is not supported' )
739  end subroutine rotation_dof_err_stop
740 
741  subroutine explicit_dummy_node_err_stop( header_name )
742  implicit none
743  character(len=*) :: header_name
744 
745  call fstr_setup_util_err_stop( '### Error: '//header_name// &
746  ' : dof 4-6 is given to beam/shell nodes with explicit dummy nodes; give it as dof 1-3 of the dummy nodes' )
747  end subroutine explicit_dummy_node_err_stop
748 
749  subroutine remap_integer_array( array, src, n )
750  implicit none
751  integer(kind=kint), pointer :: array(:)
752  integer(kind=kint), intent(in) :: src(:), n
753  integer(kind=kint), pointer :: new_array(:)
754 
755  allocate( new_array(n) )
756  new_array(1:n) = array(src(1:n))
757  deallocate( array )
758  array => new_array
759  end subroutine remap_integer_array
760 
761  subroutine remap_real_array( array, src, n )
762  implicit none
763  real(kind=kreal), pointer :: array(:)
764  integer(kind=kint), intent(in) :: src(:), n
765  real(kind=kreal), pointer :: new_array(:)
766 
767  allocate( new_array(n) )
768  new_array(1:n) = array(src(1:n))
769  deallocate( array )
770  array => new_array
771  end subroutine remap_real_array
772 
773 end module m_fstr_setup_finish
This module encapsulate the basic functions of all elements provide by this software.
Definition: element.f90:43
integer function numofshellthicknessquadpoints(etype)
Obtains the number of through-thickness quadrature points of a shell element.
Definition: element.f90:490
This module contains auxiliary functions in calculation setup.
subroutine append_node_grp_from_surf_grp(hecMESH, sgrp_id, ngrp_id)
subroutine fstr_setup_util_err_stop(msg)
subroutine reallocate_real(array, n)
subroutine reallocate_integer(array, n)
This module contains auxiliary functions in calculation setup.
subroutine append_new_groups(hecMESH, grp_type_name, n, names, index, list, first_id)
Append n groups at once; group i holds list(index(i-1)+1:index(i)).
integer(kind=kint) function get_grp_id(hecMESH, grp_type_name, name)
This module provide functions for elastoplastic calculation.
character(len=128) function, public planestressj2errormessage(ierr)
subroutine, public checkplanestressj2material(matl, ierr)
This module provides subroutines to process the data read from the cards, independently of the input ...
subroutine fstr_setup_prepare(P, counts)
Allocation and preparation after the cards are counted: the arrays sized by counts,...
subroutine remap_real_array(array, src, n)
subroutine fstr_check_shell_j2_inputs(hecMESH, fstrSOLID, fstrPARAM)
subroutine fstr_setup_post_phys_alloc(phys, NDOF, n_node, n_elem)
Initial setting of postprecessor.
subroutine fstr_setup_post(P)
subroutine fstr_check_shell_gauss_output(hecMESH, fstrSOLID)
subroutine fstr_check_up_inputs(hecMESH, fstrSOLID)
subroutine explicit_dummy_node_err_stop(header_name)
subroutine fstr_convert_rotation_dof(P)
Move dof 4-6 of 641/761/781 nodes to their rotational dummy nodes !
subroutine remap_integer_array(array, src, n)
subroutine fstr_setup_finish(P, counts)
Processing after all the cards are read: the temperature arrays, the default step,...
subroutine rotation_dof_err_stop(header_name)
subroutine fstr_convert_contact_type(hecMESH)
Convert SURF-SURF contact to NODE-SURF contact !
This module provides subroutines to initialize, allocate and finalize fstr_solid, and to read the car...
subroutine fstr_element_init(hecMESH, fstrSOLID, solution_type)
Initialize elements info in static calculation.
subroutine fstr_solid_alloc(hecMESH, fstrSOLID)
Initializer of structure fstr_solid.
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
integer(kind=kint), parameter kstdynamic
Definition: m_fstr.F90:41
integer(kind=kint), parameter kel361up
Definition: m_fstr.F90:88
integer(kind=kint), parameter kel341fi
section control
Definition: m_fstr.F90:81
integer(kind=kint), parameter idbg
Definition: m_fstr.F90:122
integer(kind=kint), parameter kel361fi
Definition: m_fstr.F90:84
integer(kind=kint), parameter kel361ic
Definition: m_fstr.F90:86
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
integer(kind=kint), parameter ilog
FILE HANDLER.
Definition: m_fstr.F90:118
integer(kind=kint), parameter kststatic
Definition: m_fstr.F90:38
integer(kind=kint), parameter kfloadtype_node
Definition: m_fstr.F90:93
integer(kind=kint), parameter kststaticeigen
Definition: m_fstr.F90:43
integer(kind=kint), parameter kstheat
Definition: m_fstr.F90:40
integer(kind=kint), parameter kel361fbar
Definition: m_fstr.F90:87
integer(kind=kint), parameter ksteigen
Definition: m_fstr.F90:39
type(tinitialcondition), dimension(:), pointer, save g_initialcnd
Definition: m_fstr.F90:139
integer(kind=kint), parameter kel611euler
Definition: m_fstr.F90:90
This module provides a function to fetch material properties from hecmw.
subroutine fstr_get_prop(hecMESH, shell_var, isect, ee, pp, rho, alpha, thick, n_totlyr, alpha_over_mu, beam_radius, beam_angle1, beam_angle2, beam_angle3, beam_angle4, beam_angle5, beam_angle6)
This module manage the parameters for contact calculation.
subroutine, public init_contactparam(cparam)
subroutine, public init_contact_if(contact_if)
This module summarizes all information of material properties.
Definition: material.f90:6
integer(kind=kint), parameter m_youngs
Definition: material.f90:95
integer(kind=kint), parameter m_expansion
Definition: material.f90:107
integer(kind=kint), parameter m_beam_radius
Definition: material.f90:111
integer(kind=kint), parameter m_beam_angle6
Definition: material.f90:117
integer(kind=kint), parameter elastic
Definition: material.f90:68
integer(kind=kint), parameter m_beam_angle3
Definition: material.f90:114
integer(kind=kint), parameter m_density
Definition: material.f90:97
integer(kind=kint), parameter m_beam_angle4
Definition: material.f90:115
integer(kind=kint), parameter m_poisson
Definition: material.f90:96
integer(kind=kint), parameter m_beam_angle1
Definition: material.f90:112
integer(kind=kint), parameter m_beam_angle5
Definition: material.f90:116
integer(kind=kint), parameter m_beam_angle2
Definition: material.f90:113
integer(kind=kint), parameter m_alpha_over_mu
Definition: material.f90:109
subroutine initmaterial(material)
Initializer.
Definition: material.f90:191
This modules defines a structure to record history dependent parameter in static analysis.
Definition: mechgauss.f90:6
integer(kind=kint) function fstr_shell_output_point_count(element)
Number of shell thickness-point tensors available for result output.
Definition: mechgauss.f90:52
Package of all data needs to initialize.
Data for DYNAMIC ANSLYSIS (fstrDYNAMIC)
Definition: m_fstr.F90:525
Data for HEAT ANSLYSIS (fstrHEAT)
Definition: m_fstr.F90:440
FSTR INNER CONTROL PARAMETERS (fstrPARAM)
Definition: m_fstr.F90:142
Data for STATIC ANSLYSIS (fstrSOLID)
Definition: m_fstr.F90:203
Counts of the input for fstr_setup_prepare and fstr_setup_finish, independent of the input file forma...