Flexural testing

(µ∩δeR Ɔonsτrµc†ioԥ)

Model-1a

The script was built partly on the script in Shell laminate.

See also video on relevant Blackboard site.

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

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, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori':  90, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori':  90, 'thi': 1.0},
        {'mat':'E-glass/Epoxy', 'ori':   0, 'thi': 1.0}]

def flex3p(modelname, L, b, dL, laminate, esize, U3):
    
    t = sum([layer['thi'] for layer in laminate])

    # 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)
     
    # planar shell:   
    ske = mod.ConstrainedSketch(name='__profile__', sheetSize=200.0)
    ske.rectangle(point1=(0.0, 0.0), point2=(L+2*dL, b))
    prt = mod.Part(name='Specimen', dimensionality=THREE_D, type=DEFORMABLE_BODY)
    prt.BaseShell(sketch=ske)
    del mod.sketches['__profile__']
    session.viewports['Viewport: 1'].setValues(displayedObject=prt)

    # Partitions:
    point1 = prt.InterestingPoint(edge=prt.edges.getByBoundingBox(xMax=0.0)[0], rule=MIDDLE)
    point2 = prt.InterestingPoint(edge=prt.edges.getByBoundingBox(xMin=L+2*dL)[0], rule=MIDDLE)
    prt.PartitionFaceByShortestPath(faces=prt.faces, point1=point1, point2=point2)
    point1 = prt.InterestingPoint(edge=prt.edges.getByBoundingBox(yMax=0.0)[0], rule=MIDDLE)
    point2 = prt.InterestingPoint(edge=prt.edges.getByBoundingBox(yMin=b)[0], rule=MIDDLE)
    prt.PartitionFaceByShortestPath(faces=prt.faces, point1=point1, point2=point2)

    id1=prt.DatumPlaneByPrincipalPlane(principalPlane=YZPLANE, offset=dL).id
    id2=prt.DatumPlaneByPrincipalPlane(principalPlane=YZPLANE, offset=dL+L).id
    faces = prt.faces.getByBoundingBox(xMax=dL+0.5*L)
    prt.PartitionFaceByDatumPlane(datumPlane=prt.datums[id1], faces=faces)
    faces = prt.faces.getByBoundingBox(xMin=dL+0.5*L)
    prt.PartitionFaceByDatumPlane(datumPlane=prt.datums[id2], faces=faces)
   
    # layup:
    id = prt.DatumCsysByDefault(coordSysType=CARTESIAN).id
    layupOrientation = prt.datums[id]
    region = regionToolset.Region(faces=prt.faces)
    compositeLayup = prt.CompositeLayup(name='Layup1', elementType=SHELL, offsetType=MIDDLE_SURFACE)
    compositeLayup.Section()
    compositeLayup.ReferenceOrientation(orientationType=SYSTEM, localCsys=layupOrientation, axis=AXIS_3)
    count = 1
    for layer in laminate:
        compositeLayup.CompositePly(suppressed=False, plyName='Ply-'+str(count), region=region, 
            material=layer['mat'], thicknessType=SPECIFY_THICKNESS, thickness=layer['thi'], 
            orientationType=SPECIFY_ORIENT, orientationValue=layer['ori'] )
        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)
    ass.translate(instanceList=('P1', ), vector=(-L/2.0-dL, -b/2.0, 0.0))

    # Boundary conditions:
    edges = ins.edges.findAt(((-L/2.0, -b/4.0, 0.0), ), ((-L/2.0, b/4.0, 0.0), ), 
        ((L/2.0, -b/4.0, 0.0), ), ((L/2.0, b/4.0, 0.0), ))
    region = ass.Set(edges=edges, name='edges-support')
    mod.DisplacementBC(name='BC-Support', createStepName='Initial', region=region, u3=SET)
    edges = ins.edges.findAt(((0.0, -b/4.0, 0.0), ), ((0.0, b/4.0, 0.0), ))
    region = ass.Set(edges=edges, name='edges-loading')
    mod.DisplacementBC(name='BC-Loading', createStepName='Initial', region=region, u3=SET )
    
    verts = ins.vertices.findAt(((0.0, -b/2.0, 0.0), ), ((0.0, b/2, 0.0), ))
    region = ass.Set(vertices=verts, name='vertices-rb1')
    mod.DisplacementBC(name='BC-RB1', createStepName='Initial', region=region, u1=SET)
    verts = ins.vertices.findAt(((0.0, 0.0, 0.0), ))
    region = ass.Set(vertices=verts, name='vertices-rb2')
    mod.DisplacementBC(name='BC-RB2', createStepName='Initial', region=region, u2=SET)
    
    # Step and loading:
    mod.StaticStep(name='Step-1', previous='Initial')
    mod.boundaryConditions['BC-Loading'].setValuesInStep(stepName='Step-1', u3=-U3)
    
    # Job and results:
    job=mdb.Job(name=modelname, model=modelname)
    job.submit(consistencyChecking=OFF)
    job.waitForCompletion()
    odb = session.openOdb(name=modelname+'.odb')
    
    session.viewports['Viewport: 1'].setValues(displayedObject=odb)
    session.viewports['Viewport: 1'].makeCurrent()
    session.viewports['Viewport: 1'].odbDisplay.display.setValues(plotState=(
        CONTOURS_ON_DEF, ))

    # Reaction forces at loading
    rfs = odb.steps['Step-1'].frames[-1].fieldOutputs['RF'].getSubset(
       region = odb.rootAssembly.nodeSets['EDGES-LOADING']).values

    rfsz = [rf.data[2] for rf in rfs]
    print 'Reaction force: {}'.format(sum(rfsz))

flex3p(modelname='M1', L=200, b=20, dL=10, laminate=lam1, esize=5, U3=10)

Model-1b

Extending Model-1a by including large deformation and extraction of both force and displacement as function of time:

Replace the last part of the previous script:

In [ ]:
    # Step and loading

    mod.StaticStep(name='Step-1', previous='Initial', initialInc=0.1, maxInc=0.1, nlgeom=ON)
    mod.boundaryConditions['BC-Loading'].setValuesInStep(stepName='Step-1', u3=-U3)
    
    # Job and results

    job=mdb.Job(name=modelname, model=modelname)
    job.submit(consistencyChecking=OFF)
    job.waitForCompletion()
    odb = session.openOdb(name=modelname+'.odb')
    
    session.viewports['Viewport: 1'].setValues(displayedObject=odb)
    session.viewports['Viewport: 1'].makeCurrent()
    session.viewports['Viewport: 1'].odbDisplay.display.setValues(plotState=(
        CONTOURS_ON_DEF, ))

    # Reaction forces at loading

    uz = []
    fz = []
    region = odb.rootAssembly.nodeSets['EDGES-LOADING']
    for frame in odb.steps['Step-1'].frames:
        rfs = frame.fieldOutputs['RF'].getSubset(region = region).values
        us = frame.fieldOutputs['U'].getSubset(region = region).values
        rfsum = sum([rf.data[2] for rf in rfs])
        u = us[0].data[2]
        uz.append(u)
        fz.append(rfsum)

    print 'uz:', uz
    print 'fz:', fz

Model-2

A model that includes discrete rigid sylinders as well as contact replacing the simple boundary conditions in the previous models:

(TODO)

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