11 use,
intrinsic :: ieee_arithmetic, only: ieee_is_finite
25 real(kind=
kreal),
parameter :: id(6,6) = reshape( &
26 & (/ 2.d0/3.d0, -1.d0/3.d0, -1.d0/3.d0, 0.d0, 0.d0, 0.d0, &
27 & -1.d0/3.d0, 2.d0/3.d0, -1.d0/3.d0, 0.d0, 0.d0, 0.d0, &
28 & -1.d0/3.d0, -1.d0/3.d0, 2.d0/3.d0, 0.d0, 0.d0, 0.d0, &
29 & 0.d0, 0.d0, 0.d0, 0.5d0, 0.d0, 0.d0, &
30 & 0.d0, 0.d0, 0.d0, 0.d0, 0.5d0, 0.d0, &
31 & 0.d0, 0.d0, 0.d0, 0.d0, 0.d0, 0.5d0/), &
33 real(kind=
kreal),
parameter :: i2(6) = (/ 1.d0, 1.d0, 1.d0, 0.d0, 0.d0, 0.d0 /)
35 integer,
parameter :: vm_elastic = 0
36 integer,
parameter :: vm_plastic = 1
38 integer,
parameter :: mc_elastic = 0
39 integer,
parameter :: mc_plastic_surf = 1
40 integer,
parameter :: mc_plastic_right = 2
41 integer,
parameter :: mc_plastic_left = 3
42 integer,
parameter :: mc_plastic_apex = 4
44 integer,
parameter :: dp_elastic = 0
45 integer,
parameter :: dp_plastic_surf = 1
46 integer,
parameter :: dp_plastic_apex = 2
48 real(kind=
kreal),
parameter :: shell_shear_correction = 5.0d0/6.0d0
49 integer,
parameter :: plane_stress_components(3) = (/ 1, 2, 4 /)
53 logical function isplanestressj2perfectplasticity( matl )
56 isplanestressj2perfectplasticity = .false.
61 if( abs(matl%variables(
m_plconst2)) > tiny(1.0d0) )
return
62 isplanestressj2perfectplasticity = .true.
63 end function isplanestressj2perfectplasticity
67 integer(kind=kint),
intent(out) :: ierr
68 type(ttable),
pointer :: table
73 if( .not. isplanestressj2perfectplasticity(matl) )
return
74 if(
associated(matl%shell_var) )
then
75 if( any(matl%shell_var%ortho /= 0) )
return
78 if( .not. missing )
then
79 if( table%ndepends /= 0 )
then
88 if( .not. all(ieee_is_finite(constants)) )
return
89 if( constants(1) <= 0.0d0 .or. constants(2) <= -1.0d0 .or. constants(2) >= 0.5d0 )
return
90 if( constants(3) <= 0.0d0 )
return
95 integer(kind=kint),
intent(in) :: ierr
96 character(len=128) :: message
100 message =
'Plane-stress J2 requires isotropic elasticity and perfect plasticity'
102 message =
'Invalid plane-stress J2 history state'
104 message =
'Invalid or missing plane-stress J2 properties: require E > 0, -1 < nu < 0.5, yield stress > 0'
106 message =
'Singular thickness tangent in plane-stress J2 condensation'
108 message =
'Plane-stress J2 local iteration did not converge'
110 message =
'Non-finite value in plane-stress J2 material update'
112 message =
'Temperature-dependent elasticity is not supported by plane-stress J2 shells'
114 message =
'Unknown plane-stress J2 error'
118 subroutine condenseplanestressj2tangent( tangent3d, shear_stiffness, tangent, ierr )
119 real(kind=
kreal),
intent(in) :: tangent3d(6,6)
120 real(kind=
kreal),
intent(in) :: shear_stiffness
121 real(kind=
kreal),
intent(out) :: tangent(5,5)
122 integer(kind=kint),
intent(out) :: ierr
124 integer :: i, j, ii, jj
128 if( .not. all(ieee_is_finite(tangent3d)) )
then
132 if( abs(tangent3d(3,3)) <= 100.0d0*epsilon(1.0d0)*maxval(abs(tangent3d)) )
then
138 ii = plane_stress_components(i)
140 jj = plane_stress_components(j)
141 tangent(i,j) = tangent3d(ii,jj)-tangent3d(ii,3)*tangent3d(3,jj)/tangent3d(3,3)
144 tangent(4,4) = shear_stiffness
145 tangent(5,5) = shear_stiffness
146 end subroutine condenseplanestressj2tangent
153 fstatus, stress, strain_increment_out, tangent, istat, fstatus_out, plpotential, energy_increment, ierr )
155 real(kind=
kreal),
intent(in) :: strain_increment(6), stress_bak(6)
156 real(kind=
kreal),
intent(in) :: plstrain, fstatus(:)
157 real(kind=
kreal),
intent(out) :: stress(6), strain_increment_out(6), tangent(5,5)
158 integer,
intent(out) :: istat
159 real(kind=
kreal),
intent(out) :: fstatus_out(:), plpotential, energy_increment
160 integer(kind=kint),
intent(out) :: ierr
162 integer,
parameter :: maxiter = 25
165 real(kind=
kreal) :: strain_increment_work(6)
166 real(kind=
kreal) :: stress_work(6), stress_bak_work(6)
167 real(kind=
kreal) :: shear_stiffness, residual, tolerance
171 strain_increment_out = strain_increment
176 energy_increment = 0.0d0
179 if( ierr /= 0 )
return
180 if(
size(fstatus) /=
size(fstatus_out) .or.
size(fstatus) < 1 )
then
184 if( .not. all(ieee_is_finite(strain_increment)) .or. .not. all(ieee_is_finite(stress_bak)) .or. &
185 .not. all(ieee_is_finite(fstatus)) .or. .not. ieee_is_finite(plstrain) )
then
189 fstatus_out = fstatus
192 strain_increment_work = strain_increment
193 strain_increment_work(5:6) = 0.0d0
194 stress_bak_work = stress_bak
195 stress_bak_work(5:6) = 0.0d0
196 strain_increment_work(3) = 0.0d0
198 shear_stiffness = shell_shear_correction*
elastic(5,5)
202 fstatus_out = fstatus
203 fstatus_out(1) = plstrain
204 stress_work = stress_bak_work+matmul(
elastic, strain_increment_work)
205 call backwardeuler( matl, stress_work, plstrain, istat, fstatus_out, plpotential, 0.0d0 )
208 if( .not. all(ieee_is_finite(stress_work)) .or. .not. all(ieee_is_finite(tangent3d)) .or. &
209 .not. all(ieee_is_finite(fstatus_out)) )
then
214 residual = stress_work(3)
215 tolerance = 1.0d-10*max(matl%variables(
m_plconst1), maxval(abs(stress_work)))
216 if( abs(residual) <= tolerance )
exit
217 if( abs(tangent3d(3,3)) <= 100.0d0*epsilon(1.0d0)*maxval(abs(tangent3d)) )
then
221 strain_increment_work(3) = strain_increment_work(3)-residual/tangent3d(3,3)
223 if( iter > maxiter )
then
228 call condenseplanestressj2tangent(tangent3d, shear_stiffness, tangent, ierr)
229 if( ierr /= 0 )
return
233 stress(5:6) = stress_bak(5:6)+shear_stiffness*strain_increment(5:6)
234 strain_increment_out = strain_increment_work
235 strain_increment_out(5:6) = strain_increment(5:6)
237 energy_increment = dot_product(stress_bak_work, strain_increment_work) &
238 +0.5d0*dot_product(matmul(
elastic, strain_increment_work), strain_increment_work)+plpotential &
239 +dot_product(stress_bak(5:6)+0.5d0*shear_stiffness*strain_increment(5:6), strain_increment(5:6))
240 if( .not. ieee_is_finite(energy_increment) ) ierr =
j2_nonfinite
246 real(kind=
kreal),
intent(in) :: stress(6), fstatus(:), plstrain
247 integer,
intent(in) :: istat
248 real(kind=
kreal),
intent(out) :: tangent(5,5)
249 integer(kind=kint),
intent(out) :: ierr
251 real(kind=
kreal) :: tangent3d(6,6), stress_work(6),
elastic(6,6)
256 if( ierr /= 0 )
return
257 if(
size(fstatus) < 1 )
then
261 if( .not. all(ieee_is_finite(stress)) .or. .not. all(ieee_is_finite(fstatus)) .or. &
262 .not. ieee_is_finite(plstrain) )
then
267 stress_work(5:6) = 0.0d0
270 call condenseplanestressj2tangent(tangent3d, shell_shear_correction*
elastic(5,5), tangent, ierr)
276 integer,
intent(in) :: secttype
277 real(kind=
kreal),
intent(in) :: stress(6)
278 real(kind=
kreal),
intent(in) :: extval(:)
279 real(kind=
kreal),
intent(in) :: plstrain
280 integer,
intent(in) :: istat
281 real(kind=
kreal),
intent(out) :: d(:,:)
282 real(kind=
kreal),
intent(in) :: temperature
283 integer(kind=kint),
intent(in),
optional :: hdflag
285 integer :: ytype,hdflag_in
288 if(
present(hdflag) ) hdflag_in = hdflag
293 call calelastoplasticmatrix_vm( matl, secttype, stress, istat, extval, plstrain, d, temperature, hdflag_in )
295 call calelastoplasticmatrix_mc( matl, secttype, stress, istat, extval, plstrain, d, temperature, hdflag_in )
299 call uelastoplasticmatrix( matl%variables, stress, istat, extval, plstrain, d, temperature, hdflag_in )
304 subroutine calelastoplasticmatrix_vm( matl, sectType, stress, istat, extval, plstrain, D, temperature, hdflag )
306 integer,
intent(in) :: secttype
307 real(kind=
kreal),
intent(in) :: stress(6)
308 real(kind=
kreal),
intent(in) :: extval(:)
309 real(kind=
kreal),
intent(in) :: plstrain
310 integer,
intent(in) :: istat
311 real(kind=
kreal),
intent(out) :: d(:,:)
312 real(kind=
kreal),
intent(in) :: temperature
313 integer(kind=kint),
intent(in) :: hdflag
317 real(kind=
kreal) :: dum, a(6), g, dlambda
318 real(kind=
kreal) :: c1,c2,c3, back(6)
319 real(kind=
kreal) :: j1,j2, harden, khard, devia(6)
321 if( secttype /=
d3 ) stop
"Elastoplastic calculation support only Solid element currently"
324 if( istat == vm_elastic )
return
325 if( hdflag == 2 )
return
327 harden = calhardencoeff( matl, extval(1), temperature )
332 back(1:6) = extval(2:7)
333 khard = calkinematicharden( matl, extval(1) )
336 j1 = (stress(1)+stress(2)+stress(3))
337 devia(1:3) = stress(1:3)-j1/3.d0
338 devia(4:6) = stress(4:6)
339 if( kinematic ) devia = devia-back
340 j2 = 0.5d0* dot_product( devia(1:3), devia(1:3) ) + &
341 dot_product( devia(4:6), devia(4:6) )
343 a(1:6) = devia(1:6)/sqrt(2.d0*j2)
345 dlambda = extval(1)-plstrain
346 c3 = sqrt(3.d0*j2)+3.d0*g*dlambda
347 c1 = 6.d0*dlambda*g*g/c3
348 dum = 3.d0*g+khard+harden
349 c2 = 6.d0*g*g*(dlambda/c3-1.d0/dum)
353 d(i,j) = d(i,j) - c1*id(i,j) + c2*a(i)*a(j)
356 end subroutine calelastoplasticmatrix_vm
359 subroutine calelastoplasticmatrix_mc( matl, sectType, stress, istat, extval, plstrain, D, temperature, hdflag )
362 integer,
intent(in) :: secttype
363 real(kind=
kreal),
intent(in) :: stress(6)
364 real(kind=
kreal),
intent(in) :: extval(:)
365 real(kind=
kreal),
intent(in) :: plstrain
366 integer,
intent(in) :: istat
367 real(kind=
kreal),
intent(out) :: d(:,:)
368 real(kind=
kreal),
intent(in) :: temperature
369 integer(kind=kint),
intent(in) :: hdflag
371 real(kind=
kreal) :: g, k, harden, r2g, r2gd3, r4gd3, r2k, youngs, poisson
372 real(kind=
kreal) :: phi, psi, cosphi, sinphi, cotphi, sinpsi, sphsps, r2cosphi, r4cos2phi
373 real(kind=
kreal) :: prnstre(3), prnprj(3,3), prnstra(3)
374 integer(kind=kint) :: m1, m2, m3
375 real(kind=
kreal) :: c1,c2, ca1, ca2, ca3, cam, cap, cd1, cd2, cd3, cdiag, coffd
376 real(kind=
kreal) :: ck1, ck2, ck3
377 real(kind=
kreal) :: dum, da, db, dc, dd, detinv
378 real(kind=
kreal) :: dpsdpe(3,3)
380 if( secttype /=
d3 ) stop
"Elastoplastic calculation support only Solid element currently"
383 if( istat == mc_elastic )
return
384 if( hdflag == 2 )
return
386 harden = calhardencoeff( matl, extval(1), temperature )
388 k = d(1,1)-(4.d0/3.d0)*g
393 youngs = 9.d0*k*g/(3.d0*k+g)
394 poisson = (3.d0*k-r2g)/(6.d0*k+r2g)
401 sphsps = sinphi*sinpsi
402 r2cosphi = 2.d0*cosphi
403 r4cos2phi = r2cosphi*r2cosphi
405 call eigen3( stress, prnstre, prnprj )
406 m1 = maxloc( prnstre, 1 )
407 m3 = minloc( prnstre, 1 )
409 m1 = 1; m2 = 2; m3 = 3
414 c1 = 4.d0*(g*(1.d0+sphsps/3.d0)+k*sphsps)
415 if( istat==mc_plastic_surf )
then
416 dd= c1 + r4cos2phi*harden
417 cd1 = (r2g*(1.d0+sinpsi/3.d0) + r2k*sinpsi)/dd
418 cd2 = (r4gd3-r2k)*sinpsi/dd
419 cd3 = (r2g*(1.d0-sinpsi/3.d0) - r2k*sinpsi)/dd
420 cap = 1.d0+sinphi/3.d0
421 cam = 1.d0-sinphi/3.d0
422 ck1 = 1.d0-2.d0*cd1*sinphi
423 ck2 = 1.d0+2.d0*cd2*sinphi
424 ck3 = 1.d0+2.d0*cd3*sinphi
425 dpsdpe(m1,m1) = r2g*( 2.d0/3.d0-cd1*cap)+k*ck1
426 dpsdpe(m1,m2) = (k-r2gd3)*ck1
427 dpsdpe(m1,m3) = r2g*(-1.d0/3.d0+cd1*cam)+k*ck1
428 dpsdpe(m2,m1) = r2g*(-1.d0/3.d0+cd2*cap)+k*ck2
429 dpsdpe(m2,m2) = r4gd3*( 1.d0-cd2*sinphi)+k*ck2
430 dpsdpe(m2,m3) = r2g*(-1.d0/3.d0-cd2*cam)+k*ck2
431 dpsdpe(m3,m1) = r2g*(-1.d0/3.d0+cd3*cap)+k*ck3
432 dpsdpe(m3,m2) = (k-r2gd3)*ck3
433 dpsdpe(m3,m3) = r2g*( 2.d0/3.d0-cd3*cam)+k*ck3
434 else if( istat==mc_plastic_apex )
then
435 cotphi = cosphi/sinphi
436 dpsdpe(:,:) = k*(1.d0-(k/(k+harden*cotphi*cosphi/sinpsi)))
438 if( istat==mc_plastic_right )
then
439 c2 = r2g*(1.d0+sinphi+sinpsi-sphsps/3.d0) + 4.d0*k*sphsps
440 else if( istat==mc_plastic_left )
then
441 c2 = r2g*(1.d0-sinphi-sinpsi-sphsps/3.d0) + 4.d0*k*sphsps
443 dum = r4cos2phi*harden
448 detinv = 1.d0/(da*dd-db*dc)
449 ca1 = r2g*(1.d0+sinpsi/3.d0)+r2k*sinpsi
450 ca2 = (r4gd3-r2k)*sinpsi
451 ca3 = r2g*(1.d0-sinpsi/3.d0)-r2k*sinpsi
454 if( istat==mc_plastic_right )
then
455 dpsdpe(m1,m1) = cdiag+ca1*(db-dd-da+dc)*(r2g+(r2k+r2gd3)*sinphi)*detinv
456 dpsdpe(m1,m2) = coffd+ca1*(r2g*(da-db)+((db-dd-da+dc)*(r2k+r2gd3)+(dd-dc)*r2g)*sinphi)*detinv
457 dpsdpe(m1,m3) = coffd+ca1*(r2g*(dd-dc)+((db-dd-da+dc)*(r2k+r2gd3)+(da-db)*r2g)*sinphi)*detinv
458 dpsdpe(m2,m1) = coffd+(ca2*(dd-db)+ca3*(da-dc))*(r2g+(r2k+r2gd3)*sinphi)*detinv
459 dpsdpe(m2,m2) = cdiag+(ca2*((r2k*(dd-db)-(db*r2gd3+dd*r4gd3))*sinphi+db*r2g) &
460 & +ca3*((r2k*(da-dc)+(da*r2gd3+dc*r4gd3))*sinphi-da*r2g))*detinv
461 dpsdpe(m2,m3) = coffd+(ca2*((r2k*(dd-db)+(db*r4gd3+dd*r2gd3))*sinphi-dd*r2g) &
462 & +ca3*((r2k*(da-dc)-(da*r4gd3+dc*r2gd3))*sinphi+dc*r2g))*detinv
463 dpsdpe(m3,m1) = coffd+(ca2*(da-dc)+ca3*(dd-db))*(r2g+(r2k+r2gd3)*sinphi)*detinv
464 dpsdpe(m3,m2) = coffd+(ca2*((r2k*(da-dc)+(da*r2gd3+dc*r4gd3))*sinphi-da*r2g) &
465 & +ca3*((r2k*(dd-db)-(db*r2gd3+dd*r4gd3))*sinphi+db*r2g))*detinv
466 dpsdpe(m3,m3) = cdiag+(ca2*((r2k*(da-dc)-(da*r4gd3+dc*r2gd3))*sinphi+dc*r2g) &
467 & +ca3*((r2k*(dd-db)+(db*r4gd3+dd*r2gd3))*sinphi-dd*r2g))*detinv
468 else if( istat==mc_plastic_left )
then
469 dpsdpe(m1,m1) = cdiag+(ca1*((r2k*(db-dd)-(db*r4gd3+dd*r2gd3))*sinphi-dd*r2g) &
470 & +ca2*((r2k*(da-dc)-(da*r4gd3+dc*r2gd3))*sinphi-dc*r2g))*detinv
471 dpsdpe(m1,m2) = coffd+(ca1*((r2k*(db-dd)+(db*r2gd3+dd*r4gd3))*sinphi+db*r2g) &
472 & +ca2*((r2k*(da-dc)+(da*r2gd3+dc*r4gd3))*sinphi+da*r2g))*detinv
473 dpsdpe(m1,m3) = coffd+(ca1*(db-dd)+ca2*(da-dc))*(-r2g+(r2k+r2gd3)*sinphi)*detinv
474 dpsdpe(m2,m1) = coffd+(ca1*((r2k*(dc-da)+(da*r4gd3+dc*r2gd3))*sinphi+dc*r2g) &
475 & +ca2*((r2k*(dd-db)+(db*r4gd3+dd*r2gd3))*sinphi+dd*r2g))*detinv
476 dpsdpe(m2,m2) = cdiag+(ca1*((r2k*(dc-da)-(da*r2gd3+dc*r4gd3))*sinphi-da*r2g) &
477 & +ca2*((r2k*(dd-db)-(db*r2gd3+dd*r4gd3))*sinphi-db*r2g))*detinv
478 dpsdpe(m2,m3) = coffd+(ca1*(dc-da)+ca2*(dd-db))*(-r2g+(r2k+r2gd3)*sinphi)*detinv
479 dpsdpe(m3,m1) = coffd+ca3*((r2k*(-db+dd+da-dc)+(db-da)*r4gd3+(dd-dc)*r2gd3)*sinphi+(dd-dc)*r2g)*detinv
480 dpsdpe(m3,m2) = coffd+ca3*((r2k*(-db+dd+da-dc)+(da-db)*r2gd3+(dc-dd)*r4gd3)*sinphi+(da-db)*r2g)*detinv
481 dpsdpe(m3,m3) = cdiag+ca3*(-db+dd+da-dc)*(-r2g+(r2k+r2gd3)*sinphi)*detinv
485 prnstra(1) = (prnstre(1)-poisson*(prnstre(2)+prnstre(3)))/youngs
486 prnstra(2) = (prnstre(2)-poisson*(prnstre(1)+prnstre(3)))/youngs
487 prnstra(3) = (prnstre(3)-poisson*(prnstre(1)+prnstre(2)))/youngs
489 end subroutine calelastoplasticmatrix_mc
494 integer,
intent(in) :: secttype
495 real(kind=
kreal),
intent(in) :: stress(6)
496 real(kind=
kreal),
intent(in) :: extval(:)
497 real(kind=
kreal),
intent(in) :: plstrain
498 integer,
intent(in) :: istat
499 real(kind=
kreal),
intent(out) :: d(:,:)
500 real(kind=
kreal),
intent(in) :: temperature
501 integer(kind=kint),
intent(in) :: hdflag
504 real(kind=
kreal) :: dum, a(6), dlambda, g, k
505 real(kind=
kreal) :: j1,j2, eta, xi, etabar, harden, devia(6)
506 real(kind=
kreal) :: alpha, beta, c1, c2, c3, c4, ca, devia_norm
508 if( secttype /=
d3 ) stop
"Elastoplastic calculation support only Solid element currently"
511 if( istat == dp_elastic )
return
512 if( hdflag == 2 )
return
514 harden = calhardencoeff( matl, extval(1), temperature )
517 k = d(1,1)-(4.d0/3.d0)*g
523 if( istat==dp_plastic_surf )
then
524 j1 = (stress(1)+stress(2)+stress(3))
525 devia(1:3) = stress(1:3)-j1/3.d0
526 devia(4:6) = stress(4:6)
527 j2 = 0.5d0* dot_product( devia(1:3), devia(1:3) ) + &
528 dot_product( devia(4:6), devia(4:6) )
530 devia_norm = sqrt(2.d0*j2)
531 a(1:6) = devia(1:6)/devia_norm
532 dlambda = extval(1)-plstrain
533 ca = 1.d0 / (g + k*eta*etabar + xi*xi*harden)
534 dum = sqrt(2.d0)*devia_norm
535 c1 = 4.d0*g*g*dlambda/dum
536 c2 = 2.d0*g*(2.d0*g*dlambda/dum - g*ca)
537 c3 = sqrt(2.d0)*g*ca*k
538 c4 = k*k*eta*etabar*ca
541 d(i,j) = d(i,j) - c1*id(i,j) + c2*a(i)*a(j) &
542 - c3*(eta*a(i)*i2(j) + etabar*i2(i)*a(j)) &
549 c1 = k*(1.d0 - k/(k + alpha*beta*harden))
552 d(i,j) = c1*i2(i)*i2(j)
559 real(kind=
kreal)
function calhardencoeff( matl, pstrain, temp )
561 real(kind=
kreal),
intent(in) :: pstrain
562 real(kind=
kreal),
intent(in) :: temp
566 real(kind=
kreal) :: s0, s1,s2, ef, ina(2)
568 calhardencoeff = -1.d0
574 ina(1) = temp; ina(2)=pstrain
575 call fetch_tablegrad(
mc_yield, ina, matl%dict, calhardencoeff, ierr )
580 calhardencoeff = s1*s2*( s0+pstrain )**(s2-1)
585 ef = calcurryield( matl, pstrain, temp )
586 calhardencoeff = s1*(ef/s1)**(1.d0-s2) /(s0*s2)
588 calhardencoeff = 0.d0
595 real(kind=
kreal)
function calkinematicharden( matl, pstrain )
597 real(kind=
kreal),
intent(in) :: pstrain
603 calkinematicharden = matl%variables(
m_plconst3)
605 calkinematicharden = 0.d0
610 real(kind=
kreal)
function calcurrkinematic( matl, pstrain )
612 real(kind=
kreal),
intent(in) :: pstrain
618 calcurrkinematic = matl%variables(
m_plconst3)*pstrain
620 calcurrkinematic = 0.d0
625 real(kind=
kreal)
function calcurryield( matl, pstrain, temp )
627 real(kind=
kreal),
intent(in) :: pstrain
628 real(kind=
kreal),
intent(in) :: temp
631 real(kind=
kreal) :: s0, s1,s2, ina(2), outa(1)
640 ina(1) = temp; ina(2)=pstrain
641 call fetch_tabledata(
mc_yield, matl%dict, outa, ierr, ina)
642 if( ierr ) stop
"Fail to get yield stress!"
643 calcurryield = outa(1)
648 calcurryield = s1*( s0+pstrain )**s2
653 if( pstrain<=s0 )
then
656 calcurryield = s1*( pstrain/s0 )**(1.d0/s2)
664 subroutine backwardeuler( matl, stress, plstrain, istat, fstat, plpotential, temp, hdflag )
666 real(kind=
kreal),
intent(inout) :: stress(6)
667 real(kind=
kreal),
intent(in) :: plstrain
668 integer,
intent(inout) :: istat
669 real(kind=
kreal),
intent(inout) :: fstat(:)
670 real(kind=
kreal),
intent(inout) :: plpotential
671 real(kind=
kreal),
intent(in) :: temp
672 integer(kind=kint),
intent(in),
optional :: hdflag
674 integer :: ytype, hdflag_in
677 if(
present(hdflag) ) hdflag_in = hdflag
681 if( ytype /= 3 )
then
687 call backwardeuler_vm( matl, stress, plstrain, istat, fstat, plpotential, temp, hdflag_in )
689 call backwardeuler_mc( matl, stress, plstrain, istat, fstat, temp, hdflag_in )
691 call backwardeuler_dp( matl, stress, plstrain, istat, fstat, temp, hdflag_in )
693 call ubackwardeuler( matl%variables, stress, plstrain, istat, fstat, temp, hdflag_in )
698 subroutine backwardeuler_vm( matl, stress, plstrain, istat, fstat, plpotential, temp, hdflag )
700 real(kind=
kreal),
intent(inout) :: stress(6)
701 real(kind=
kreal),
intent(in) :: plstrain
702 integer,
intent(inout) :: istat
703 real(kind=
kreal),
intent(inout) :: fstat(:)
704 real(kind=
kreal),
intent(inout) :: plpotential
705 real(kind=
kreal),
intent(in) :: temp
706 integer(kind=kint),
intent(in) :: hdflag
708 real(kind=
kreal),
parameter :: tol =1.d-8
709 integer,
parameter :: maxiter = 10
710 real(kind=
kreal) :: dlambda, f
712 real(kind=
kreal) :: youngs, poisson, pstrain, ina(1), ee(2)
713 real(kind=
kreal) :: j1, j2, h, kh, kk, dd, eqvs, yd, g, k, devia(6)
714 logical :: kinematic, ierr
715 real(kind=
kreal) :: betan, back(6)
719 if( kinematic ) back(1:6) = fstat(8:13)
721 j1 = (stress(1)+stress(2)+stress(3))
722 devia(1:3) = stress(1:3)-j1/3.d0
723 devia(4:6) = stress(4:6)
724 if( kinematic ) devia = devia-back
725 j2 = 0.5d0* dot_product( devia(1:3), devia(1:3) ) + &
726 dot_product( devia(4:6), devia(4:6) )
728 eqvs = dsqrt( 3.d0*j2 )
729 yd = calcurryield( matl, plstrain, temp )
732 if( abs(f/yd)<tol )
then
735 elseif( f<0.d0 )
then
739 if( hdflag == 2 )
return
742 kh = 0.d0; kk=0.d0; betan=0.d0
744 betan = calcurrkinematic( matl, plstrain )
750 call fetch_tabledata(
mc_isoelastic, matl%dict, ee, ierr, ina)
752 stop
" fail to fetch young's modulus in elastoplastic calculation"
757 if( youngs==0.d0 ) stop
"YOUNG's ratio==0"
758 g = youngs/ ( 2.d0*(1.d0+poisson) )
759 k = youngs/ ( 3.d0*(1.d0-2.d0*poisson) )
765 h= calhardencoeff( matl, pstrain, temp )
767 kh = calkinematicharden( matl, pstrain )
770 dlambda = dlambda+f/dd
771 if( dlambda<0.d0 )
then
774 istat=vm_elastic;
exit
776 pstrain = plstrain+dlambda
777 yd = calcurryield( matl, pstrain, temp )
779 kk = calcurrkinematic( matl, pstrain )
781 f = eqvs-3.d0*g*dlambda-yd -(kk-betan)
782 if( abs(f/yd)<tol )
exit
788 kk = calcurrkinematic( matl, pstrain )
789 fstat(2:7) = back(:)+(kk-betan)*devia(:)/eqvs
791 devia(:) = (1.d0-3.d0*dlambda*g/eqvs)*devia(:)
792 stress(1:3) = devia(1:3)+j1/3.d0
793 stress(4:6) = devia(4:6)
794 stress(:)= stress(:)+back(:)
798 h= calhardencoeff( matl, pstrain, temp )
799 yd = calcurryield( matl, plstrain, temp )
800 plpotential = -0.5d0*(eqvs-yd)*(eqvs-yd)/(h+3.d0*g)
802 end subroutine backwardeuler_vm
805 subroutine backwardeuler_mc( matl, stress, plstrain, istat, fstat, temp, hdflag )
808 real(kind=
kreal),
intent(inout) :: stress(6)
809 real(kind=
kreal),
intent(in) :: plstrain
810 integer,
intent(inout) :: istat
811 real(kind=
kreal),
intent(inout) :: fstat(:)
812 real(kind=
kreal),
intent(in) :: temp
813 integer(kind=kint),
intent(in) :: hdflag
815 real(kind=
kreal),
parameter :: tol =1.d-8
816 integer,
parameter :: maxiter = 10
817 real(kind=
kreal) :: dlambda, f, mat(3,3)
818 integer :: i, m1, m2, m3
819 real(kind=
kreal) :: youngs, poisson, pstrain, ina(1), ee(2)
820 real(kind=
kreal) :: h, dd, eqvs, cohe, g, k
821 real(kind=
kreal) :: prnstre(3), prnprj(3,3), tstre(3,3)
822 real(kind=
kreal) :: phi, psi, trialprn(3)
824 real(kind=
kreal) :: c1, c2, cs1, cs2, cs3
825 real(kind=
kreal) :: sinphi, cosphi, sinpsi, sphsps, r2cosphi, r4cos2phi, cotphi
826 real(kind=
kreal) :: da, db, dc, depv, detinv, dlambdb, dum, eps, eqvsb, fb
827 real(kind=
kreal) :: pt, p, resid
833 r2cosphi = 2.d0*cosphi
835 call eigen3( stress, prnstre, prnprj )
837 m1 = maxloc( prnstre, 1 )
838 m3 = minloc( prnstre, 1 )
840 m1 = 1; m2 = 2; m3 = 3
845 eqvs = prnstre(m1)-prnstre(m3) + (prnstre(m1)+prnstre(m3))*sinphi
846 cohe = calcurryield( matl, plstrain, temp )
847 f = eqvs - r2cosphi*cohe
849 if( abs(f/cohe)<tol )
then
850 istat = mc_plastic_surf
852 elseif( f<0.d0 )
then
856 if( hdflag == 2 )
return
858 istat = mc_plastic_surf
861 call fetch_tabledata(
mc_isoelastic, matl%dict, ee, ierr, ina)
863 stop
" fail to fetch young's modulus in elastoplastic calculation"
868 if( youngs==0.d0 ) stop
"YOUNG's ratio==0"
869 g = youngs/ ( 2.d0*(1.d0+poisson) )
870 k = youngs/ ( 3.d0*(1.d0-2.d0*poisson) )
876 sphsps = sinphi*sinpsi
877 r4cos2phi = r2cosphi*r2cosphi
878 c1 = 4.d0*(g*(1.d0+sphsps/3.d0)+k*sphsps)
880 h= calhardencoeff( matl, pstrain, temp )
882 dlambda = dlambda+f/dd
883 if( r2cosphi*dlambda<0.d0 )
then
884 if( cosphi==0.d0 ) stop
"Math error in return mapping"
887 istat = mc_elastic;
exit
889 pstrain = plstrain + r2cosphi*dlambda
890 cohe = calcurryield( matl, pstrain, temp )
891 f = eqvs - c1*dlambda - r2cosphi*cohe
892 if( abs(f/cohe)<tol )
exit
897 cs1 =2.d0*g*(1.d0+sinpsi/3.d0) + 2.d0*k*sinpsi
898 cs2 =(4.d0*g/3.d0-2.d0*k)*sinpsi
899 cs3 =2.d0*g*(1.d0-sinpsi/3.d0) - 2.d0*k*sinpsi
900 prnstre(m1) = prnstre(m1)-cs1*dlambda
901 prnstre(m2) = prnstre(m2)+cs2*dlambda
902 prnstre(m3) = prnstre(m3)+cs3*dlambda
903 eps = (abs(prnstre(m1))+abs(prnstre(m2))+abs(prnstre(m3)))*tol
904 if( prnstre(m1) < prnstre(m2)-eps .or. prnstre(m2) < prnstre(m3)-eps )
then
909 if( (1.d0-sinpsi)*prnstre(m1) - 2*prnstre(m2) + (1.d0+sinpsi)*prnstre(m3) > 0)
then
910 istat = mc_plastic_right
911 eqvsb = prnstre(m1)-prnstre(m2) + (prnstre(m1)+prnstre(m2))*sinphi
912 c2 = 2.d0*g*(1.d0+sinphi+sinpsi-sphsps/3.d0) + 4.d0*k*sphsps
914 istat = mc_plastic_left
915 eqvsb = prnstre(m2)-prnstre(m3) + (prnstre(m2)+prnstre(m3))*sinphi
916 c2 = 2.d0*g*(1.d0-sinphi-sinpsi-sphsps/3.d0) + 4.d0*k*sphsps
918 cohe = calcurryield( matl, plstrain, temp )
919 f = eqvs - r2cosphi*cohe
920 fb = eqvsb - r2cosphi*cohe
923 h= calhardencoeff( matl, pstrain, temp )
929 detinv = 1.d0/(da*dd-db*dc)
930 dlambda = dlambda + detinv*( dd*f - db*fb)
931 dlambdb = dlambdb + detinv*(-dc*f + da*fb)
932 pstrain = plstrain + r2cosphi*(dlambda+dlambdb)
933 cohe = calcurryield( matl, pstrain, temp )
934 f = eqvs - c1*dlambda - c2*dlambdb - r2cosphi*cohe
935 fb = eqvsb - c2*dlambda - c1*dlambdb - r2cosphi*cohe
936 if( (abs(f)+abs(fb))/(abs(eqvs)+abs(eqvsb)) < tol )
exit
941 if( istat==mc_plastic_right )
then
942 prnstre(m1) = prnstre(m1)-cs1*(dlambda+dlambdb)
943 prnstre(m2) = prnstre(m2)+cs2*dlambda+cs3*dlambdb
944 prnstre(m3) = prnstre(m3)+cs3*dlambda+cs2*dlambdb
946 prnstre(m1) = prnstre(m1)-cs1*dlambda+cs2*dlambdb
947 prnstre(m2) = prnstre(m2)+cs2*dlambda-cs1*dlambdb
948 prnstre(m3) = prnstre(m3)+cs3*(dlambda+dlambdb)
950 eps = (abs(prnstre(m1))+abs(prnstre(m2))+abs(prnstre(m3)))*tol
951 if( prnstre(m1) < prnstre(m2)-eps .or. prnstre(m2) < prnstre(m3)-eps )
then
954 istat = mc_plastic_apex
955 if( sinphi==0.d0 ) stop
'ERROR: BackwardEuler_MC: phi==0.0'
956 if( sinpsi==0.d0 ) stop
'ERROR: BackwardEuler_MC: psi==0.0'
958 cohe = calcurryield( matl, plstrain, temp )
959 cotphi = cosphi/sinphi
960 pt = (stress(1)+stress(2)+stress(3))/3.d0
961 resid = cotphi*cohe - pt
964 h= calhardencoeff( matl, pstrain, temp )
965 dd= cosphi*cotphi*h/sinpsi + k
966 depv = depv - resid/dd
967 pstrain = plstrain + cosphi*depv/sinpsi
968 cohe = calcurryield( matl, pstrain,temp )
970 resid = cotphi*cohe-p
971 if( abs(resid/cohe)<tol )
exit
982 tstre(1,1)= prnstre(1); tstre(2,2)=prnstre(2); tstre(3,3)=prnstre(3)
983 mat= matmul( prnprj, tstre )
984 mat= matmul( mat, transpose(prnprj) )
993 end subroutine backwardeuler_mc
998 real(kind=
kreal),
intent(inout) :: stress(6)
999 real(kind=
kreal),
intent(in) :: plstrain
1000 integer,
intent(inout) :: istat
1001 real(kind=
kreal),
intent(inout) :: fstat(:)
1002 real(kind=
kreal),
intent(in) :: temp
1003 integer(kind=kint),
intent(in) :: hdflag
1005 real(kind=
kreal),
parameter :: tol =1.d-8
1006 integer,
parameter :: maxiter = 10
1007 real(kind=
kreal) :: dlambda, f
1009 real(kind=
kreal) :: youngs, poisson, pstrain, xi, ina(1), ee(2)
1010 real(kind=
kreal) :: j1,j2,h, dd, eqvst, eqvs, cohe, g, k, devia(6), eta, etabar, pt, p
1012 real(kind=
kreal) :: alpha, beta, depv, factor, resid
1018 j1 = (stress(1)+stress(2)+stress(3))
1020 devia(1:3) = stress(1:3)-pt
1021 devia(4:6) = stress(4:6)
1022 j2 = 0.5d0* dot_product( devia(1:3), devia(1:3) ) + &
1023 dot_product( devia(4:6), devia(4:6) )
1026 cohe = calcurryield( matl, plstrain, temp )
1027 f = eqvst + eta*pt - xi*cohe
1029 if( abs(f/cohe)<tol )
then
1030 istat = dp_plastic_surf
1032 elseif( f<0.d0 )
then
1036 if( hdflag == 2 )
return
1038 istat = dp_plastic_surf
1041 call fetch_tabledata(
mc_isoelastic, matl%dict, ee, ierr, ina)
1043 stop
" fail to fetch young's modulus in elastoplastic calculation"
1048 if( youngs==0.d0 ) stop
"YOUNG's ratio==0"
1049 g = youngs/ ( 2.d0*(1.d0+poisson) )
1050 k = youngs/ ( 3.d0*(1.d0-2.d0*poisson) )
1056 h= calhardencoeff( matl, pstrain, temp )
1057 dd= g+k*etabar*eta+h*xi*xi
1058 dlambda = dlambda+f/dd
1059 if( xi*dlambda<0.d0 )
then
1060 if( xi==0.d0 ) stop
"Math error in return mapping"
1065 pstrain = plstrain+xi*dlambda
1066 cohe = calcurryield( matl, pstrain, temp )
1067 eqvs = eqvst-g*dlambda
1068 p = pt-k*etabar*dlambda
1069 f = eqvs + eta*p- xi*cohe
1070 if( abs(f/cohe)<tol )
exit
1075 if( eqvs>=0.d0 )
then
1076 factor = 1.d0-g*dlambda/eqvst
1078 istat = dp_plastic_apex
1079 if( eta==0.d0 ) stop
'ERROR: BackwardEuler_DP: eta==0.0'
1080 if( etabar==0.d0 ) stop
'ERROR: BackwardEuler_DP: etabar==0.0'
1085 cohe = calcurryield( matl, pstrain, temp )
1086 resid = beta*cohe - pt
1088 h= calhardencoeff( matl, pstrain, temp )
1089 dd= alpha*beta*h + k
1090 depv = depv - resid/dd
1091 pstrain = plstrain+alpha*depv
1092 cohe = calcurryield( matl, pstrain, temp )
1094 resid = beta*cohe - p
1095 if( abs(resid/cohe)<tol )
then
1105 devia(:) = factor*devia(:)
1106 stress(1:3) = devia(1:3)+p
1107 stress(4:6) = devia(4:6)
1116 gauss%plstrain= gauss%fstatus(1)
1118 gauss%fstatus(8:13) =gauss%fstatus(2:7)
integer(kind=4), parameter kreal
This module provides functions for elastic material.
subroutine calelasticmatrix(matl, sectType, D, temp, hdflag)
Calculate isotropic elastic matrix hdflag: 0=full, 1=deviatoric only (edge-smoothed,...
This module provide functions for elastoplastic calculation.
subroutine calelastoplasticmatrix_dp(matl, sectType, stress, istat, extval, plstrain, D, temperature, hdflag)
This subroutine calculates elastoplastic constitutive relation.
subroutine, public planestressj2tangent(matl, stress, istat, fstatus, plstrain, tangent, ierr)
Condense the in-plane J2 tangent and retain the elastic transverse-shear stiffness.
integer, parameter, public j2_no_convergence
integer, parameter, public j2_singular
subroutine, public backwardeuler(matl, stress, plstrain, istat, fstat, plpotential, temp, hdflag)
This subroutine does backward-Euler return calculation.
subroutine backwardeuler_dp(matl, stress, plstrain, istat, fstat, temp, hdflag)
This subroutine does backward-Euler return calculation for Drucker-Prager.
integer, parameter, public j2_bad_state
subroutine, public calelastoplasticmatrix(matl, sectType, stress, istat, extval, plstrain, D, temperature, hdflag)
This subroutine calculates elastoplastic constitutive relation.
character(len=128) function, public planestressj2errormessage(ierr)
subroutine, public update_planestressj2(matl, strain_increment, stress_bak, plstrain, fstatus, stress, strain_increment_out, tangent, istat, fstatus_out, plpotential, energy_increment, ierr)
Return the plane-stress response of the existing three-dimensional J2 perfect-plastic material update...
integer, parameter, public j2_temperature
integer, parameter, public j2_nonfinite
integer, parameter, public j2_bad_property
integer, parameter, public j2_unsupported
subroutine, public checkplanestressj2material(matl, ierr)
subroutine, public updateepstate(gauss)
Clear elatoplastic state.
This module provides aux functions.
subroutine eigen3(tensor, eigval, princ)
Compute eigenvalue and eigenvetor for symmetric 3*3 tensor using Jacobi iteration adapted from numeri...
subroutine deriv_general_iso_tensor_func_3d(dpydpx, dydx, eigv, px, py)
Compute derivative of a general isotropic tensor function of one tensor.
This module summarizes all information of material properties.
integer function getyieldfunction(mtype)
Get type of yield function.
integer(kind=kint), parameter m_plconst5
integer(kind=kint), parameter m_plconst4
integer function getelastictype(mtype)
Get elastic type.
integer(kind=kint), parameter m_plconst1
integer function gethardentype(mtype)
Get type of hardening.
integer(kind=kint), parameter d3
integer(kind=kint), parameter elastic
integer(kind=kint), parameter m_plconst2
character(len=dict_key_length) mc_yield
logical function iskinematicharden(mtype)
If it is a kinematic hardening material?
character(len=dict_key_length) mc_isoelastic
integer(kind=kint), parameter m_plconst3
logical function iselastoplastic(mtype)
If it is an elastoplastic material?
This modules defines a structure to record history dependent parameter in static analysis.
This subroutine read in used-defined material properties tangent.
subroutine, public uelastoplasticmatrix(matl, stress, istat, fstat, plstrain, D, temp, hdflag)
This subroutine calculates elastoplastic constitutive relation.
subroutine, public ubackwardeuler(matl, stress, plstrain, istat, fstat, temp, hdflag)
This subroutine does backward-Euler return calculation.
Structure to manage all material related data.
All data should be recorded in every quadrature points.