Beispiel #1
0
    def __init__(self,idx,nodelist=[]):
        self.index = idx
        self.nodes = nodelist[:]
        self.sfns = [qsf0,qsf1,qsf2,qsf3]
        self.dsfns = [[dqsf0d1,dqsf0d2],[dqsf1d1,dqsf1d2],
                      [dqsf2d1,dqsf2d2],[dqsf3d1,dqsf3d2]]
        for n in self.nodes:
            n.add_element(self)

        # Gauss-point-specific data.  Initialize plastic strain field
        # to be zero.
        self.gpdata = {}
        for p in self.gausspts():
            # Data are the local gamma, the six components of plastic
            # strain, and the six components of the yield surface
            # center.
            self.gpdata[p]=[0.0,
                            0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                            0.0, 0.0, 0.0, 0.0, 0.0, 0.0 ]

        # Use shape-functions directly to represent the stress.  The
        # shape functions are capable of representing lower-order
        # objects, so in principle this should not create any
        # difficulties, and is convenient.  They are only used on a
        # per-element basis, of course.
        mmtx = smallmatrix.SmallMatrix(4,4)
        rmtx = smallmatrix.SmallMatrix(4,4)
        mmtx.clear()
        rmtx.clear()
        for i in range(4):
            rmtx[i,i]=1.0 # Identity matrix.
            for j in range(4):
                res = 0.0
                for p in self.gausspts():
                    res += self.shapefn(i,p.xi,p.zeta)* \
                           self.shapefn(j,p.xi,p.zeta)* \
                           p.weight*self.jacobian(p.xi,p.zeta)
                mmtx[i,j]=res
        r = mmtx.solve(rmtx)
        if r!=0:
            print >> sys.stderr, \
                  "Element mass matrix is singular, run for the hills!"
        else:
            self.s_mtx = rmtx
Beispiel #2
0
def ycheck(cijkl,yld,stress):
    eps = 1.0e-10
    # Local return-mapping problem -- DOFs are, in order,
    # lambda, ep00,ep11,ep22,ep12,ep02,ep01 (voigt order).
    mtx = smallmatrix.SmallMatrix(7,7)
    rhs = smallmatrix.SmallMatrix(7,1)
    #
    ep = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    lmbda = 0.0
    #
    icount = 0
    while icount < 10:
        icount += 1
        lstress = [ [ stress[i][j]-sum([ sum([ cijkl[i][j][k][l]*ep[voigt[k][l]] for l in range(3) ]) for k in range(3) ]) for j in range(3) ] for i in range(3) ]

        mtx.clear()
        rhs.clear()
        
        # Build right-hand-side, check for zeroness.
        rhs[0,0] = -yld.yeeld(lstress)

        dy = yld.dyeeld(lstress)
        d2y = yld.d2yeeld(lstress)
        for i in range(3):
            for j in range(i+1):
                rhs[voigt[i][j]+1,0] = -lmbda*dy[i][j]+ep[voigt[i][j]]

        # print "\nRHS: ", [ rhs[i,0] for i in range(rhs.rows()) ]
        
        mag = sum( [ rhs[i,0]**2 for i in range(rhs.rows()) ] )
        if mag<eps:
            break # out of while loop.

        # Build matrix. 
        # First row, consistency equation.
        for k in range(3):
            for l in range(3):
                col = voigt[k][l]+1
                mtx[0,col] += sum([ sum([ -dy[i][j]*cijkl[i][j][k][l] 
                                          for j in range(3) ])
                                    for i in range(3) ])

        # Subsequent rows:
        for i in range(3):
            for j in range(i+1):
                row = voigt[i][j]+1
                # Column zero, easy.
                mtx[row,0]=dy[i][j]
                for m in range(3):
                    for n in range(3):
                        col = voigt[m][n]+1
                        diag = 0.0
                        if i==m and j==n:
                            diag = 1.0
                        mtx[row,col] += sum([ sum([ -lmbda*d2y[i][j][k][l]*cijkl[k][l][m][n] for l in range(3) ]) for k in range(3) ])-diag

        # Solve the resulting linearized system.
        # for mtxi in range(7):
        #     print [ mtx[mtxi,j] for j in range(7) ]
        rr = mtx.solve(rhs)
        if rr==0:
            # print "Increments: ", [ rhs[i,0] for i in range(7) ]
            lmbda += rhs[0,0]
            for i in range(6):
                ep[i] += rhs[i+1,0]
            # print "Soln: ", [lmbda] + [ep[i] for i in range(6)] 
        else:
            print >> sys.stderr, "Error in solving in ycheck, rr=", rr

    # Broke out of loop.
    return ep    
