Exemplo n.º 1
0
def runCalpyAnalysis(jobname=None,verbose=False,flavia=False):
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """

    ############################
    # Load the needed calpy modules    
    from plugins import calpy_itf
    calpy_itf.check()

    ## # Load development version
    #import sys
    #sys.path.insert(0,'/home/bene/prj/calpy')
    #print sys.path

    import calpy
    reload(calpy)
    print calpy.__path__
    
    calpy.options.optimize=True
    from calpy import femodel,fe_util,plane
    from calpy.arrayprint import aprint
    ############################

    checkWorkdir()

    if model is None:
        warn()
        return

    if jobname is None:
        # ask job name from user
        res = askItems([('JobName',feresult_name.peek()),('Verbose Mode',False)])
        if res:
            jobname = res['JobName']
            verbose = res['Verbose Mode']

    if not jobname:
        print "No Job Name: bailing out"
        return
   
    # OK, start calpy
    print "Starting the Calpy analysis module --- this might take some time"
    pf.app.processEvents()
    starttime = time.clock()

    calpyModel = femodel.FeModel(2,"elast","Plane_Stress")
    calpyModel.nnodes = model.coords.shape[0]
    calpyModel.nelems = model.celems[-1]
    print [ e.shape for e in model.elems ]
Exemplo n.º 2
0
def computeAveragedNodalStresses(M, data, gprule):
    """Compute averaged nodal stresses from GP stresses in 2D quad8 mesh"""

    ############################
    # Load the needed calpy modules
    from plugins import calpy_itf
    calpy_itf.check()

    gprule = (2, 2)  # integration rule: minimum (1,1),  maximum (5,5)
    Q = calpy_itf.QuadInterpolator(M.nelems(), M.nplex(), gprule)
    ngp = prod(gprule)  # number of datapoints per element
    print("Number of data points per element: %s" % ngp)
    print("Original element data: %s" % str(data.shape))
    # compute the data at the nodes, per element
    endata = Q.GP2Nodes(data)
    print("Element nodal data: %s" % str(endata.shape))
    # compute nodal averages
    nodata = Q.NodalAvg(M.elems + 1, endata, M.nnodes())
    print("Average nodal data: %s" % str(nodata.shape))
    # extract the colors per element

    return nodata
Exemplo n.º 3
0
def computeAveragedNodalStresses(M,data,gprule):
    """Compute averaged nodal stresses from GP stresses in 2D quad8 mesh"""


    ############################
    # Load the needed calpy modules
    from plugins import calpy_itf
    calpy_itf.check()

    gprule = (2,2) # integration rule: minimum (1,1),  maximum (5,5)
    Q = calpy_itf.QuadInterpolator(M.nelems(),M.nplex(),gprule)
    ngp = prod(gprule) # number of datapoints per element
    print("Number of data points per element: %s" % ngp)
    print("Original element data: %s" % str(data.shape))
    # compute the data at the nodes, per element
    endata = Q.GP2Nodes(data)
    print("Element nodal data: %s" % str(endata.shape))
    # compute nodal averages
    nodata = Q.NodalAvg(M.elems+1,endata,M.nnodes())
    print("Average nodal data: %s" % str(nodata.shape))
    # extract the colors per element

    return nodata
Exemplo n.º 4
0
def runCalpyAnalysis(jobname=None, verbose=False, flavia=False):
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """

    ############################
    # Load the needed calpy modules
    from plugins import calpy_itf

    calpy_itf.check()
    import calpy

    calpy.options.optimize = True
    from calpy import femodel, fe_util, plane
    from calpy.arrayprint import aprint

    ############################

    checkWorkdir()

    if model is None:
        warn()
        return

    if jobname is None:
        # ask job name from user
        res = askItems([("JobName", feresult_name.peek()), ("Verbose Mode", False)])
        if res:
            jobname = res["JobName"]
            verbose = res["Verbose Mode"]

    if not jobname:
        print "No Job Name: bailing out"
        return

    # OK, start calpy
    print "Starting the Calpy analysis module --- this might take some time"
    GD.app.processEvents()
    starttime = time.clock()

    calpyModel = femodel.FeModel(2, "elast", "Plane_Stress")
    calpyModel.nnodes = model.coords.shape[0]
    calpyModel.nelems = model.celems[-1]
    calpyModel.nnodel = 4

    # 2D model in calpy needs 2D coordinates
    coords = model.coords[:, :2]
    if verbose:
        fe_util.PrintNodes(coords)

    # Boundary conditions
    bcon = zeros((calpyModel.nnodes, 2), dtype=int32)
    bcon[:, 2:6] = 1  # leave only ux and uy
    for p in PDB.getProp(kind="n", attr=["bound"]):
        bnd = where(p.bound)[0]
        if p.set is None:
            nod = arange(calpyModel.nnodes)
        else:
            nod = array(p.set)
        for i in bnd:
            bcon[p.set, i] = 1
    fe_util.NumberEquations(bcon)
    if verbose:
        fe_util.PrintDofs(bcon, header=["ux", "uy"])

    # The number of free DOFs remaining
    calpyModel.ndof = bcon.max()
    print "Number of DOF's: %s" % calpyModel.ndof

    # We extract the materials/sections from the property database
    matprops = PDB.getProp(kind="e", attr=["section"])

    # E, nu, thickness, rho
    mats = array(
        [
            [mat.young_modulus, mat.poisson_ratio, mat.thickness, 0.0]  # rho was not defined in material
            for mat in matprops
        ]
    )
    calpyModel.nmats = mats.shape[0]
    if verbose:
        fe_util.PrintMats(mats, header=["E", "nu", "thick", "rho"])

    ########### Find number of load cases ############
    calpyModel.nloads = 1
    calpyModel.PrintModelData()
    ngp = 2
    nzem = 3
    calpyModel.banded = True

    # Create element definitions:
    # In calpy, each element is represented by nnod + 1 integer numbers:
    #    matnr,  node1, node2, ....
    # Also notice that Calpy numbering starts at 1, not at 0 as customary
    # in pyFormex; therefore we add 1 to elems.
    matnr = zeros(calpyModel.nelems, dtype=int32)
    for i, mat in enumerate(matprops):  # proces in same order as above!
        matnr[mat.set] = i + 1

    NodesGrp = []
    MatnrGrp = []
    PlaneGrp = []

    for i, e in enumerate(model.elems):
        j, k = model.celems[i : i + 2]
        Plane = plane.Quad("part-%s" % i, [ngp, ngp], calpyModel)
        Plane.debug = 0
        PlaneGrp.append(Plane)
        NodesGrp.append(e + 1)
        MatnrGrp.append(matnr[j:k])
        if verbose:
            fe_util.PrintElements(NodesGrp[-1], MatnrGrp[-1])

        # Plane.AddElements(e+1,matnr[j:k],mats,coords,bcon)

    for Plane, nodenrs, matnrs in zip(PlaneGrp, NodesGrp, MatnrGrp):
        Plane.AddElements(nodenrs, matnrs, mats, coords, bcon)

    # Create load vectors
    # Calpy allows for multiple load cases in a single analysis.
    # However, our script currently puts all loads together in a single
    # load case. So the processing hereafter is rather simple, especially
    # since Calpy provides a function to assemble a single concentrated
    # load into the load vector. We initialize the load vector to zeros
    # and then add all the concentrated loads from the properties database.
    # A single concentrated load consists of 6 components, corresponding
    # to the 6 DOFs of a node.
    #
    # AssembleVector takes 3 arguments: the global vector in which to
    # assemble a nodal vector (length ndof), the nodal vector values
    # (length 6), and a list of indices specifying the positions of the
    # nodal DOFs in the global vector.
    # Beware: The function does not change the global vector, but merely
    # returns the value after assembling.
    # Also notice that the indexing inside the bcon array uses numpy
    # convention (starting at 0), thus no adding 1 is needed!
    print "Assembling Concentrated Loads"
    calpyModel.nloads = 1
    f = zeros((calpyModel.ndof, calpyModel.nloads), float)
    for p in PDB.getProp("n", attr=["cload"]):
        if p.set is None:
            nodeset = range(calpyModel.nnodes)
        else:
            nodeset = p.set
        F = [0.0, 0.0]
        for i, v in p.cload:
            if i in [0, 1]:
                F[i] = v
        for n in nodeset:
            f[:, 0] = fe_util.AssembleVector(f[:, 0], F, bcon[n])

    print "Assembling distributed loads"
    # This is a bit more complex. See Calpy for details
    # We first generate the input data in a string, then read them with the
    # calpy femodel.ReadBoundaryLoads function and finally assemble them with
    # plane.addBoundaryLoads. We have to this operation per element group.
    # The group number is stored in the property record.
    ngroups = model.ngroups()
    s = [""] * ngroups
    nb = [0] * ngroups
    loadcase = 1
    for p in PDB.getProp("e", attr=["eload"]):
        xload = yload = 0.0
        if p.label == "x":
            xload = p.value
        elif p.label == "y":
            yload = p.value
        # Because of the way we constructed the database, the set will
        # contain only one element, but let's loop over it anyway in case
        # one day we make the storage more effective
        # Also, remember calpy numbers are +1 !
        g = p.group
        print "Group %s" % g
        for e in p.set:
            s[g] += "%s %s %s %s %s\n" % (e + 1, p.edge + 1, loadcase, xload, yload)
            nb[g] += 1
    # print s,nb
    for nbi, si, nodes, matnr, Plane in zip(nb, s, NodesGrp, MatnrGrp, PlaneGrp):
        if nbi > 0:
            idloads, dloads = fe_util.ReadBoundaryLoads(nbi, calpyModel.ndim, si)
            # print idloads,dloads
            Plane.AddBoundaryLoads(f, calpyModel, idloads, dloads, nodes, matnr, coords, bcon, mats)

    if verbose:
        print "Calpy.Loads"
        print f

    ############ Create global stiffness matrix ##########
    s = calpyModel.ZeroStiffnessMatrix(0)
    for elgrp in PlaneGrp:
        s = elgrp.Assemble(s, mats, calpyModel)
    # print "The complete stiffness matrix"
    # print s

    ############ Solve the system of equations ##########
    v = calpyModel.SolveSystem(s, f)
    print "Calpy analysis has finished --- Runtime was %s seconds." % (time.clock() - starttime)
    displ = fe_util.selectDisplacements(v, bcon)
    if verbose:
        print "Displacements", displ

    if flavia:
        flavia.WriteMeshFile(jobname, "Quadrilateral", model.nnodel, coord, nodes, matnr)
        res = flavia.ResultsFile(jobname)

    # compute stresses
    for l in range(calpyModel.nloads):

        print "Results for load case %d" % (l + 1)
        print "Displacements"
        aprint(displ[:, :, l], header=["x", "y"], numbering=True)

        if flavia:
            flavia.WriteResultsHeader(res, '"Displacement" "Elastic Analysis"', l + 1, "Vector OnNodes")
            flavia.WriteResults(res, displ[:, :, l])

        stresn = count = None
        i = 0
        for e, P in zip(model.elems, PlaneGrp):
            i += 1
            # P.debug = 1
            stresg = P.StressGP(v[:, l], mats)
            if verbose:
                print "elem group %d" % i
                print "GP Stress\n", stresg

            strese = P.GP2Nodes(stresg)
            if verbose:
                print "Nodal Element Stress\n", strese

            # print "Nodes",e+1
            stresn, count = P.NodalAcc(e + 1, strese, nnod=calpyModel.nnodes, nodata=stresn, nodn=count)
            # print stresn,count

        # print stresn.shape
        # print count.shape
        # print "TOTAL",stresn,count
        stresn /= count.reshape(-1, 1)
        # print "AVG",stresn
        if verbose:
            print "Averaged Nodal Stress\n"
            aprint(stresn, header=["sxx", "syy", "sxy"], numbering=True)

        if flavia:
            flavia.WriteResultsHeader(res, '"Stress" "Elastic Analysis"', l + 1, "Matrix OnNodes")
            flavia.WriteResults(res, stresn)

    DB = FeResult()
    DB.nodes = model.coords
    DB.nnodes = model.coords.shape[0]
    DB.nodid = arange(DB.nnodes)
    DB.elems = dict(enumerate(model.elems))
    DB.nelems = model.celems[-1]
    DB.Finalize()
    DB.data_size["S"] = 3
    # print DB.elems
    for lc in range(calpyModel.nloads):
        DB.Increment(lc, 0)
        d = zeros((calpyModel.nnodes, 3))
        d[:, :2] = displ[:, :, lc]
        DB.R["U"] = d
        DB.R["S"] = stresn
    postproc_menu.setDB(DB)
    name = feresult_name.next()
    export({name: DB})
    showInfo("The results have been exported as %s\nYou can now use the postproc menu to display results" % name)
