FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
mechgauss.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 module mmechgauss
7  use hecmw_util
8  use mmaterial
11  implicit none
12 
13  ! ----------------------------------------------------------------------------
16  type(tmaterial), pointer :: pmaterial => null()
17  real(kind=kreal) :: strain(6)
18  real(kind=kreal) :: stress(6)
19  integer, pointer :: istatus(:) =>null()
20  real(kind=kreal), pointer :: fstatus(:) => null()
21  real(kind=kreal) :: plstrain
22  real(kind=kreal) :: strain_bak(6)
23  real(kind=kreal) :: stress_bak(6)
24  real(kind=kreal) :: nqm(12)
25  real(kind=kreal) :: strain_out(6)
26  real(kind=kreal) :: stress_out(6)
27  real(kind=kreal) :: strain_energy
28  real(kind=kreal) :: strain_energy_bak
29  real(kind=kreal) :: plpotential
30  end type
31 
32  ! ----------------------------------------------------------------------------
34  type telement
35  integer :: etype
36  integer :: iset
37  real(kind=kreal), pointer :: equiforces(:) => null()
38  type(tgaussstatus), pointer :: gausses(:) => null()
39  type(tgaussstatus), pointer :: shell_layer_gausses(:) => null()
40  integer(kind=kint) :: shell_nlayer = 0
41  integer(kind=kint) :: shell_nthick = 0
42  real(kind=kreal), pointer :: aux(:,:) => null()
43  integer :: elemact_flag
44  real(kind=kreal) :: elemact_coeff
45  real(kind=kreal) :: p(1)
46  end type
47 
48 contains
49 
51  integer(kind=kint) function fstr_shell_output_point_count(element) result(npoint)
52  type(telement), intent(in) :: element
53 
54  npoint = 0
55  if( associated(element%shell_layer_gausses) ) then
56  npoint = size(element%shell_layer_gausses)
57  return
58  endif
59  select case(element%etype)
61  if( .not.associated(element%gausses) ) return
62  if( element%gausses(1)%pMaterial%nlgeom_flag /= infinitesimal ) return
63  if( .not.iselastic(element%gausses(1)%pMaterial%mtype) ) return
64  npoint = size(element%gausses)*element%gausses(1)%pMaterial%totallyr &
65  *numofshellthicknessquadpoints(element%etype)
66  end select
68 
71  logical function fstr_uses_plane_stress_j2_shell( etype, nn, material )
72  integer(kind=kint), intent(in) :: etype
73  integer(kind=kint), intent(in) :: nn
74  type(tmaterial), intent(in) :: material
75 
77  if( etype /= fe_mitc4_shell .or. nn /= 4 ) return
78  if( material%nlgeom_flag /= infinitesimal ) return
79  if( .not. iselastoplastic(material%mtype) ) return
80  if( getelastictype(material%mtype) /= 0 ) return
81  if( getyieldfunction(material%mtype) /= 0 ) return
82  if( gethardentype(material%mtype) /= 0 ) return
83  if( abs(material%variables(m_plconst2)) > tiny(1.0d0) ) return
86 
88  subroutine fstr_init_gauss( gauss )
90  type( tgaussstatus ), intent(inout) :: gauss
91  integer :: n
92  gauss%strain=0.d0; gauss%stress=0.d0
93  gauss%strain_bak=0.d0; gauss%stress_bak=0.d0
94  gauss%strain_out=0.d0; gauss%stress_out=0.d0
95  gauss%plstrain =0.d0
96  gauss%plpotential =0.d0
97  gauss%nqm =0.d0
98  gauss%strain_energy =0.d0
99  gauss%strain_energy_bak =0.d0
100  if( gauss%pMaterial%mtype==usermaterial ) then
101  if( gauss%pMaterial%nfstatus> 0 ) then
102  allocate( gauss%fstatus(gauss%pMaterial%nfstatus) )
103  gauss%fstatus(:) = 0.d0
104  endif
105  else if( iselastoplastic(gauss%pMaterial%mtype) ) then
106  allocate( gauss%istatus(1) ) ! 0:elastic 1:plastic
107  if( getyieldfunction( gauss%pMaterial%mtype )==3 ) then ! user defined
108  n = uelastoplasticnumstatus( gauss%pMaterial%variables )
109  if( n>0 ) allocate( gauss%fstatus(n) )
110  elseif( iskinematicharden( gauss%pMaterial%mtype ) ) then
111  ! (1) trial eq. plastic strain, (2:7) trial back stress, (8:13) converged back stress
112  allocate( gauss%fstatus(7+6) )
113  else
114  allocate( gauss%fstatus(2) ) ! (1) trial eq. plastic strain, (2) unused
115  endif
116  gauss%istatus = 0
117  gauss%fstatus = 0.d0
118  else if( isviscoelastic(gauss%pMaterial%mtype) ) then
119  n = fetch_tablerow( mc_viscoelastic, gauss%pMaterial%dict )
120  if( n>0 ) then
121  ! per Prony term: (1:6) converged and (7:12) trial visco stress; last 6: converged deviatoric strain
122  allocate( gauss%fstatus(12*n+6) )
123  gauss%fstatus = 0.d0
124  else
125  stop "Viscoelastic properties not defined"
126  endif
127  else if( gauss%pMaterial%mtype==norton ) then
128  allocate( gauss%fstatus(2) ) ! (1) updated eq. stress, (2) converged eq. creep strain
129  gauss%fstatus = 0.d0
130  gauss%plstrain = 0.d0
131  endif
132  end subroutine fstr_init_gauss
133 
135  subroutine fstr_finalize_gauss( gauss )
136  type( tgaussstatus ), intent(inout) :: gauss
137  if( associated( gauss%istatus ) ) deallocate( gauss%istatus )
138  if( associated( gauss%fstatus ) ) deallocate( gauss%fstatus )
139  end subroutine
140 
143  integer(kind=kint) function fstr_shell_num_thickness_points( etype )
144  integer(kind=kint), intent(in) :: etype
145 
148 
150  subroutine fstr_init_shell_layer_gausses( element, ng, nlayer, nthick )
151  type( telement ), intent(inout) :: element
152  integer(kind=kint), intent(in) :: ng, nlayer, nthick
153  integer(kind=kint) :: i, nstatus
154 
155  if( ng <= 0 .or. nlayer <= 0 .or. nthick <= 0 ) return
156  if( .not. associated( element%gausses ) ) return
157  if( associated( element%shell_layer_gausses ) ) return
158 
159  nstatus = ng*nlayer*nthick
160  allocate( element%shell_layer_gausses( nstatus ) )
161  element%shell_nlayer = nlayer
162  element%shell_nthick = nthick
163 
164  do i = 1, nstatus
165  element%shell_layer_gausses(i)%pMaterial => element%gausses(1)%pMaterial
166  call fstr_init_gauss( element%shell_layer_gausses(i) )
167  enddo
168  end subroutine fstr_init_shell_layer_gausses
169 
171  integer(kind=kint) function fstr_shell_layer_gauss_index( element, ig, ilayer, ithick )
172  type( telement ), intent(in) :: element
173  integer(kind=kint), intent(in) :: ig, ilayer, ithick
174  integer(kind=kint) :: ngauss
175 
177  if( .not. associated( element%gausses ) ) return
178  if( .not. associated( element%shell_layer_gausses ) ) return
179  if( element%shell_nlayer <= 0 .or. element%shell_nthick <= 0 ) return
180  if( ilayer < 1 .or. ilayer > element%shell_nlayer ) return
181  if( ithick < 1 .or. ithick > element%shell_nthick ) return
182 
183  ngauss = size( element%gausses )
184  if( ig < 1 .or. ig > ngauss ) return
185  if( size( element%shell_layer_gausses ) < ngauss*element%shell_nlayer*element%shell_nthick ) return
186 
187  fstr_shell_layer_gauss_index = ((ig-1)*element%shell_nlayer + ilayer-1) &
188  *element%shell_nthick + ithick
189  end function fstr_shell_layer_gauss_index
190 
193  real(kind=kreal) function fstr_element_average_plstrain( element )
194  type( telement ), intent(in) :: element
195  integer(kind=kint) :: i, ig, ilayer, ithick, ishell
196  real(kind=kreal) :: weight, total_weight
197 
199  if( associated(element%shell_layer_gausses) ) then
200  if( .not. associated(element%gausses) ) return
201  if( element%shell_nlayer <= 0 .or. element%shell_nthick <= 0 ) return
202  if( size(element%gausses) <= 0 ) return
203  if( .not. associated(element%gausses(1)%pMaterial) ) return
204  if( .not. associated(element%gausses(1)%pMaterial%shell_var) ) return
205  if( element%shell_nlayer > size(element%gausses(1)%pMaterial%shell_var) ) return
206  total_weight = 0.0d0
207  do ig = 1, size(element%gausses)
208  do ilayer = 1, element%shell_nlayer
209  weight = element%gausses(1)%pMaterial%shell_var(ilayer)%weight
210  do ithick = 1, element%shell_nthick
211  ishell = fstr_shell_layer_gauss_index(element, ig, ilayer, ithick)
212  if( ishell <= 0 ) cycle
214  + element%shell_layer_gausses(ishell)%plstrain * weight
215  total_weight = total_weight + weight
216  enddo
217  enddo
218  enddo
219  if( total_weight > 0.0d0 ) fstr_element_average_plstrain = fstr_element_average_plstrain/total_weight
220  else if( associated(element%gausses) ) then
221  if( size(element%gausses) <= 0 ) return
222  do i = 1, size(element%gausses)
224  enddo
226  endif
227  end function fstr_element_average_plstrain
228 
230  subroutine fstr_shell_thickness_quadrature( etype, ithick, zeta, weight, ierr )
231  integer(kind=kint), intent(in) :: etype, ithick
232  real(kind=kreal), intent(out) :: zeta, weight
233  integer(kind=kint), intent(out) :: ierr
234 
235  ierr = 0
236  zeta = 0.0d0
237  weight = 0.0d0
238 
239  if( ithick < 1 .or. ithick > numofshellthicknessquadpoints(etype) ) then
240  ierr = 1
241  return
242  endif
243 
244  call getshellthicknessquadpoint(etype, ithick, zeta)
245  weight = getshellthicknessweight(etype, ithick)
246  end subroutine fstr_shell_thickness_quadrature
247 
249  subroutine fstr_shell_layer_quadrature( element, ilayer, ithick, zeta_layer, weight, ierr )
250  type( telement ), intent(in) :: element
251  integer(kind=kint), intent(in) :: ilayer, ithick
252  real(kind=kreal), intent(out) :: zeta_layer, weight
253  integer(kind=kint), intent(out) :: ierr
254 
255  ierr = 0
256  zeta_layer = 0.0d0
257  weight = 0.0d0
258 
259  if( .not. associated( element%gausses ) ) then
260  ierr = 1
261  return
262  endif
263 
264  call fstr_shell_layer_quadrature_gauss( element%etype, element%gausses(1), ilayer, ithick, &
265  zeta_layer, weight, ierr )
266  end subroutine fstr_shell_layer_quadrature
267 
269  subroutine fstr_shell_layer_quadrature_gauss( etype, gauss, ilayer, ithick, zeta_layer, weight, ierr )
270  integer(kind=kint), intent(in) :: etype, ilayer, ithick
271  type( tgaussstatus ), intent(in) :: gauss
272  real(kind=kreal), intent(out) :: zeta_layer, weight
273  integer(kind=kint), intent(out) :: ierr
274  real(kind=kreal) :: zeta
275 
276  ierr = 0
277  zeta_layer = 0.0d0
278  weight = 0.0d0
279 
280  call fstr_shell_thickness_quadrature( etype, ithick, zeta, weight, ierr )
281  if( ierr /= 0 ) return
282  call fstr_shell_layer_zeta( gauss, ilayer, zeta, zeta_layer, ierr )
283  end subroutine fstr_shell_layer_quadrature_gauss
284 
286  subroutine fstr_shell_layer_zeta( gauss, ilayer, zeta, zeta_layer, ierr )
287  type( tgaussstatus ), intent(in) :: gauss
288  integer(kind=kint), intent(in) :: ilayer
289  real(kind=kreal), intent(in) :: zeta
290  real(kind=kreal), intent(out) :: zeta_layer
291  integer(kind=kint), intent(out) :: ierr
292  integer(kind=kint) :: i
293  real(kind=kreal) :: sumlyr
294 
295  ierr = 0
296  zeta_layer = 0.0d0
297 
298  if( .not. associated( gauss%pMaterial ) ) then
299  ierr = 1
300  return
301  endif
302  if( ilayer < 1 .or. ilayer > gauss%pMaterial%totallyr ) then
303  ierr = 1
304  return
305  endif
306 
307  sumlyr = 0.0d0
308  do i = 1, ilayer
309  sumlyr = sumlyr + 2.0d0*gauss%pMaterial%shell_var(i)%weight
310  enddo
311  zeta_layer = -1.0d0 + sumlyr - gauss%pMaterial%shell_var(ilayer)%weight*(1.0d0-zeta)
312  end subroutine fstr_shell_layer_zeta
313 
315  subroutine fstr_finalize_shell_layer_gausses( element )
316  type( telement ), intent(inout) :: element
317  integer(kind=kint) :: i
318 
319  if( associated( element%shell_layer_gausses ) ) then
320  do i = 1, size( element%shell_layer_gausses )
321  call fstr_finalize_gauss( element%shell_layer_gausses(i) )
322  enddo
323  deallocate( element%shell_layer_gausses )
324  endif
325  element%shell_nlayer = 0
326  element%shell_nthick = 0
327  end subroutine fstr_finalize_shell_layer_gausses
328 
330  subroutine fstr_copy_gauss( gauss1, gauss2 )
331  type( tgaussstatus ), intent(in) :: gauss1
332  type( tgaussstatus ), intent(inout) :: gauss2
333 
334  gauss2%strain = gauss1%strain
335  gauss2%stress = gauss1%stress
336  gauss2%strain_bak = gauss1%strain_bak
337  gauss2%stress_bak = gauss1%stress_bak
338  gauss2%nqm = gauss1%nqm
339  gauss2%strain_out = gauss1%strain_out
340  gauss2%stress_out = gauss1%stress_out
341  gauss2%plstrain = gauss1%plstrain
342  gauss2%strain_energy = gauss1%strain_energy
343  gauss2%strain_energy_bak = gauss1%strain_energy_bak
344  gauss2%plpotential = gauss1%plpotential
345 
346  if( associated(gauss1%istatus) .and. associated(gauss2%istatus) ) then
347  gauss2%istatus = gauss1%istatus
348  end if
349  if( associated(gauss1%fstatus) .and. associated(gauss2%fstatus) ) then
350  gauss2%fstatus = gauss1%fstatus
351  end if
352  end subroutine fstr_copy_gauss
353 
355  subroutine fstr_copy_shell_layer_gausses( element1, element2 )
356  type( telement ), intent(in) :: element1
357  type( telement ), intent(inout) :: element2
358  integer(kind=kint) :: i
359 
360  if( .not. associated( element1%shell_layer_gausses ) ) return
361  if( .not. associated( element2%shell_layer_gausses ) ) return
362  if( size( element1%shell_layer_gausses ) /= size( element2%shell_layer_gausses ) ) return
363 
364  do i = 1, size( element1%shell_layer_gausses )
365  call fstr_copy_gauss( element1%shell_layer_gausses(i), element2%shell_layer_gausses(i) )
366  enddo
367  end subroutine fstr_copy_shell_layer_gausses
368 
369 
370 end module
This module encapsulate the basic functions of all elements provide by this software.
Definition: element.f90:43
subroutine getshellthicknessquadpoint(etype, np, zeta)
Fetch the through-thickness quadrature coordinate of a shell element.
Definition: element.f90:504
integer function numofshellthicknessquadpoints(etype)
Obtains the number of through-thickness quadrature points of a shell element.
Definition: element.f90:490
integer, parameter fe_mitc4_shell
Definition: element.f90:95
integer, parameter fe_mitc9_shell
Definition: element.f90:97
integer, parameter fe_mitc3_shell
Definition: element.f90:94
real(kind=kreal) function getshellthicknessweight(etype, np)
Fetch the through-thickness quadrature weight of a shell element.
Definition: element.f90:522
I/O and Utility.
Definition: hecmw_util_f.F90:7
integer(kind=4), parameter kreal
This module summarizes all information of material properties.
Definition: material.f90:6
integer function getyieldfunction(mtype)
Get type of yield function.
Definition: material.f90:294
character(len=dict_key_length) mc_viscoelastic
Definition: material.f90:147
integer function getelastictype(mtype)
Get elastic type.
Definition: material.f90:282
integer function gethardentype(mtype)
Get type of hardening.
Definition: material.f90:306
integer(kind=kint), parameter m_plconst2
Definition: material.f90:101
integer(kind=kint), parameter norton
Definition: material.f90:81
integer(kind=kint), parameter infinitesimal
Definition: material.f90:13
logical function iskinematicharden(mtype)
If it is a kinematic hardening material?
Definition: material.f90:318
integer(kind=kint), parameter usermaterial
Definition: material.f90:66
logical function iselastic(mtype)
If it is an elastic material?
Definition: material.f90:327
logical function isviscoelastic(mtype)
If it is an viscoelastic material?
Definition: material.f90:354
logical function iselastoplastic(mtype)
If it is an elastoplastic material?
Definition: material.f90:336
This modules defines a structure to record history dependent parameter in static analysis.
Definition: mechgauss.f90:6
integer(kind=kint) function fstr_shell_num_thickness_points(etype)
Compatibility accessor for shell history allocation. The quadrature rule itself is defined in element...
Definition: mechgauss.f90:144
subroutine fstr_shell_layer_zeta(gauss, ilayer, zeta, zeta_layer, ierr)
Map layer-local zeta to the whole shell thickness coordinate.
Definition: mechgauss.f90:287
subroutine fstr_init_gauss(gauss)
Initializer.
Definition: mechgauss.f90:89
subroutine fstr_shell_layer_quadrature_gauss(etype, gauss, ilayer, ithick, zeta_layer, weight, ierr)
Layer-local shell thickness coordinate and quadrature weight from material status.
Definition: mechgauss.f90:270
subroutine fstr_init_shell_layer_gausses(element, ng, nlayer, nthick)
Allocate shell history for every surface Gauss point, layer, and thickness point.
Definition: mechgauss.f90:151
integer(kind=kint) function fstr_shell_layer_gauss_index(element, ig, ilayer, ithick)
Convert surface Gauss/layer/thickness indices to shell_layer_gausses index.
Definition: mechgauss.f90:172
subroutine fstr_finalize_gauss(gauss)
Finializer.
Definition: mechgauss.f90:136
subroutine fstr_shell_thickness_quadrature(etype, ithick, zeta, weight, ierr)
Through-thickness quadrature point and weight used by shell elements.
Definition: mechgauss.f90:231
subroutine fstr_shell_layer_quadrature(element, ilayer, ithick, zeta_layer, weight, ierr)
Layer-local shell thickness coordinate and quadrature weight.
Definition: mechgauss.f90:250
subroutine fstr_finalize_shell_layer_gausses(element)
Release shell layer/thickness history.
Definition: mechgauss.f90:316
logical function fstr_uses_plane_stress_j2_shell(etype, nn, material)
Return whether the element and material are supported by the plane-stress J2 shell path.
Definition: mechgauss.f90:72
integer(kind=kint) function fstr_shell_output_point_count(element)
Number of shell thickness-point tensors available for result output.
Definition: mechgauss.f90:52
subroutine fstr_copy_gauss(gauss1, gauss2)
Copy.
Definition: mechgauss.f90:331
subroutine fstr_copy_shell_layer_gausses(element1, element2)
Copy shell layer/thickness history.
Definition: mechgauss.f90:356
real(kind=kreal) function fstr_element_average_plstrain(element)
Average equivalent plastic strain over the active quadrature history. Average shell history points eq...
Definition: mechgauss.f90:194
This subroutine read in used-defined material properties tangent.
Definition: uyield.f90:7
integer(kind=kint) function, public uelastoplasticnumstatus(matl)
This function returns the number of real state variables.
Definition: uyield.f90:25
Structure to manage all material related data.
Definition: material.f90:169
All data should be recorded in every elements.
Definition: mechgauss.f90:34
All data should be recorded in every quadrature points.
Definition: mechgauss.f90:15