Beispiel #3
0
def ycheck(cijkl,yld,stress,center,gamma):
    eps = 1.0e-10
    # Local return-mapping problem -- DOFs are, in order,
    # lambda, ep00,ep11,ep22,ep12,ep02,ep01 (voigt order).
    mtx = smallmatrix.SmallMatrix(14,14)
    rhs = smallmatrix.SmallMatrix(14,1)
    #
    # The variables occur in this order.
    lmbda = 0.0
    dgamma = 0.0
    ep = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    dcenter = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    #
    icount = 0
    while icount < 100:
        icount += 1
        lstress = [ [ stress[i][j]-sum([ sum([ cijkl[i][j][k][l]*ep[voigt[k][l]] for l in range(3) ]) for k in range(3) ]) for j in range(3) ] for i in range(3) ]

        mtx.clear()
        rhs.clear()

        # Short for "current center"...
        ccenter = [ [ center[i][j]+dcenter[voigt[i][j]]
                      for j in range(3) ] for i in range(3) ]
        eptensor = [ [ ep[voigt[i][j]] for j in range(3) ]
                     for i in range(3) ]
        dy = yld.dyeeld(lstress,ccenter)
        flow = yld.flow(lstress,ccenter)
        dflow = yld.dflow(lstress,ccenter)

        ihard = yld.isohard(eptensor)
        dihard = yld.disohard(eptensor)

        khard = yld.khard(eptensor)
        dkhard = yld.dkhard(eptensor)
        
        # Build right-hand-side, check for zeroness.
        rhs[0,0] = -yld.yeeld(lstress,ccenter,gamma+dgamma)

        rhs[1,0] = -dgamma + ihard
        # rhs[1,0] = -dgamma + yld.iso_c*sq_epmag

      
        for i in range(3):
            for j in range(i+1):
                rhs[voigt[i][j]+2,0] = -lmbda*flow[i][j]+ep[voigt[i][j]]


        for i in range(3):
            for j in range(i+1):
                rhs[voigt[i][j]+8,0] = -dcenter[voigt[i][j]] + khard[i][j]
        # print "\nRHS: ", [ rhs[i,0] for i in range(rhs.rows()) ]
        
        mag = sum( [ rhs[i,0]**2 for i in range(rhs.rows()) ] )
        if mag<eps:
            break # out of while loop.

        # Build matrix. 
        # First row, consistency equation.
        mtx[0,1] = -1.0 # Derivative of yield function wrt delta-gamma.
        for k in range(3):
            for l in range(3):
                col = voigt[k][l]+2
                mtx[0,col] += sum([ sum([ -dy[i][j]*cijkl[i][j][k][l] 
                                          for j in range(3) ])
                                    for i in range(3) ])
                
                col = voigt[k][l]+8
                # Derivative of yield function wrt delta-c components.
                mtx[0,col] -= dy[k][l]
               
                                                      
        # Second row, isotropic hardening.  No dependence on ccenter.
        mtx[1,1]=1.0
        for k in range(3):
            for l in range(3):
                col = voigt[k][l]+2
                mtx[1,col] += -dihard[k][l]

                    
        # Third through eights rows, flow rule.
        for i in range(3):
            for j in range(i+1):
                row = voigt[i][j]+2
                # Column zero, easy.
                mtx[row,0]=dy[i][j]
                for m in range(3):
                    for n in range(3):
                        col = voigt[m][n]+2
                        diag = 0.0
                        if i==m and j==n:
                            diag = 1.0
                        mtx[row,col] += sum([ sum([ -lmbda*dflow[i][j][k][l]*cijkl[k][l][m][n] for l in range(3) ]) for k in range(3) ])-diag

                        col = voigt[m][n]+8
                        mtx[row,col] += -lmbda*dflow[i][j][m][n]

        # Ninth through fourteenth rows, kinematic hardening.
        for i in range(3):
            for j in range(i+1):
                row = voigt[i][j]+8
                mtx[row,row]=1.0 # Diagonal part, deriv wrt c's.
                # Component-wise match-up.
                for k in range(3):
                    for l in range(3):
                        col = voigt[k][l]+2
                        mtx[row,col] = -dkhard[i][j][k][l]
                

        # Solve the resulting linearized system.
        # for mtxi in range(8):
        #     print [ mtx[mtxi,j] for j in range(8) ]
        rr = mtx.solve(rhs)
        if rr==0:
            # print "Increments: ", [ rhs[i,0] for i in range(8) ]
            lmbda += rhs[0,0]
            dgamma += rhs[1,0]
            for i in range(6):
                ep[i] += rhs[i+2,0]
                dcenter[i] += rhs[i+8,0]
                
            # print "Soln: ", [lmbda, dgamma] + [ep[i] for i in range(6)] 
        else:
            print >> sys.stderr, "Error in solving in ycheck, rr=", rr

    else:
        print >> sys.stderr, "Error, ycheck loop did not converge."
    # Broke out of loop.
    return [dgamma]+ep+dcenter    
