TMM4175 Polymer Composites

Home About Python Links Table of Contents

CASE STUDY: Laminate optimization of in-plane load cases

General assumptions:

The laminate is symmetric and balanced and $\mathbf{M} = 0$ and $\mathbf{\kappa} = 0$ such that

\begin{equation} \begin{bmatrix} N_x \\ N_y \\ N_{xy} \end{bmatrix} = \begin{bmatrix} A_{xx} & A_{xy} & 0 \\ A_{xy} & A_{yy} & 0 \\ 0 & 0 & A_{ss} \end{bmatrix} \begin{bmatrix} \varepsilon_x^0 \\ \varepsilon_y^0 \\ \gamma_{xy}^0 \end{bmatrix} \tag{1} \end{equation}

image.png

Material for the study:

In [1]:
import matlib
m1=matlib.get('Carbon/Epoxy(a)')

The cured thickness of individual layers is 0.25 mm.

Useful imports and functions:

In [2]:
import numpy as np
from laminatelib import laminateStiffnessMatrix, solveLaminateLoadCase, layerResults, laminateThickness
import matplotlib.pyplot as plt
%matplotlib inline

Case-1: Combinations of $N_x$ and $N_y$ for a laminate with 0 and 90 layers, stiffness based design

image.png

Objective: Minimize the mass by finding the optimum combination of 0 and 90 layers for the loads $ N_x$ =400 N/mm and $ N_y$ =100 N/mm where none of the strain components shall be greater than 0.002.

STEP-1: Ignore the discretization of layers and find the optimum ratio between the total thickness of 0 and total thickness of 90 layers where the objective is to minimize the total deformation (strains)

In [3]:
h = 1
ratio = np.linspace(0.8,0.9)

epsx=[]
epsy=[]

for r in ratio:
    t0 = h*r
    t90 = h*(1-r)
    layup = [{'mat': m1, 'ori': 0, 'thi': t0/2},
             {'mat': m1, 'ori':90, 'thi': t90},
             {'mat': m1, 'ori': 0, 'thi': t0/2}]
    ABD = laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD, Nx=400, Ny=100)
    epsx.append(eK[0])
    epsy.append(eK[1])
    
plt.plot(ratio,epsx, ratio,epsy)
plt.grid()
plt.show()
    

STEP-2: Scale the thickness of all layers to meet the requirement

In [4]:
h = 1*0.00342/0.002
ratio = np.linspace(0.8,0.9)

epsx=[]
epsy=[]

for r in ratio:
    t0 = h*r
    t90 = h*(1-r)
    layup = [{'mat': m1, 'ori': 0, 'thi': t0/2},
             {'mat': m1, 'ori':90, 'thi': t90},
             {'mat': m1, 'ori': 0, 'thi': t0/2}]
    ABD = laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD, Nx=400, Ny=100)
    epsx.append(eK[0])
    epsy.append(eK[1])
    
plt.plot(ratio,epsx, ratio,epsy)
plt.grid()
plt.show()

STEP-3: Take actual layer thickness into consideration and compute the required number of layers:

In [5]:
print('No. of 0-layers: ', h*0.864/0.25)
print('No. of 90-layers:', h*(1-0.864)/0.25)
No. of 0-layers:  5.9097599999999995
No. of 90-layers: 0.9302400000000001

Hence, 6 layers with 0 orientation and 1 layer with 90 orientation:

In [6]:
layup = [{'mat': m1, 'ori': 0, 'thi': 0.25*3},
         {'mat': m1, 'ori':90, 'thi': 0.25*1},
         {'mat': m1, 'ori': 0, 'thi': 0.25*3}]
ABD = laminateStiffnessMatrix(layup)
NM, eK = solveLaminateLoadCase(ABD, Nx=400, Ny=100)
print('Strains:',eK[0:2])
print('Total thickness',laminateThickness(layup))
print('Weight per area:', m1['rho']*laminateThickness(layup)*1E9,'kg/m2')
Strains: [0.00196622 0.00188974]
Total thickness 1.75
Weight per area: 2.8000000000000003 kg/m2