##
## This file is part of pyFormex 0.5 Release Fri Aug 10 12:04:07 2007
## pyFormex is a Python implementation of Formex algebra
## Website: http://pyformex.berlios.de/
## Copyright (C) Benedict Verhegghe ([email protected]) 
##
## This program is distributed under the GNU General Public License
## version 2 or later (see file COPYING for details)
##
"""X-shaped truss analysis"""

############################
# Load the needed calpy modules    

from plugins import calpy_itf
calpy_itf.check()

from fe_util import *
from truss3d import *
############################

import time

###########################

linewidth(1.0)
clear()
from examples.X_truss import X_truss
bgcolor(lightgrey)

# create a truss (Vandepitte, Chapter 1, p.16)
Exemplo n.º 6
0
def runCalpyAnalysis():
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """

    ############################
    # Load the needed calpy modules    
    from plugins import calpy_itf
    calpy_itf.check()
    import calpy
    calpy.options.optimize=True
    from calpy import fe_util,beam3d
    ############################

    try:
        FE = named('fe_model')
##         print FE.keys()
##         nodes = FE.nodes
##         elems = FE.elems
##         prop = FE.prop
##         nodloads = FE.loads
##         botnodes = FE.botnodes
##         nsteps = FE.nsteps
    except:
        warning("I could not find the finite element model.\nMaybe you should try to create it first?")
        return
    
    # ask job name from user
    res = askItems([('JobName','hesperia_frame'),('Verbose Mode',False)])
    if not res:
        return

    jobname = res['JobName']
    if not jobname:
        print "No Job Name: bailing out"
        return
    verbose = res['Verbose Mode']
   
    nnod = FE.nodes.shape[0]
    nel = FE.elems.shape[0]
    print "Number of nodes: %s" % nnod
    print "Number of elements: %s" % nel

    # Create an extra node for beam orientations
    #
    # !!! This is ok for the support beams, but for the structural beams
    # !!! this should be changed to the center of the sphere !!!
    extra_node = array([[0.0,0.0,0.0]])
    coords = concatenate([FE.nodes,extra_node])
    nnod = coords.shape[0]
    print "Adding a node for orientation: %s" % nnod

    # We extract the materials/sections from the property database
    matprops = FE.prop.getProp(kind='e',attr=['section'])
    
    # Beam Properties in Calpy consist of 7 values:
    #   E, G, rho, A, Izz, Iyy, J
    # The beam y-axis lies in the plane of the 3 nodes i,j,k.
    mats = array([[mat.young_modulus,
                  mat.shear_modulus,
                  mat.density,
                  mat.cross_section,
                  mat.moment_inertia_11,
                  mat.moment_inertia_22,
                  mat.moment_inertia_12,
                  ] for mat in matprops]) 
    if verbose:
        print "Calpy.materials"
        print mats
    
    # Create element definitions:
    # In calpy, each beam element is represented by 4 integer numbers:
    #    i j k matnr,
    # where i,j are the node numbers,
    # k is an extra node for specifying orientation of beam (around its axis),
    # matnr refers to the material/section properties (i.e. the row nr in mats)
    # Also notice that Calpy numbering starts at 1, not at 0 as customary
    # in pyFormex; therefore we add 1 to elems.
    # The third node for all beams is the last (extra) node, numbered nnod.
    # We need to reshape tubeprops to allow concatenation
    matnr = zeros(nel,dtype=int32)
    for i,mat in enumerate(matprops):  # proces in same order as above!
        matnr[mat.set] = i+1
    elements = concatenate([FE.elems + 1,         # the normal node numbers
                            nnod * ones(shape=(nel,1),dtype=int), # extra node  
                            matnr.reshape((-1,1))],  # mat number
                           axis=1)
  
    if verbose:
        print "Calpy.elements"
        print elements

    # Boundary conditions
    # While we could get the boundary conditions from the node properties
    # database, we will formulate them directly from the numbers
    # of the supported nodes (botnodes).
    # Calpy (currently) only accepts boundary conditions in global
    # (cartesian) coordinates. However, as we only use fully fixed
    # (though hinged) support nodes, that presents no problem here.
    # For each supported node, a list of 6 codes can (should)be given,
    # corresponding to the six Degrees Of Freedom (DOFs): ux,uy,uz,rx,ry,rz.
    # The code has value 1 if the DOF is fixed (=0.0) and 0 if it is free.
    # The easiest way to set the correct boundary conditions array for Calpy
    # is to put these codes in a text field and have them read with
    # ReadBoundary.
    s = ""
    for n in FE.botnodes + 1:   # again, the +1 is to comply with Calpy numbering!
        s += "  %d  1  1  1  1  1  1\n" % n    # a fixed hinge
    # Also clamp the fake extra node
    s += "  %d  1  1  1  1  1  1\n" % nnod
    if verbose:
        print "Specified boundary conditions"
        print s
    bcon = fe_util.ReadBoundary(nnod,6,s)
    fe_util.NumberEquations(bcon)
    if verbose:
        print "Calpy.DOF numbering"
        print bcon # all DOFs are numbered from 1 to ndof

    # The number of free DOFs remaining
    ndof = bcon.max()
    print "Number of DOF's: %s" % ndof

    # Create load vectors
    # Calpy allows for multiple load cases in a single analysis.
    # However, our script currently puts all loads together in a single
    # load case. So the processing hereafter is rather simple, especially
    # since Calpy provides a function to assemble a single concentrated
    # load into the load vector. We initialize the load vector to zeros
    # and then add all the concentrated loads from the properties database.
    # A single concentrated load consists of 6 components, corresponding
    # to the 6 DOFs of a node.
    #
    # AssembleVector takes 3 arguments: the global vector in which to
    # assemble a nodal vector (length ndof), the nodal vector values
    # (length 6), and a list of indices specifying the positions of the
    # nodal DOFs in the global vector.
    # Beware: The function does not change the global vector, but merely
    # returns the value after assembling.
    # Also notice that the indexing inside the bcon array uses numpy
    # convention (starting at 0), thus no adding 1 is needed!
    print "Assembling Concentrated Loads"
    nlc = 1
    loads = zeros((ndof,nlc),float)
    for p in FE.prop.getProp('n',attr=['cload']):
        loads[:,0] = fe_util.AssembleVector(loads[:,0],p.cload,bcon[p.set,:])
    if verbose:
        print "Calpy.Loads"
        print loads
    # Perform analysis
    # OK, that is really everything there is to it. Now just run the
    # analysis, and hope for the best ;)
    # Enabling the Echo will print out the data.
    # The result consists of nodal displacements and stress resultants.
    print "Starting the Calpy analysis module --- this might take some time"
    GD.app.processEvents()
    starttime = time.clock()
    displ,frc = beam3d.static(coords,bcon,mats,elements,loads,Echo=True)
    print "Calpy analysis has finished --- Runtime was %s seconds." % (time.clock()-starttime)
    # Export the results, but throw way these for the extra (last) node
    export({'calpy_results':(displ[:-1],frc)})
Exemplo n.º 7
0
def runCalpyAnalysis(jobname=None,verbose=False,flavia=False):
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """

    ############################
    # Load the needed calpy modules    
    from plugins import calpy_itf
    calpy_itf.check()
    import calpy
    calpy.options.optimize=True
    from calpy import femodel,fe_util,plane
    from calpy.arrayprint import aprint
    ############################

    if model is None:
        warn()
        return

    if jobname is None:
        # ask job name from user
        res = askItems([('JobName','FeEx'),('Verbose Mode',False)])
        if res:
            jobname = res['JobName']
            verbose = res['Verbose Mode']

    if not jobname:
        print "No Job Name: bailing out"
        return
   
    # OK, start calpy
    print "Starting the Calpy analysis module --- this might take some time"
    GD.app.processEvents()
    starttime = time.clock()

    Model = femodel.FeModel(2,"elast","Plane_Stress")
    Model.nnodes = model.coords.shape[0]
    Model.nelems = model.celems[-1]
    Model.nnodel = 4

    # 2D model in calpy needs 2D coordinates
    coords = model.coords[:,:2]
    if verbose:
        fe_util.PrintNodes(coords)

    # Boundary conditions
    bcon = zeros((Model.nnodes,2),dtype=int32)
    bcon[:,2:6] = 1 # leave only ux and uy
    for p in PDB.getProp(kind='n',attr=['bound']):
        bnd = where(p.bound)[0]
        if p.set is None:
            nod = arange(Model.nnodes)
        else:
            nod = array(p.set)
        for i in bnd:
            bcon[p.set,i] = 1
    fe_util.NumberEquations(bcon)
    if verbose:
        fe_util.PrintDofs(bcon,header=['ux','uy'])

    # The number of free DOFs remaining
    Model.ndof = bcon.max()
    print "Number of DOF's: %s" % Model.ndof

    
    # We extract the materials/sections from the property database
    matprops = PDB.getProp(kind='e',attr=['section'])
    
    # E, nu, thickness, rho
    mats = array([[mat.young_modulus,
                   mat.poisson_ratio,
                   mat.thickness,
                   0.0,      # rho was not defined in material
                   ] for mat in matprops]) 
    Model.nmats = mats.shape[0]
    if verbose:
        fe_util.PrintMats(mats,header=['E','nu','thick','rho'])

   
    ########### Find number of load cases ############
    Model.nloads = 1
    Model.PrintModelData()
    ngp = 2
    nzem = 3
    Model.banded = True


    # Create element definitions:
    # In calpy, each element is represented by nnod + 1 integer numbers:
    #    matnr,  node1, node2, .... 
    # Also notice that Calpy numbering starts at 1, not at 0 as customary
    # in pyFormex; therefore we add 1 to elems.
    matnr = zeros(Model.nelems,dtype=int32)
    for i,mat in enumerate(matprops):  # proces in same order as above!
        matnr[mat.set] = i+1

    PlaneGrp = []
    
    for i,e in enumerate(model.elems):
        j,k = model.celems[i:i+2]
        Plane = plane.Quad("part-%s" % i,[ngp,ngp],Model)
        Plane.debug = 0
        fe_util.PrintElements(e+1,matnr[j:k])
        Plane.AddElements(e+1,matnr[j:k],mats,coords,bcon)
        PlaneGrp.append(Plane)

    # Create load vectors
    # Calpy allows for multiple load cases in a single analysis.
    # However, our script currently puts all loads together in a single
    # load case. So the processing hereafter is rather simple, especially
    # since Calpy provides a function to assemble a single concentrated
    # load into the load vector. We initialize the load vector to zeros
    # and then add all the concentrated loads from the properties database.
    # A single concentrated load consists of 6 components, corresponding
    # to the 6 DOFs of a node.
    #
    # AssembleVector takes 3 arguments: the global vector in which to
    # assemble a nodal vector (length ndof), the nodal vector values
    # (length 6), and a list of indices specifying the positions of the
    # nodal DOFs in the global vector.
    # Beware: The function does not change the global vector, but merely
    # returns the value after assembling.
    # Also notice that the indexing inside the bcon array uses numpy
    # convention (starting at 0), thus no adding 1 is needed!
    print "Assembling Concentrated Loads"
    Model.nloads = 1
    f = zeros((Model.ndof,Model.nloads),float)
    for p in PDB.getProp('n',attr=['cload']):
        if p.set is None:
            nodeset = range(Model.nnodes)
        else:
            nodeset = p.set
        F = [0.0,0.0]
        for i,v in p.cload:
            if i in [0,1]:
                F[i] = v
        for n in nodeset:
            print F
            print "HALLO"
            f[:,0] = fe_util.AssembleVector(f[:,0],F,bcon[n])

    print "Assembling distributed loads"
    # This is a bit more complex. See Calpy for details
    # We first generate the input data, then read them with the
    # calpy femodel.ReadBoundaryLoads function and finally
    # assemble them with plane.addBoundaryLoads.
    for p in PDB.getProp('n',attr=['dload']):
        print p
    #idloads,dloads = plane.ReadBoundaryLoads(*nb,model.ndim)
    
    if verbose:
        print "Calpy.Loads"
        print f

    ############ Create global stiffness matrix ##########
    s = Model.ZeroStiffnessMatrix(0)
    for elgrp in PlaneGrp:
        s = elgrp.Assemble(s,mats,Model)
    #print "The complete stiffness matrix"
    #print s
    print f
    v = Model.SolveSystem(s,f)
    if verbose:
        print "Displacements",v
    print "Calpy analysis has finished --- Runtime was %s seconds." % (time.clock()-starttime)
    displ = fe_util.selectDisplacements (v,bcon)
    print displ.shape
    if verbose:
        print displ

    if flavia:
        flavia.WriteMeshFile(jobname,"Quadrilateral",model.nnodel,coord,nodes,matnr)
        res=flavia.ResultsFile(jobname)
        
    # compute stresses
    for l in range(Model.nloads):
        
        print "Results for load case %d" %(l+1)
        print "Displacements"
        aprint(displ[:,:,l],header=['x','y'],numbering=True)

        if flavia:
            flavia.WriteResultsHeader(res,'"Displacement" "Elastic Analysis"',l+1,'Vector OnNodes')
            flavia.WriteResults(res,displ[:,:,l])
            
        stresn = count = None
        i = 0
        for e,P in zip(model.elems,PlaneGrp):
            i += 1
            #P.debug = 1
            stresg = P.StressGP (v[:,l],mats)
            if verbose:
                print "elem group %d" % i
                print "GP Stress\n", stresg
            
            strese = P.GP2Nodes(stresg)
            if verbose:
                print "Nodal Element Stress\n", strese

            #print "Nodes",e+1
            stresn,count = P.NodalAcc(e+1,strese,nnod=Model.nnodes,nodata=stresn,nodn=count)
            #print stresn,count
            
        #print stresn.shape
        #print count.shape
        #print "TOTAL",stresn,count
        stresn /= count.reshape(-1,1)
        #print "AVG",stresn
        if verbose:
            print "Averaged Nodal Stress\n"
            aprint(stresn,header=['sxx','syy','sxy'],numbering=True)
                
        if flavia:
            flavia.WriteResultsHeader(res,'"Stress" "Elastic Analysis"',l+1,'Matrix OnNodes')
            flavia.WriteResults(res,stresn)

    
    DB = FeResult()
    DB.nodes = model.coords
    DB.nnodes = model.coords.shape[0]
    DB.nodid = arange(DB.nnodes)
    DB.elems = dict(enumerate(model.elems))
    DB.nelems = model.celems[-1]
    DB.Finalize()
    DB.data_size['S'] = 3
    #print DB.elems
    for lc in range(Model.nloads):
        DB.Increment(lc,0)
        d = zeros((Model.nnodes,3))
        d[:,:2] = displ[:,:,lc]
        DB.R['U'] = d
        DB.R['S'] = stresn
    postproc_menu.setDB(DB)
    info("You can now use the postproc menu to display results")
    export({'FeResult':DB})