Beispiel #4
0
    def __init__(self,idx,nodelist=[]):
        self.index = idx
        self.nodes = nodelist[:]
        self.sfns = [qsf0,qsf1,qsf2,qsf3]
        self.dsfns = [[dqsf0d1,dqsf0d2],[dqsf1d1,dqsf1d2],
                      [dqsf2d1,dqsf2d2],[dqsf3d1,dqsf3d2]]
        for n in self.nodes:
            n.add_element(self)

        # Gauss-point-specific data.  Initialize plastic strain field
        # to be zero.
        self.gpdata = {}
        for p in self.gausspts():
            self.gpdata[p]=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

        # Use shape-functions directly to represent the stress.  The
        # shape functions are capable of representing lower-order
        # objects, so in principle this should not create any
        # difficulties, and is convenient.  They are only used on a
        # per-element basis, of course.
        mmtx = smallmatrix.SmallMatrix(4,4)
        rmtx = smallmatrix.SmallMatrix(4,4)
        mmtx.clear()
        rmtx.clear()
        for i in range(4):
            rmtx[i,i]=1.0 # Identity matrix.
            for j in range(4):
                res = 0.0
                for p in self.gausspts():
                    res += self.shapefn(i,p.xi,p.zeta)* \
                           self.shapefn(j,p.xi,p.zeta)* \
                           p.weight*self.jacobian(p.xi,p.zeta)
                mmtx[i,j]=res
        r = mmtx.solve(rmtx)
        if r!=0:
            print >> sys.stderr, \
                  "Element mass matrix is singular, run for the hills!"
        else:
            self.s_mtx = rmtx


        # G-matrix is indexed by triples, i,j,k, where i is the index
        # of the shape function, j is the index of the shape function
        # derivative, and k is the component of the derivative, for
        # which the entry is the integral over the element.

        self.g_mtx = [[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]],
                      [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]],
                      [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]],
                      [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]]

        for i in range(4):
            for j in range(4):
                for k in range(2):
                    res = 0.0
                    for p in self.gausspts():
                        res += self.shapefn(i,p.xi,p.zeta)* \
                               self.dshapefn(j,k,p.xi,p.zeta)* \
                               p.weight* \
                               self.jacobian(p.xi,p.zeta)
                    self.g_mtx[i][j][k] = res

        # Premultiply.
        self.sg_mtx = [[[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]],
                       [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]],
                       [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]],
                       [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]]

        for s in range(4):
            for j in range(4):
                for k in range(2):
                    for t in range(4):
                        self.sg_mtx[s][j][k] += self.s_mtx[s,t]*self.g_mtx[t][j][k]

        self.make_fmtx()