Case-2: Combinations of $N_x$ and $N_y$ for a laminate with 0 and 90 layers, strength based design

image.png

Objective: Minimize the mass by finding the optimum combination of 0 and 90 layers for the loads $ N_x$ =1200 N/mm and $ N_y$ =600 N/mm where the stress exposure factor according to maximum stress criterion shall be less than 1.0.

STEP-1: Ignore the discretization of layers and find the optimum ratio between the total thickness of 0 and total thickness of 90 layers where the objective is to minimize the exposure factor.

In [7]:
h = 1
ratio = np.linspace(0.6,0.8)

fE_lam=[]

for r in ratio:
    t0 = h*r
    t90 = h*(1-r)
    layup = [{'mat': m1, 'ori': 0, 'thi': t0/2},
             {'mat': m1, 'ori':90, 'thi': t90},
             {'mat': m1, 'ori': 0, 'thi': t0/2}]
    ABD = laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD, Nx=1200, Ny=600)
    res = layerResults(layup,eK)
    fE_laymax=0
    for layres in res:
        if layres['fail']['MS']['bot']> fE_laymax:
            fE_laymax = layres['fail']['MS']['bot']
    fE_lam.append(fE_laymax)
        
plt.plot(ratio,fE_lam)
plt.grid()
plt.show()

STEP-2: Scale the thickness of all layers to meet the requirement

In [8]:
h = 1*3.97
ratio = np.linspace(0.6,0.8)

fE_lam=[]

for r in ratio:
    t0 = h*r
    t90 = h*(1-r)
    layup = [{'mat': m1, 'ori': 0, 'thi': t0/2},
             {'mat': m1, 'ori':90, 'thi': t90},
             {'mat': m1, 'ori': 0, 'thi': t0/2}]
    ABD = laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD, Nx=1200, Ny=600)
    res = layerResults(layup,eK)
    fE_laymax=0
    for layres in res:
        if layres['fail']['MS']['bot']> fE_laymax:
            fE_laymax = layres['fail']['MS']['bot']
    fE_lam.append(fE_laymax)
        
plt.plot(ratio,fE_lam)
plt.grid()
plt.show()

STEP-3: Take actual layer thickness into consideration and compute the number of layers:

In [9]:
print(h*0.7/0.25)
print(h*(1-0.7)/0.25)
11.116
4.764000000000001
In [10]:
layup = [{'mat': m1, 'ori': 0, 'thi': 0.25*6},
         {'mat': m1, 'ori':90, 'thi': 0.25*5},
         {'mat': m1, 'ori': 0, 'thi': 0.25*6}]

ABD = laminateStiffnessMatrix(layup)
NM, eK = solveLaminateLoadCase(ABD, Nx=1200, Ny=600)
res = layerResults(layup,eK)
print(res[0]['fail']['MS']['bot'])
print(res[1]['fail']['MS']['bot'])
print('Total thickness',laminateThickness(layup))
print('Weight per area:', m1['rho']*laminateThickness(layup)*1E9,'kg/m2')
0.9371028879886175
0.9292828360721618
Total thickness 4.25
Weight per area: 6.800000000000001 kg/m2

Case-3: Combinations of $N_x$ and $N_{xy}$ for a laminate with 0 and $\pm$45 layers, stiffness based design

image.png

Objective: Minimize the mass by finding the optimum combination of 0 and $\pm$45 layers for the loads $ N_x$ =1000 N/mm and $ N_{xy}$ =500 N/mm where both $\epsilon_x^0$ and $\gamma_{xy}^0$ shall be less than 0.002.

STEP-1: Ignore the discretization of layers and find the optimum ratio between the different thicknesses where the objective is to minimize the total deformation (strains)

In [11]:
h=1
ratio = np.linspace(0.1,0.4)

epsx=[]
epsxy=[]