Exemplo n.º 8
0
def runCalpyAnalysis():
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """
    checkWorkdir()

    ############################
    # Load the needed calpy modules
    # You can prepend your own path here to override the installed calpy
    # sys.path[0:0] = ['/home/bene/prj/calpy']
    from plugins import calpy_itf
    calpy_itf.check()
    import calpy
    print(calpy)
    calpy.options.optimize = True
    from calpy import fe_util, beam3d
    ############################

    try:
        FE = named('fe_model')


##         print FE.keys()
##         nodes = FE.nodes
##         elems = FE.elems
##         prop = FE.prop
##         nodloads = FE.loads
##         botnodes = FE.botnodes
##         nsteps = FE.nsteps
    except:
        warning(
            "I could not find the finite element model.\nMaybe you should try to create it first?"
        )
        return

    # ask job name from user
    res = askItems([('JobName', 'hesperia_frame'), ('Verbose Mode', False)])
    if not res:
        return

    jobname = res['JobName']
    if not jobname:
        print("No Job Name: bailing out")
        return
    verbose = res['Verbose Mode']

    nnod = FE.nodes.shape[0]
    nel = FE.elems.shape[0]
    print("Number of nodes: %s" % nnod)
    print("Number of elements: %s" % nel)

    # Create an extra node for beam orientations
    #
    # !!! This is ok for the support beams, but for the structural beams
    # !!! this should be changed to the center of the sphere !!!
    extra_node = array([[0.0, 0.0, 0.0]])
    coords = concatenate([FE.nodes, extra_node])
    nnod = coords.shape[0]
    print("Adding a node for orientation: %s" % nnod)

    # We extract the materials/sections from the property database
    matprops = FE.prop.getProp(kind='e', attr=['section'])

    # Beam Properties in Calpy consist of 7 values:
    #   E, G, rho, A, Izz, Iyy, J
    # The beam y-axis lies in the plane of the 3 nodes i,j,k.
    mats = array([[
        mat.young_modulus,
        mat.shear_modulus,
        mat.density,
        mat.cross_section,
        mat.moment_inertia_11,
        mat.moment_inertia_22,
        mat.moment_inertia_12,
    ] for mat in matprops])
    if verbose:
        print("Calpy.materials")
        print(mats)

    # Create element definitions:
    # In calpy, each beam element is represented by 4 integer numbers:
    #    i j k matnr,
    # where i,j are the node numbers,
    # k is an extra node for specifying orientation of beam (around its axis),
    # matnr refers to the material/section properties (i.e. the row nr in mats)
    # Also notice that Calpy numbering starts at 1, not at 0 as customary
    # in pyFormex; therefore we add 1 to elems.
    # The third node for all beams is the last (extra) node, numbered nnod.
    # We need to reshape tubeprops to allow concatenation
    matnr = zeros(nel, dtype=int32)
    for i, mat in enumerate(matprops):  # proces in same order as above!
        matnr[mat.set] = i + 1
    elements = concatenate(
        [
            FE.elems + 1,  # the normal node numbers
            nnod * ones(shape=(nel, 1), dtype=int),  # extra node
            matnr.reshape((-1, 1))
        ],  # mat number
        axis=1)

    if verbose:
        print("Calpy.elements")
        print(elements)

    # Boundary conditions
    # While we could get the boundary conditions from the node properties
    # database, we will formulate them directly from the numbers
    # of the supported nodes (botnodes).
    # Calpy (currently) only accepts boundary conditions in global
    # (cartesian) coordinates. However, as we only use fully fixed
    # (though hinged) support nodes, that presents no problem here.
    # For each supported node, a list of 6 codes can (should)be given,
    # corresponding to the six Degrees Of Freedom (DOFs): ux,uy,uz,rx,ry,rz.
    # The code has value 1 if the DOF is fixed (=0.0) and 0 if it is free.
    # The easiest way to set the correct boundary conditions array for Calpy
    # is to put these codes in a text field and have them read with
    # ReadBoundary.
    s = ""
    for n in FE.botnodes + 1:  # again, the +1 is to comply with Calpy numbering!
        s += "  %d  1  1  1  1  1  1\n" % n  # a fixed hinge
    # Also clamp the fake extra node
    s += "  %d  1  1  1  1  1  1\n" % nnod
    if verbose:
        print("Specified boundary conditions")
        print(s)
    bcon = fe_util.ReadBoundary(nnod, 6, s)
    fe_util.NumberEquations(bcon)
    if verbose:
        print("Calpy.DOF numbering")
        print(bcon)  # all DOFs are numbered from 1 to ndof

    # The number of free DOFs remaining
    ndof = bcon.max()
    print("Number of DOF's: %s" % ndof)

    # Create load vectors
    # Calpy allows for multiple load cases in a single analysis.
    # However, our script currently puts all loads together in a single
    # load case. So the processing hereafter is rather simple, especially
    # since Calpy provides a function to assemble a single concentrated
    # load into the load vector. We initialize the load vector to zeros
    # and then add all the concentrated loads from the properties database.
    # A single concentrated load consists of 6 components, corresponding
    # to the 6 DOFs of a node.
    #
    # AssembleVector takes 3 arguments: the global vector in which to
    # assemble a nodal vector (length ndof), the nodal vector values
    # (length 6), and a list of indices specifying the positions of the
    # nodal DOFs in the global vector.
    # Beware: The function does not change the global vector, but merely
    # returns the value after assembling.
    # Also notice that the indexing inside the bcon array uses numpy
    # convention (starting at 0), thus no adding 1 is needed!
    print("Assembling Concentrated Loads")
    nlc = 1
    loads = zeros((ndof, nlc), float)
    for p in FE.prop.getProp('n', attr=['cload']):
        cload = zeros(6)
        for i, v in p.cload:
            cload[i] += v
        print(cload)
        print(cload.shape)
        loads[:, 0] = fe_util.AssembleVector(loads[:, 0], cload,
                                             bcon[p.set, :])
    if verbose:
        print("Calpy.Loads")
        print(loads)
    # Perform analysis
    # OK, that is really everything there is to it. Now just run the
    # analysis, and hope for the best ;)
    # Enabling the Echo will print out the data.
    # The result consists of nodal displacements and stress resultants.
    print("Starting the Calpy analysis module --- this might take some time")
    pf.app.processEvents()
    starttime = time.clock()
    displ, frc = beam3d.static(coords, bcon, mats, elements, loads, Echo=True)
    print("Calpy analysis has finished --- Runtime was %s seconds." %
          (time.clock() - starttime))
    # Export the results, but throw way these for the extra (last) node
    export({'calpy_results': (displ[:-1], frc)})
Exemplo n.º 9
0
def runCalpyAnalysis(jobname=None,verbose=False):
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """

    ############################
    # Load the needed calpy modules    
    from plugins import calpy_itf
    calpy_itf.check()
    import calpy
    calpy.options.optimize=True
    from calpy import femodel,fe_util,plane
    ############################

    if model is None:
        warn()
        return

    if jobname is None:
        # ask job name from user
        res = askItems([('JobName','FeEx'),('Verbose Mode',False)])
        if res:
            jobname = res['JobName']
            verbose = res['Verbose Mode']

    if not jobname:
        print "No Job Name: bailing out"
        return
   
    Model = femodel.FeModel(2,"elast","Plane_Stress")
    Model.nnodes = model.nodes.shape[0]
    Model.nelems = model.celems[-1]
    Model.nnodel = 4

    # 2D model in calpy needs 2D coordinates
    coords = model.nodes[:,:2]
    if verbose:
        fe_util.PrintNodes(coords)

    # Boundary conditions
    bcon = zeros((Model.nnodes,2),dtype=int32)
    bcon[:,2:6] = 1 # leave only ux and uy
    for p in PDB.getProp(kind='n',attr=['bound']):
        bnd = where(p.bound)[0]
        if p.set is None:
            nod = arange(Model.nnodes)
        else:
            nod = array(p.set)
        for i in bnd:
            bcon[p.set,i] = 1
    fe_util.NumberEquations(bcon)
    if verbose:
        fe_util.PrintDofs(bcon,header=['ux','uy'])

    # The number of free DOFs remaining
    Model.ndof = bcon.max()
    print "Number of DOF's: %s" % Model.ndof

    
    # We extract the materials/sections from the property database
    matprops = PDB.getProp(kind='e',attr=['section'])
    
    # E, nu, thickness, rho
    mats = array([[mat.young_modulus,
                   mat.poisson_ratio,
                   mat.thickness,
                   0.0,      # rho was not defined in material
                   ] for mat in matprops]) 
    Model.nmats = mats.shape[0]
    if verbose:
        fe_util.PrintMats(mats,header=['E','nu','thick','rho'])

   
    ########### Find number of load cases ############
    Model.nloads = 1
    Model.PrintModelData()
    ngp = 2
    nzem = 3
    Model.banded = True


    # Create element definitions:
    # In calpy, each element is represented by nnod + 1 integer numbers:
    #    matnr,  node1, node2, .... 
    # Also notice that Calpy numbering starts at 1, not at 0 as customary
    # in pyFormex; therefore we add 1 to elems.
    matnr = zeros(Model.nelems,dtype=int32)
    for i,mat in enumerate(matprops):  # proces in same order as above!
        matnr[mat.set] = i+1

    PlaneGrp = []
    
    for i,e in enumerate(model.elems):
        j,k = model.celems[i:i+2]
        Plane = plane.Quad("part-%s" % i,[ngp,ngp],Model)
        Plane.debug = 0
        fe_util.PrintElements(e+1,matnr[j:k])
        Plane.AddElements(e+1,matnr[j:k],mats,coords,bcon)
        PlaneGrp.append(Plane)
    # Create load vectors
    # Calpy allows for multiple load cases in a single analysis.
    # However, our script currently puts all loads together in a single
    # load case. So the processing hereafter is rather simple, especially
    # since Calpy provides a function to assemble a single concentrated
    # load into the load vector. We initialize the load vector to zeros
    # and then add all the concentrated loads from the properties database.
    # A single concentrated load consists of 6 components, corresponding
    # to the 6 DOFs of a node.
    #
    # AssembleVector takes 3 arguments: the global vector in which to
    # assemble a nodal vector (length ndof), the nodal vector values
    # (length 6), and a list of indices specifying the positions of the
    # nodal DOFs in the global vector.
    # Beware: The function does not change the global vector, but merely
    # returns the value after assembling.
    # Also notice that the indexing inside the bcon array uses numpy
    # convention (starting at 0), thus no adding 1 is needed!
    print "Assembling Concentrated Loads"
    Model.nloads = 1
    f = zeros((Model.ndof,Model.nloads),float)
    print f.shape
    for p in PDB.getProp('n',attr=['cload']):
        if p.set is None:
            nodeset = range(Model.nnodes)
        else:
            nodeset = p.set
        for n in nodeset:
            print p.cload[:2]
            print
            f[:,0] = fe_util.AssembleVector(f[:,0],p.cload[:2],bcon[n])
    if verbose:
        print "Calpy.Loads"
        print f
    # Perform analysis
    # OK, that is really everything there is to it. Now just run the
    # analysis, and hope for the best ;)
    # Enabling the Echo will print out the data.
    # The result consists of nodal displacements and stress resultants.
    print "Starting the Calpy analysis module --- this might take some time"
    GD.app.processEvents()
    starttime = time.clock()
    ############ Create global stiffness matrix ##########
    s = Model.ZeroStiffnessMatrix(0)
    for elgrp in PlaneGrp:
        s = elgrp.Assemble(s,mats,Model)
    #print "The complete stiffness matrix"
    #print s
    print f
    v = Model.SolveSystem(s,f)
    print "Displacements",v
    print "Calpy analysis has finished --- Runtime was %s seconds." % (time.clock()-starttime)
    displ = fe_util.selectDisplacements (v,bcon)
    print displ.shape
    print displ
    
    DB = FeResult()
    DB.nodes = model.nodes
    DB.nnodes = model.nodes.shape[0]
    DB.nodid = arange(DB.nnodes)
    DB.elems = dict(enumerate(model.elems))
    DB.nelems = model.celems[-1]
    DB.Finalize()
    print DB.elems
    for lc in range(Model.nloads):
        DB.Increment(lc,0)
        d = zeros((Model.nnodes,3))
        d[:,:2] = displ[:,:,lc]
        DB.R['U'] = d
    postproc_menu.setDB(DB)
    info("You can now use the postproc menu to display results")
    export({'FeResult':DB})
