program vplate ! F90 version of plate code ! to include voigt effects ! Limits: 10 material sets, 20 plies ! Equation references are to Roylance Module 15 real E_1(10) ! Modulus in fiber direction real E_2(10) ! Modulus in transverse direction real G_12(10) ! In-plane shear modulus real nu_12(10) ! Principal Poisson's ratio real thk(10) ! Ply thickness real v_frac(10) ! Creep fraction integer k ! Ply index real theta(20) ! Ply orientation (degrees) real eps(6) ! vector of strains and curvatures real eps0(3) ! Laminate in-plane strains real kappa(3) ! Laminate curvature real sig(3) ! Ply stresses in 1-2 frame real sigbar(3) ! Ply stresses in x-y frame real z(21) ! Vertical coordinate of bottom of ply real A(3,3) ! Transformation matrix real A_inv(3,3) ! Inverse transformation matrix real C(6,6) ! Laminate compliance matrix real D(3,3) ! Ply stiffness matrix in 1-2 frame real D_bar(3,3) ! Ply stiffness matrix in x-y frame real E(6,6) ! Laminate stiffness matrix real N(6) ! Vector of tractions and moments real R(3,3) ! Reuter's matrix real R_inv(3,3) ! Inverse Reuter's matrix real S(3,3) ! Ply compliance matrix in 1-2 frame real S_bar(3,3) ! Ply compliance matrix in x-y frame real eps_l_c(6) ! Laminate creep strain real eps0_l_c(3) ! Laminate creep strain vector real kappa_l_c(3) ! Laminate creep curvature vector real eps_p_e_xy(3) ! Ply elastic strain in x-y frame real eps_p_e_12(3) ! Ply elastic strain in 1-2 frame real eps_p_lc_xy(3) ! Ply laminate creep strain in x-y frame real eps_p_lc_12(3) ! Ply laminate creep strain in 1-2 frame real eps_pc(3,20) ! Ply creep strain history array real eps_p_c_12(3) ! Ply creep strain, 1-2 frame real sig_k_12(3) ! Ply stress, 1-2 frame real sig_k_xy(3) ! Ply stress, x-y frame real N_c(3) ! Equivalent laminate creep traction real M_c(3) ! Equivalent laminate creep bending moment real N_l_c(6) ! Equivalent laminate creep load integer m ! material property set index integer mat(20) ! ply material index integer Nplies ! number of plies in layup data R/1.,3*0.,1.,3*0.,2./ data R_inv/1.,3*0.,1.,3*0.,.5/ data E/36*0./ data eps_l_c/6*0./ data eps_pc/60*0./ print*, 'Viscoelastic laminate code, rev 9/11/99' print* ! ---------------------------------------------------------------------- ! Get material properties do m = 1,10 print*, 'Material set ',m,': ' print*, 'Enter modulus in fiber direction (-1 to stop): ' read*, E_1(m) if (E_1(m) .lt. 0.0 ) exit print*, 'Enter modulus in transverse direction: ' read*, E_2(m) print*, 'Enter principal Poisson ratio: ' read*, nu_12(m) check = abs((E_1(m)-E_2(m))/E_1(m) ) ! check for isotropy if (check.lt.0.001) then G_12(m) = E_1(m)/(2.*(1.+ nu_12(m) )) ! calculate G_12 if isotropic else print*, 'Enter shear modulus: ' read*, G_12(m) ! otherwise read G_12 end if print*, 'Enter ply thickness: ' read*, thk(m) print*, 'Enter creep fraction: ' read*, v_frac(m) end do ! ---------------------------------------------------------------------- ! Define layup (ply orientations) z(1)=0. ! vertical coordinate, bottom of first ply print*, 'Define layup sequence, starting at bottom...' print*, ' (use negative material set number to stop)' ! loop over plies do k = 1,20 write (*,50) k 50 format (/' enter material set number for ply number',i3,': ') read (5,*) m if (m.lt.0) exit mat(k) = m print*, 'enter ply angle: ' read*, theta(k) z(k+1)=z(k)+thk(m) Nplies = k end do ! Loop over plies again, ! adjust ply coordinates to measure from centerline z0 = z(Nplies+1)/2. ! midpoint coordinate do k = 1, Nplies+1 z(k) = z(k) - z0 end do ! ---------------------------------------------------------------------- ! Loop over plies, ! compute contributions to stiffness matrix (Eqn. 25, p.9) do k = 1,Nplies z1= z(k+1) - z(k) z2= 0.5 * ( z(k+1)**2 - z(k)**2 ) z3=(1./3.) * ( z(k+1)**3 - z(k)**3) call get_D_bar (D_bar) do i=1,3 do j=1,3 E(i,j) = E(i,j) + D_bar(i,j)*z1 E(i+3,j) = E(i+3,j) + D_bar(i,j)*z2 E(i,j+3) = E(i,j+3) + D_bar(i,j)*z2 E(i+3,j+3)= E(i+3,j+3) + D_bar(i,j)*z3 end do end do end do ! ---------------------------------------------------------------------- ! print stiffness matrix E(6,6) write(*,120) 120 format(/' laminate stiffness matrix:',/) do i=1,6 write(*,130) (E(i,j),j=1,6) 130 format (4x,3e12.4,2x,3e12.4) if (i.eq.3) print* end do ! obtain and print laminate compliance matrix C(6,6) call invert (E,6,6,C) ! Numerical recipes inversion routine write(*,310) 310 format(/' laminate compliance matrix:',/) do i=1,6 write(*,130) (C(i,j),j=1,6) if (i.eq.3) print* end do ! ---------------------------------------------------------------------- ! obtain traction-moment vector N(6) print* print*, 'input tractions and moments...' print* print*, ' Nx: ' ; read *, N(1) print*, ' Ny: ' ; read *, N(2) print*, ' Nxy: ' ; read *, N(3) print*, ' Mx: ' ; read *, N(4) print*, ' My: ' ; read *, N(5) print*, ' Mxy: ' ; read *, N(6) ! ---------------------------------------------------------------------- ! compute and print resulting strains and rotations eps = matmul (C,N) write(6,150) (eps(i),i=1,6) 150 format(/' midplane strains:',//3x,'eps-xx =',e12.4, & /3x,'eps-yy =',e12.4,/3x,'eps-xy =',e12.4, & //' rotations:',//3x,'kappa-xx =',e12.4, & /3x,'kappa-yy= ',e12.4,/3x,'kappa-xy =',e12.4//) ! ---------------------------------------------------------------------- ! compute ply stresses write(6,160) 160 format (/' stresses:',/2x,'ply',5x,'sigma-1', & 5x,'sigma-2',4x,'sigma-12'/) do i=1,3 ! get midplane strain and curvature vectors eps0(i) = eps(i) kappa(i) = eps(i+3) end do do k=1,Nplies ! loop over plies (Eqn. 16, p. 8) zctr=(z(k)+z(k+1))/2. ! center coordinate of ply call get_D_bar (D_bar) ! this also gets A for current ply sigbar = matmul(D_bar,eps0) + zctr * matmul(D_bar,kappa) ! x-y frame sig = matmul(A,sigbar) ! transform to 1-2 frame write(6,200) k,sig 200 format (3x,i2,3e12.4) end do ! ---------------------------------------------------------------------- ! ---------------------------------------------------------------------- ! adaptation of Brinson-Tuttle viscoelastic response ! assumes simple voigt behavior in 2- and 12-directions ! get time parameters, begin time loop ! all plies have same relaxation time print*, 'Enter relaxation time' ; read*, tau told = 0. t = tau/100. do while (t.le.(100.*tau)) ! step over +/- 2 decades from tau dt = t - told ! recover midplane strain and curvature vectors do i=1,3 eps0(i) = eps(i) kappa(i) = eps(i+3) eps0_l_c(i) = eps_l_c(i) kappa_l_c(i) = eps_l_c(i+3) end do ! get creep response of individual plies ! zero-initialize creep load vector do i=1,3 N_c(i)=0. M_c(i)=0. end do do k=1,Nplies zctr = (z(k)+z(k+1))/2 ! ply center coordinate thk_p = z(k+1)-z(k) ! ply thickness call get_A(A) ; call get_A_inv(A_inv) ; call get_D(D) ! ply elastic strain eps_p_e_xy = eps0 + zctr*kappa eps_p_e_12 = matmul(R,matmul(A,matmul(R_inv,eps_p_e_xy))) ! contribution of laminate creep strain eps_p_lc_xy = eps0_l_c + zctr*kappa_l_c eps_p_lc_12 = matmul(R,matmul(A,matmul(R_inv,eps_p_lc_xy))) ! recover ply creep strain from history do i=1,3 eps_p_c_12(i) = eps_pc(i,k) end do ! current ply stress sig_k_12 = matmul (D,(eps_p_e_12 + eps_p_lc_12 - eps_p_c_12)) ! independent ply creep strain - voigt model ! only 2- and 12-components effected m = mat(k) C_v_2 = v_frac(m) / E_2(m) C_v_12 = v_frac(m) / G_12(m) eps_p_c_12(2) = sig_k_12(2) * C_v_2 * (1. - exp( -dt/tau )) & + eps_p_c_12(2) * exp( -dt/tau ) eps_p_c_12(3) = sig_k_12(3) * C_v_12 * (1. - exp( -dt/tau )) & + eps_p_c_12(3) * exp( -dt/tau ) ! store in history for later recovery eps_pc(2,k) = eps_p_c_12(2) eps_pc(3,k) = eps_p_c_12(3) ! stresses corresponding to ply creep strains sig_k_12 = matmul (D,eps_p_c_12) sig_k_xy = matmul (A_inv,sig_k_12) ! contributions to equivalent laminate creep load N_c = N_c + thk_p * sig_k_xy M_c = M_c + thk_p * zctr * sig_k_xy end do ! end loop over plies do i=1,3 ! form 6x1 equivalent laminate creep load N_l_c(i) = N_c(i) N_l_c(i+3) = M_c(i) end do ! equivalent laminate creep strain eps_l_c = matmul(C,N_l_c) write (*,400) t,eps_l_c !write (*,400) t,eps_p_e_12(2),eps_p_lc_12(2),eps_p_c_12(2), & ! sig_k_12(2),sig_k_xy(1),N_l_c(1),eps_l_c(1) 400 format (7e12.4) ! update time, end time loop told = t t = t*(10**(1./4.)) ! 4 logarithmic time steps per decade end do ! ---------------------------------------------------------------------- ! ---------------------------------------------------------------------- ! ! internal routines contains subroutine get_A (A) ! Transformation matrix for x-y --> 1-2 (Eqn. 3.27, p. 99) dimension A(3,3) thet = theta(k) * 3.14159/180. sc = sin(thet)*cos(thet) s2 = (sin(thet))**2 c2 = (cos(thet))**2 A(1,1) = c2 A(2,1) = s2 A(3,1) = -1.*sc A(1,2) = s2 A(2,2) = c2 A(3,2) = sc A(1,3) = 2.*sc A(2,3) = -2.*sc A(3,3) = c2 - s2 end subroutine get_A ! ---------------------------------------------------------------------- subroutine get_A_inv (A_inv) ! Transformation matrix for 1-2 --> x-y dimension A_inv(3,3) thet = theta(k) * 3.14159/180. sc = sin(thet)*cos(thet) s2 = (sin(thet))**2 c2 = (cos(thet))**2 A_inv(1,1) = c2 A_inv(2,1) = s2 A_inv(3,1) = sc A_inv(1,2) = s2 A_inv(2,2) = c2 A_inv(3,2) = -1.*sc A_inv(1,3) = -2.*sc A_inv(2,3) = 2.*sc A_inv(3,3) = c2 - s2 end subroutine get_A_inv ! ---------------------------------------------------------------------- subroutine get_D(D) ! Stiffness matrix for current ply in 1-2 frame dimension D(3,3) call get_S(S) call invert (S,3,3,D) ! Numerical Recipes matrix inversion end subroutine get_D ! ---------------------------------------------------------------------- subroutine get_D_bar (D_bar) ! Stiffness matrix for current ply in x-y frame dimension D_bar(3,3) ! First, compute compliance matrix S_bar in x-y frame ! [S_bar] = [R][A]-1[R]-1[S][A] (Eqn. 3.56, p.114) call get_A (A); call get_A_inv (A_inv); call get_S(S) S_bar = matmul(R,matmul(A_inv,matmul(R_inv,matmul(S,A)))) ! invert S_bar to obtain D_bar call invert (S_bar,3,3,D_bar) ! Numerical Recipes matrix inversion end subroutine get_D_bar ! ---------------------------------------------------------------------- subroutine get_S (S) ! Compliance matrix for current ply in 1-2 frame (Eqn. 3.55, p. 119) dimension S(3,3) m=mat(k) S(1,1) = 1./E_1(m) S(2,1) = -nu_12(m) / E_1(m) S(3,1) = 0. S(1,2) = S(2,1) S(2,2) = 1./E_2(m) S(3,2) = 0. S(1,3) = 0. S(2,3) = 0. S(3,3) = 1./G_12(m) end subroutine get_S ! ---------------------------------------------------------------------- end program vplate