for r in ratio:
    t0= h*r
    t45=h*(1-r)
    layup=[{'mat':m1, 'ori':  0,  'thi':t0/2},
           {'mat':m1, 'ori': 45,  'thi':t45/4},
           {'mat':m1, 'ori':-45,  'thi':t45/4},
           {'mat':m1, 'ori':-45,  'thi':t45/4},
           {'mat':m1, 'ori': 45,  'thi':t45/4},
           {'mat':m1, 'ori':  0,  'thi':t0/2}]

    ABD=laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD,Nx=1000,Nxy=500)
    epsx.append(eK[0])
    epsxy.append(eK[2])
    
plt.plot(ratio,epsx,ratio,epsxy)
plt.grid()
plt.show()

STEP-2: Scale the thickness of all layers to meet the requirement

In [12]:
h=9.94
ratio = np.linspace(0.29,0.3)

epsx=[]
epsxy=[]

for r in ratio:
    t0= h*r
    t45=h*(1-r)
    layup=[{'mat':m1, 'ori':  0,  'thi':t0/2},
           {'mat':m1, 'ori': 45,  'thi':t45/4},
           {'mat':m1, 'ori':-45,  'thi':t45/4},
           {'mat':m1, 'ori':-45,  'thi':t45/4},
           {'mat':m1, 'ori': 45,  'thi':t45/4},
           {'mat':m1, 'ori':  0,  'thi':t0/2}]

    ABD=laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD,Nx=1000,Nxy=500)
    epsx.append(eK[0])
    epsxy.append(eK[2])
    
plt.plot(ratio,epsx,ratio,epsxy)
plt.grid()
plt.show()

STEP-3: Take actual layer thickness into consideration.

In [13]:
print(h*0.295/0.25)
print(h*(1-0.295)/0.25)
11.729199999999999
28.030800000000003

Finally,

In [14]:
layup=[{'mat':m1, 'ori':  0,  'thi':6*0.25},
       {'mat':m1, 'ori': 45,  'thi':7*0.25},
       {'mat':m1, 'ori':-45,  'thi':7*0.25},
       {'mat':m1, 'ori':-45,  'thi':7*0.25},
       {'mat':m1, 'ori': 45,  'thi':7*0.25},
       {'mat':m1, 'ori':  0,  'thi':6*0.25}]

ABD=laminateStiffnessMatrix(layup)
NM, eK = solveLaminateLoadCase(ABD,Nx=1000,Nxy=500)
print('Strains:',eK[0:3])
print()
print('Laminate thickness:',laminateThickness(layup))

print()
print('Weight per area:',m1['rho']*laminateThickness(layup)*1E9,'kg/m2')
Strains: [ 0.00196436 -0.001441    0.00199898]

Laminate thickness: 10.0

Weight per area: 16.0 kg/m2

Case-4: Combinations of $N_x$ and $N_{xy}$ for a laminate with $\pm\theta$ layers, stiffness based design

image.png

Objective: Minimize the mass by finding the optimum angle $\theta$ for the loads $ N_x$ =1000 N/mm and $ N_xy$ =500 N/mm where both $\epsilon_x^0$ and $\gamma_{xy}^0$ shall be less than 0.002.

STEP-1: Ignore the discretization of layers and find the optimum angle where the objective is to minimize the total deformation (strains)

In [15]:
h = 1
angles = np.linspace(10,50)

epsx=[]
epsxy=[]

for a in angles:
    layup=[{'mat':m1, 'ori': a,  'thi':h/4},
           {'mat':m1, 'ori':-a,  'thi':h/4},
           {'mat':m1, 'ori':-a,  'thi':h/4},
           {'mat':m1, 'ori': a,  'thi':h/4}]

    ABD=laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD,Nx=1000,Nxy=500)
    epsx.append(eK[0])
    epsxy.append(eK[2])

plt.plot(angles,epsx,angles,epsxy)
plt.grid()
plt.show()    

STEP-2: Scale the thickness of all layers to meet the requirement

In [16]:
h = 10
angles = np.linspace(28,30)

epsx=[]
epsxy=[]

for a in angles:
    layup=[{'mat':m1, 'ori': a,  'thi':h/4},
           {'mat':m1, 'ori':-a,  'thi':h/4},
           {'mat':m1, 'ori':-a,  'thi':h/4},
           {'mat':m1, 'ori': a,  'thi':h/4}]

    ABD=laminateStiffnessMatrix(layup)
    NM, eK = solveLaminateLoadCase(ABD,Nx=1000,Nxy=500)
    epsx.append(eK[0])
    epsxy.append(eK[2])