Exemplo n.º 10
0
def runCalpyAnalysis(jobname=None,verbose=False,flavia=False):
    """Create data for Calpy analysis module and run Calpy on the data.

    While we could write an analysis file in the Calpy format and then
    run the Calpy program on it (like we did with Abaqus), we can (and do)
    take another road here: Calpy has a Python/numpy interface, allowing
    us to directly present the numerical data in arrays to the analysis
    module.
    It is supposed that the Finite Element model has been created and
    exported under the name 'fe_model'.
    """

    ############################
    # Load the needed calpy modules    
    from plugins import calpy_itf
    calpy_itf.check()

    ## # Load development version
    #import sys
    #sys.path.insert(0,'/home/bene/prj/calpy')
    #print sys.path

    import calpy
    reload(calpy)
    print(calpy.__path__)
    
    calpy.options.optimize=True
    from calpy import femodel,fe_util,plane
    from calpy.arrayprint import aprint
    ############################

    checkWorkdir()

    if model is None:
        warn()
        return

    if jobname is None:
        # ask job name from user
        res = askItems([('JobName',feresult_name.peek()),('Verbose Mode',False)])
        if res:
            jobname = res['JobName']
            verbose = res['Verbose Mode']

    if not jobname:
        print("No Job Name: bailing out")
        return
   
    # OK, start calpy
    print("Starting the Calpy analysis module --- this might take some time")
    pf.app.processEvents()
    starttime = time.clock()

    calpyModel = femodel.FeModel(2,"elast","Plane_Stress")
    calpyModel.nnodes = model.coords.shape[0]
    calpyModel.nelems = model.celems[-1]
    print([ e.shape for e in model.elems ])
    nplex = [ e.shape[1] for e in model.elems ]
    if min(nplex) != max(nplex):
        warning("All parts should have same element type")
        return
    
    calpyModel.nnodel = nplex[0]

    # 2D model in calpy needs 2D coordinates
    coords = model.coords[:,:2]
    if verbose:
        fe_util.PrintNodes(coords)

    # Boundary conditions
    bcon = zeros((calpyModel.nnodes,2),dtype=int32)
    bcon[:,2:6] = 1 # leave only ux and uy
    for p in PDB.getProp(kind='n',attr=['bound']):
        bnd = where(p.bound)[0]
        if p.set is None:
            nod = arange(calpyModel.nnodes)
        else:
            nod = array(p.set)
        for i in bnd:
            bcon[p.set,i] = 1
    fe_util.NumberEquations(bcon)
    if verbose:
        fe_util.PrintDofs(bcon,header=['ux','uy'])

    # The number of free DOFs remaining
    calpyModel.ndof = bcon.max()
    print("Number of DOF's: %s" % calpyModel.ndof)

    
    # We extract the materials/sections from the property database
    secprops = PDB.getProp(kind='e',attr=['section'])
    
    # E, nu, thickness, rho
    mats = array([[mat.young_modulus,
                   mat.poisson_ratio,
                   mat.thickness,
                   0.0,      # rho was not defined in material
                   ] for mat in secprops]) 
    calpyModel.nmats = mats.shape[0]
    if verbose:
        fe_util.PrintMats(mats,header=['E','nu','thick','rho'])

   
    ########### Find number of load cases ############
    calpyModel.nloads = nsteps
    calpyModel.PrintModelData()
    ngp = 2
    nzem = 3
    calpyModel.banded = True


    # Create element definitions:
    # In calpy, each element is represented by nnod + 1 integer numbers:
    #    matnr,  node1, node2, .... 
    # Also notice that Calpy numbering starts at 1, not at 0 as customary
    # in pyFormex; therefore we add 1 to elems.
    matnr = zeros(calpyModel.nelems,dtype=int32)
    for i,mat in enumerate(secprops):  # proces in same order as above!
        matnr[mat.set] = i+1

    NodesGrp = []
    MatnrGrp = []
    PlaneGrp = []

    for i,e in enumerate(model.elems):
        j,k = model.celems[i:i+2]
        Plane = plane.Quad("part-%s" % i,[ngp,ngp],calpyModel)
        Plane.debug = 0
        PlaneGrp.append(Plane)
        NodesGrp.append(e+1)
        MatnrGrp.append(matnr[j:k])
        if verbose:
            fe_util.PrintElements(NodesGrp[-1],MatnrGrp[-1])

        #Plane.AddElements(e+1,matnr[j:k],mats,coords,bcon)
        
    for Plane,nodenrs,matnrs in zip(PlaneGrp,NodesGrp,MatnrGrp):
        Plane.AddElements(nodenrs,matnrs,mats,coords,bcon)

    # Create load vectors
    # Calpy allows for multiple load cases in a single analysis.
    # However, our script currently puts all loads together in a single
    # load case. So the processing hereafter is rather simple, especially
    # since Calpy provides a function to assemble a single concentrated
    # load into the load vector. We initialize the load vector to zeros
    # and then add all the concentrated loads from the properties database.
    # A single concentrated load consists of 6 components, corresponding
    # to the 6 DOFs of a node.
    #
    # AssembleVector takes 3 arguments: the global vector in which to
    # assemble a nodal vector (length ndof), the nodal vector values
    # (length 6), and a list of indices specifying the positions of the
    # nodal DOFs in the global vector.
    # Beware: The function does not change the global vector, but merely
    # returns the value after assembling.
    # Also notice that the indexing inside the bcon array uses numpy
    # convention (starting at 0), thus no adding 1 is needed!
    print("Assembling Concentrated Loads")
    f = zeros((calpyModel.ndof,calpyModel.nloads),float)
    for p in PDB.getProp('n',attr=['cload']):
        lc = loadcaseFromTag(p)-1  # calpy loadcases start from 0
        if p.set is None:
            nodeset = range(calpyModel.nnodes)
        else:
            nodeset = p.set
        F = [0.0,0.0]
        for i,v in p.cload:
            if i in [0,1]:
                F[i] = v
        for n in nodeset:
            f[:,lc] = fe_util.AssembleVector(f[:,lc],F,bcon[n])

    print("Assembling distributed loads")
    # This is a bit more complex. See Calpy for details
    # We first generate the input data in a string, then read them with the
    # calpy femodel.ReadBoundaryLoads function and finally assemble them with
    # plane.addBoundaryLoads. We have to do this operation per element group.
    # The group number is stored in the property record.
    ngroups = model.ngroups()
    s = [ "" ] * ngroups
    nb = [ 0 ] * ngroups
    for p in PDB.getProp('e',attr=['eload']):
        lc = loadcaseFromTag(p)-1  # calpy loadcases start from 0
        xload = yload = 0.
        if p.label == 'x':
            xload = p.value
        elif p.label == 'y':
            yload = p.value
        # Because of the way we constructed the database, the set will
        # contain only one element, but let's loop over it anyway in case
        # one day we make the storage more effective
        # Also, remember calpy numbers are +1 !
        g = p.group
        print("Group %s" % g)
        for e in p.set:
            s[g] += "%s %s %s %s %s\n" % (e+1,p.edge+1,lc,xload,yload)
            nb[g] += 1
    #print s,nb
    for nbi,si,nodes,matnr,Plane in zip(nb,s,NodesGrp,MatnrGrp,PlaneGrp):
        if nbi > 0:
            idloads,dloads = fe_util.ReadBoundaryLoads(nbi,calpyModel.ndim,si)
            #print idloads,dloads
            Plane.AddBoundaryLoads(f,calpyModel,idloads,dloads,nodes,matnr,coords,bcon,mats)
    
    if verbose:
        print("Calpy.Loads")
        print(f)

    ############ Create global stiffness matrix ##########
    s = calpyModel.ZeroStiffnessMatrix(0)
    for elgrp in PlaneGrp:
        s = elgrp.Assemble(s,mats,calpyModel)
    # print "The complete stiffness matrix"
    # print s

    ############ Solve the system of equations ##########
    v = calpyModel.SolveSystem(s,f)
    print("Calpy analysis has finished --- Runtime was %s seconds." % (time.clock()-starttime))
    displ = fe_util.selectDisplacements (v,bcon)
    if verbose:
        print("Displacements",displ)

    if flavia:
        flavia.WriteMeshFile(jobname,"Quadrilateral",model.nnodel,coord,nodes,matnr)
        res=flavia.ResultsFile(jobname)
        
    # compute stresses
    for lc in range(calpyModel.nloads):
        
        print("Results for load case %d" %(lc+1))
        print("Displacements")
        aprint(displ[:,:,lc],header=['x','y'],numbering=True)

        if flavia:
            flavia.WriteResultsHeader(res,'"Displacement" "Elastic Analysis"',lc+1,'Vector OnNodes')
            flavia.WriteResults(res,displ[:,:,lc])
            
        stresn = count = None
        i = 0
        for e,P in zip(model.elems,PlaneGrp):
            i += 1
            #P.debug = 1
            stresg = P.StressGP (v[:,lc],mats)
            if verbose:
                print("elem group %d" % i)
                print("GP Stress\n", stresg)
            
            strese = P.GP2Nodes(stresg)
            if verbose:
                print("Nodal Element Stress\n", strese)

            #print "Nodes",e+1
            stresn,count = P.NodalAcc(e+1,strese,nnod=calpyModel.nnodes,nodata=stresn,nodn=count)
            #print stresn,count
            
        #print stresn.shape
        #print count.shape
        #print "TOTAL",stresn,count
        stresn /= count.reshape(-1,1)
        #print "AVG",stresn
        if verbose:
            print("Averaged Nodal Stress\n")
            aprint(stresn,header=['sxx','syy','sxy'],numbering=True)
                
        if flavia:
            flavia.WriteResultsHeader(res,'"Stress" "Elastic Analysis"',lc+1,'Matrix OnNodes')
            flavia.WriteResults(res,stresn)

    
    DB = FeResult()
    DB.nodes = model.coords
    DB.nnodes = model.coords.shape[0]
    DB.nodid = arange(DB.nnodes)
    DB.elems = dict(enumerate(model.elems))
    DB.nelems = model.celems[-1]
    DB.Finalize()
    DB.datasize['S'] = 3
    #print DB.elems
    for lc in range(calpyModel.nloads):
        DB.Increment(lc,0)
        d = zeros((calpyModel.nnodes,3))
        d[:,:2] = displ[:,:,lc]
        DB.R['U'] = d
        DB.R['S'] = stresn
    postproc_menu.setDB(DB)
    name = feresult_name.next()
    export({name:DB})

    print("STEPS:",DB.getSteps())
    print("INCS:",DB.getIncs(DB.getSteps()[0]))

    if showInfo("The results have been exported as %s\nYou can now use the postproc menu to display results" % name,actions=['Cancel','OK']) == 'OK':
        postproc_menu.selection.set(name)
        postproc_menu.selectDB(DB)
        postproc_menu.open_dialog()