Solid laminate

A solid laminate implies a laminate made of solid elements where each layer is a discret volume as described in Lightweight Design

The layup definition for the script is a list of dictionaries similar to the one found in Laminates from Lightweight Design. A material reference for a layer is however not an object, but a name.

The following example has five layers of the same material but with different thicknesses and orientations:

lam1 = [{'mat':'E-glass/Epoxy', 'ori':  0.0, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori':-45.0, 'thi': 2.0},
        {'mat':'E-glass/Epoxy', 'ori':  0.0, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori': 45.0, 'thi': 2.0},
        {'mat':'E-glass/Epoxy', 'ori':  0.0, 'thi': 1.0}]

Lists of parameters are generated from the laminate definition:

    tk = [layer['thi'] for layer in laminate]                 # list of thicknesses
    t = sum(tk)                                               # total thickness
    zk = [sum(tk[0:i])+tk[i]/2.0 for i in range(0, len(tk))]  # list of z-coordinates to the midle of layers
    orientations = [layer['ori'] for layer in laminate]       # list of rotation angles
    materials = [layer['mat'] for layer in laminate]          # list of material names

The complete script for one load case:

In [ ]:
from abaqus import *
from abaqusConstants import *

def matlib(modelname):
    mod = mdb.models[modelname]
    mat = mod.Material('E-glass/Epoxy')
    mat.Density(table=((2000e-12, ), ))
    mat.Elastic(type=ENGINEERING_CONSTANTS, 
        table=((40000, 10000, 10000, 0.3, 0.3, 0.3, 3800, 3800, 3400,), ))
    mat.Expansion(type=ORTHOTROPIC, table=((7E-06, 22E-06, 22E-06), ))


lam1 = [{'mat':'E-glass/Epoxy', 'ori':  0.0, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori':-45.0, 'thi': 2.0},
        {'mat':'E-glass/Epoxy', 'ori':  0.0, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori': 45.0, 'thi': 2.0},
        {'mat':'E-glass/Epoxy', 'ori':  0.0, 'thi': 1.0}]

def solidLaminateA(modelname, L, b, laminate, esize, ex):
    
    tk = [layer['thi'] for layer in laminate]                 # list of thicknesses
    t = sum(tk)                                               # total thickness
    zk = [sum(tk[0:i])+tk[i]/2.0 for i in range(0, len(tk))]  # list of z-coordinates to the midle of layers
    orientations = [layer['ori'] for layer in laminate]       # list of rotation angles
    materials = [layer['mat'] for layer in laminate]          # list of material names
    
    # new model:
    mod = mdb.Model(name=modelname)

    # materials and sections:
    matlib(modelname)
    for matname in mod.materials.keys():
        mod.HomogeneousSolidSection(name=matname, material=matname, thickness=None)
     
    # sketch and solid extrusion:    
    ske = mod.ConstrainedSketch(name='__profile__', sheetSize=200.0)
    ske.rectangle(point1=(0.0, 0.0), point2=(L, b))
    prt = mod.Part(name='P1', dimensionality=THREE_D, type=DEFORMABLE_BODY)
    prt.BaseSolidExtrude(sketch=ske, depth=t)
    del mod.sketches['__profile__']
    session.viewports['Viewport: 1'].setValues(displayedObject=prt)

    # Partitions (creating layers):
    hk = 0
    for i in range(0, len(tk)-1):
        hk=hk+tk[i]
        id=prt.DatumPlaneByPrincipalPlane(principalPlane=XYPLANE, offset=hk).id
        prt.PartitionCellByDatumPlane(cells=prt.cells, datumPlane=prt.datums[id])

    # Sets, orientations and section assignments:
    id = prt.DatumCsysByDefault(coordSysType=CARTESIAN).id
    count = 1
    for z,ang,mat in zip(zk,orientations,materials):
        c = prt.cells.findAt(coordinates=((L/2.0, b/2.0, z),))
        reg = prt.Set(name='Layer-'+str(count), cells=c)
        prt.MaterialOrientation(region=reg, orientationType=SYSTEM, axis=AXIS_3, 
            localCsys=prt.datums[id], additionalRotationType=ROTATION_ANGLE, 
            angle=ang, stackDirection=STACK_3)
        prt.SectionAssignment(region=reg, sectionName=mat)
        count = count + 1

    # Mesh:
    prt.seedPart(size=esize, deviationFactor=0.1, minSizeFactor=0.1)
    prt.generateMesh()

    # Assembly:
    ass = mod.rootAssembly
    ass.DatumCsysByDefault(CARTESIAN)
    ins = ass.Instance(name='P1', part=prt, dependent=ON)

    # Load case: uniform tensile strain x-direction:
    mod.StaticStep(name='Step-1', previous='Initial')
    region = ass.Set(name='faces at x=0', faces = ins.faces.getByBoundingBox(xMax=0))
    mod.DisplacementBC(name='fix ux at x=0', createStepName='Step-1', region=region, u1=0)
    region = ass.Set(name='faces at x=L', faces = ins.faces.getByBoundingBox(xMin=L))
    mod.DisplacementBC(name='displacement ux at x=L', createStepName='Step-1', region=region, u1=ex*L)
    # Preventing rigid body motions:
    region = ass.Set(name='v1-rb', vertices = ins.vertices.findAt(coordinates=((0,0,0),)))
    mod.DisplacementBC(name='rb1', createStepName='Step-1', region=region, u2=0, u3=0)
    region = ass.Set(name='v2-rb', vertices = ins.vertices.findAt(coordinates=((0,b,0),)))
    mod.DisplacementBC(name='rb2', createStepName='Step-1', region=region, u3=0)

    # Job and results
    job = mdb.Job(name=modelname, model=modelname)
    job.submit(consistencyChecking=OFF)
    job.waitForCompletion()
    odb = session.openOdb(name=modelname+'.odb')

solidLaminateA(modelname='Lam1', L=100.0, b=100.0, laminate=lam1, esize=5, ex=0.01 )

Example

The result from the script as given, shows that the laminate twists when subjected to the uniform strain $\varepsilon_x$ as expected from the anti-symmetric layup.

Observe that the boundary conditions constrains the deformations for the faces at x = 0 and x = L such that they remain plane after deformation. That is not the case for the faces at y = 0 and y = b.

See also a modified and extended script in the example Laminate edge effects.

TOC Next Prev

Disclaimer:This site is designed for educational purposes only. There are most likely errors, mistakes, typos, and poorly crafted statements that are not detected yet... www.ntnu.edu/employees/nils.p.vedvik

Copyright 2024, All rights reserved