plt.plot(angles,epsx,angles,epsxy)
plt.grid()
plt.show()    

Case-5:Strength based design for a set of load cases

image.png

Objective: Minimize the mass by finding the optimum combinations of 0, 90 and $\pm$45 layers for a laminate subjected to a set of five possible load cases where the stress exposure factor given by the maximum stress criterion shall be less than one.

Load cases:

  1. $N_x$ = 2000
  2. $N_y$ = 1000
  3. $N_{xy}$ = 600
  4. $N_x$ = 2000 and $N_y$ = 1000
  5. $N_x$ = 2000 and $N_{xy}$ = 600
In [17]:
t0 = 0.25*16     # 0,2,4,6,...
t90= 0.25*4      # 0,1,2,3....
t45= 0.25*8      # 4,8,12,16,...

layup=[{'mat':m1, 'ori':  0,  'thi': t0/2},
       {'mat':m1, 'ori': 45,  'thi':t45/4},
       {'mat':m1, 'ori':-45,  'thi':t45/4},
       {'mat':m1, 'ori': 90,  'thi':t90/1},
       {'mat':m1, 'ori':-45,  'thi':t45/4},
       {'mat':m1, 'ori': 45,  'thi':t45/4},
       {'mat':m1, 'ori':  0,  'thi': t0/2}]

ABD=laminateStiffnessMatrix(layup)
Nloads = ((2000,0,0),(0,1000,0),(0,0,600),(2000,1000,0),(2000,0,600))
for N in Nloads:
    NM,eK = solveLaminateLoadCase(ABD,Nx=N[0],Ny=N[1],Nxy=N[2])
    res = layerResults(layup,eK)
    fE_high=0
    for layer in res:
        if layer['fail']['MS']['bot']>fE_high:
            fE_high=layer['fail']['MS']['bot']
    print(fE_high)
    
print('h=',laminateThickness(layup))
0.7771452508841328
0.9969146946756637
0.6029187451045062
0.9720217614822217
0.9790449039498517
h= 7.0
In [18]:
t0 = 0.25*12     # 0,2,4,6,...
t90= 0.25*4      # 0,1,2,3....
t45= 0.25*12     # 4,8,12,16,...

layup=[{'mat':m1, 'ori':  0,  'thi': t0/2},
       {'mat':m1, 'ori': 45,  'thi':t45/4},
       {'mat':m1, 'ori':-45,  'thi':t45/4},
       {'mat':m1, 'ori': 90,  'thi':t90/1},
       {'mat':m1, 'ori':-45,  'thi':t45/4},
       {'mat':m1, 'ori': 45,  'thi':t45/4},
       {'mat':m1, 'ori':  0,  'thi': t0/2}]

ABD=laminateStiffnessMatrix(layup)
Nloads = ((2000,0,0),(0,1000,0),(0,0,600),(2000,1000,0),(2000,0,600))
for N in Nloads:
    NM,eK = solveLaminateLoadCase(ABD,Nx=N[0],Ny=N[1],Nxy=N[2])
    res = layerResults(layup,eK)
    fE_high=0
    for layer in res:
        if layer['fail']['MS']['bot']>fE_high:
            fE_high=layer['fail']['MS']['bot']
    print(fE_high)
    
print('h=',laminateThickness(layup))
0.9271609602957828
0.9039257942931977
0.4549611766462595
0.9993625252313258
0.9271609602957828
h= 7.0

Disclaimer:This site is about polymer composites, designed for educational purposes. Consumption and use of any sort & kind is solely at your own risk.
Fair use: I spent some time making all the pages, and even the figures and illustrations are my own creations. Obviously, you may steal whatever you find useful here, but please show decency and give some acknowledgment if or when copying. Thanks! Contact me: nils.p.vedvik@ntnu.no www.ntnu.edu/employees/nils.p.vedvik

Copyright 2021, All right reserved, I guess.