TMM4175 Polymer Composites

Home About Python Links Table of Contents

CASE STUDY: Fiber diameter distribution

While carbon fibers and Kevlar fibers usually have consistent diameter with just a minor variation, the diameter within single batches of glass fibers varies significantly [1].

This case study presents ideas on how to numerically process and visualize fiber diameter distribution and randomly placed fibers in a unidirectional configuration. The diameters of a representative sample of 600 glass fibers are listed in the text file fiberDiameters.txt.

The simple numpy method for reading the data into a numpy array is:

In [1]:
import numpy as np
fibd=np.loadtxt('data/fiberDiameters.txt')

Then, visualize the fiber diameter distribution:

In [2]:
%matplotlib inline

def plotDistribution(d):
    import matplotlib.pyplot as plt
    fig,ax = plt.subplots(figsize=(8,6))
    n,bins,patches=plt.hist(d, 20, density=True,facecolor='teal', alpha=0.6 )
    ax.set_xlabel('Fiber diameter(um)')
    ax.set_ylabel('Normalized number of fibers')
    ax.set_title('Fiber diameter distribution')
    ax.set_xlim(0,)
    ax.grid(True)
    plt.show()
    
plotDistribution(fibd)

Relevant statistical data:

In [3]:
print('Min:',np.amin(fibd))
print('Max:',np.amax(fibd))
print('Range:',np.ptp(fibd))
print('Mean:',np.mean(fibd))
print('Stdev:',np.std(fibd))
Min: 7.54
Max: 17.0
Range: 9.46
Mean: 12.025266666666667
Stdev: 1.5298298147905938

The basic idea of the following code is to simulate a cross section of UD composite with randomly placed fibers with varying diameters according to the previous distribution:

In [4]:
def plotRandomDistributionOfFibers(dx,dy,d,n):
    import numpy as np
    rx=dx*np.random.rand(n)
    ry=dy*np.random.rand(n)
    x, y = [], []  #lists of coordinates verified to fit
    dm=[] 
    k=0 # counter: no. of fibers already added
    
    for j in range(0,n):     # all randomly generated coordinates
        fits=True            # initially assuming that the fiber fits
        for p in range(0,k): # all previously verified coordinates
            distance= ( (rx[j]-x[p])**2 + (ry[j]-y[p])**2 )**0.5   # vector length
            if distance<(d[k]+d[p])/2:   # does not fit if the distance is less than average diameter of the two
                fits=False
        if fits==True:       # append only the ones that fit
            x.append(rx[j])
            y.append(ry[j])
            dm.append(d[k])
            k=k+1
    print('Number of fibers:',k)
    import matplotlib.pyplot as plt
    fig,ax=plt.subplots(figsize=(12,12))
    ax.set_xlim(0,dx)
    ax.set_ylim(0,dy)
    ax.set_axis_off()
    for i in range(0,len(x)):
        circle1 = plt.Circle( (x[i], y[i]), dm[i]/2, color='black',fc='silver')
        ax.add_artist(circle1)
In [5]:
plotRandomDistributionOfFibers(dx=200,dy=200,d=fibd,n=20000)  
Number of fibers: 191

Although the sample of fibers is the same, another random sample of positions will produce a different result, and likely a different number of fibers in the cross section:

In [6]:
plotRandomDistributionOfFibers(dx=200,dy=200,d=fibd,n=20000)  
Number of fibers: 188

The same code for a sample of fibers having identical diameters:

In [7]:
d12=[12.025 for i in range(0,300)]
plotRandomDistributionOfFibers(dx=200,dy=200,d=d12,n=20000)  
Number of fibers: 197

The function scipy.stats.norm() creates a normal distribution based on the mean and the standard deviation which can be added to the plot:

In [8]:
def plotDistributionB(d):
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    x=np.linspace(min(d),max(d))
    y=norm.pdf(x,np.mean(d),np.std(d))
    fig,ax = plt.subplots(figsize=(8,6))
    n,bins,patches=plt.hist(d, 20, density=True,facecolor='teal', alpha=0.6 )
    ax.plot(x,y,color='black')
    ax.set_xlabel('Fiber diameter(um)')
    ax.set_ylabel('Normalized number of fibers')
    ax.set_title('Fiber diameter distribution')
    ax.set_xlim(0,)
    ax.grid(True)
    plt.show()
    
plotDistributionB(fibd)

Finally, creating a fictive distribution is simple. For example, natural fibers show typically diameters within a large range as in the following example:

In [9]:
def plotFakeDistribution(mean,std,n):
    import matplotlib.pyplot as plt
    from scipy.stats import norm
    dis = np.random.normal(mean, std, n)
    fig,ax = plt.subplots(figsize=(8,6))
    n,bins,patches=plt.hist(dis, 15, density=True,facecolor='orange', alpha=0.6 )
    x=np.linspace(min(dis),max(dis))
    y=norm.pdf(x,mean,std)
    ax.plot(x,y,color='black')
    ax.set_xlabel('Fiber diameter(um)')
    ax.set_ylabel('Normalized number of fibers')
    ax.set_title('Fiber diameter distribution')
    ax.set_xlim(0,)
    ax.grid(True)
    plt.show()
In [10]:
plotFakeDistribution(40,10,500)

References and further readings

  1. Thomason, J. L. "Structure–property Relationships in Glass Reinforced Polyamide, Part 2: The Effects of Average Fiber Diameter and Diameter Distribution." Polymer Composites 28, no. 3 (2007): 331-43.

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.