Beispiel #1
0
 def createDisp(self):
     # trial , committed, incr = (committed-trial)
     self.disp = np.zeros(4 * self.numberDOF)
     # 按照储存顺序
     self.trialDisp = Vector(self.numberDOF, self.disp[0:self.numberDOF])
     self.commitDisp = Vector(self.numberDOF,
                              self.disp[self.numberDOF:2 * self.numberDOF])
     self.incrDisp = Vector(
         self.numberDOF, self.disp[2 * self.numberDOF:3 * self.numberDOF])
     self.incrDeltaDisp = Vector(self.numberDOF,
                                 self.disp[3 * self.numberDOF:-1])
     return 0
Beispiel #2
0
    def __init__(self, tag, ndof, *Crd):
        DomainComponent.__init__(self, tag, Node.NOD_TAG_Node)
        self.numberDOF = ndof  # number of dof at Node
        self.theDOF_Group = None  # pointer to associated DOF_Group

        self.Crd = Vector(len(Crd))  # Crd是可变参数,接收到的是一个 tuple
        for i in range(0, len(Crd)):
            self.Crd[i] = Crd[i]

        self.commitDisp = None
        self.commitVel = None
        self.commitAccel = None

        self.trialDisp = None
        self.trialVel = None
        self.trialAccel = None

        self.unbalLoad = None  # unbalanced load
        self.incrDisp = None
        self.incrDeltaDisp = None

        # double arrays holding the disp, vel and accel value
        # 对应 np.narray
        self.disp = None
        self.vel = None
        self.accel = None

        self.R = None  # nodal participation matrix
        self.mass = None  # mass matrix
        self.unbalLoadWithInertia = None
        self.alphaM = 0  # rayleigh damping factor
        self.theEigenvectors = None

        self.reaction = None
        self.displayLocation = None
Beispiel #3
0
    def __init__(self):
        self.theElements = MapOfTaggedObjects()
        self.theNodes = MapOfTaggedObjects()
        self.theSPs = MapOfTaggedObjects()
        self.theMPs = MapOfTaggedObjects()
        self.thePCs = MapOfTaggedObjects()
        self.theLoadPatterns = MapOfTaggedObjects()
        self.theParameters = MapOfTaggedObjects()

        self.currentTime = 0.0  # current pseudo time
        self.committedTime = 0.0  # the committed pseudo time
        self.dT = 0.0  # difference between committed and current time

        self.currentGeoTag = 0  # an integer used mark if domain has changed
        self.hasDomainChangedFlag = False  # a bool flag used to indicate if GeoTag needs to be ++
        self.lastGeoSendTag = -1  # the value of currentGeoTag when sendSelf was last invoked

        self.nodeGraphBuiltFlag = False
        self.eleGraphBuiltFlag = False

        self.theBounds = Vector(6)
        self.theBounds[0] = 0  # x min
        self.theBounds[1] = 0  # y min
        self.theBounds[2] = 0  # z min
        self.theBounds[3] = 0  # x max
        self.theBounds[4] = 0  # y max
        self.theBounds[5] = 0  # z max
Beispiel #4
0
 def getTangForce(self, disp, fact=1.0):
     if self.myEle != None:
         # zero out the force vector
         self.theResidual.Zero()
         # check for a quick return
         if fact == 0.0:
             return self.theResidual
         # get the component we need out of the vector and place in a temporary vector
         tmp = Vector(self.numDOF)
         for i in range(0, self.numDOF):
             dof = self.myID[i]
             if dof >= 0:
                 tmp[i] = disp[dof]
             else:
                 tmp[i] = 0.0
         # form the tangent again and then add the force
         self.theIntegrator.formEleTangent(self)
         if self.theResidual.addMatrixVector(1.0, self.theTangent, tmp,
                                             fact) < 0:
             print(
                 'WARNING FE_Element::getTangForce() - addMatrixVector returned error.\n'
             )
         return self.theResidual
     else:
         print('WARNING FE_Element::addTangForce() - no Element *given.\n')
         return FE_Element.errVector
Beispiel #5
0
    def setSize(self, theGraph):
        result = 0
        oldSize = self.size
        self.size = theGraph.getNumVertex() # 几何上的节点数 = 方程数
        # 求半带宽(包括对角线)
        self.half_band = 0
        theVertices = theGraph.getVertices()
        for tag, vertex in theVertices:
            vertexNum = vertex.getTag()
            theAdjacency = vertex.getAdjacency()
            for i in range(0, theAdjacency.Size()):
                otherNum = theAdjacency[i]
                diff = vertexNum - otherNum # 不用加绝对值吗? 可能theAdjacency只储存了节点号比本身小的
                if(self.half_band < diff):
                    self.half_band = diff
        self.half_band += 1 # include the diagonal

        self.A = np.zeros((self.half_band,self.size), dtype=float) # rank-2 array
        self.Asize = self.half_band * self.size
        self.factored = False

        self.B = np.zeros(self.size, dtype=float)
        self.X = np.zeros(self.size, dtype=float)
        
        self.vectX = Vector(self.X, self.size)
        self.vectB = Vector(self.B, self.size)

        self.Bsize = self.size #???
        
        # invoke setSize() on the Solver
        theSolver = self.getSolver()
        # 因为theSolver.setSize() do nothing
        # solverOK = theSolver.setSize()
        # if solverOK<0:
        #     print('WARNING: BandSPDLinSOE::setSize() - solver failed setSize().\n')
        #     return solverOK

        return result
Beispiel #6
0
 def addKg_Force(self, disp, fact=1.0):
     if self.myEle != None:
         if fact == 0.0:
             return
         tmp = Vector(self.numDOF)
         for i in range(0, self.numDOF):
             loc = self.myID[i]
             if loc >= 0:
                 tmp[i] = disp[loc]
             else:
                 tmp[i] = 0.0
         if self.theResidual.addMatrixVector(
                 1.0, self.myEle.getGeometricTangentStiff(), tmp, fact) < 0:
             print(
                 'WARNING FE_Element::addKg_Force() - addMatrixVector returned error.\n'
             )
     else:
         print('WARNING FE_Element::addKg_Force() - no Element *given.\n')
Beispiel #7
0
 def getKi_Force(self, disp, fact=1.0):
     if self.myEle != None:
         self.theResidual.Zero()
         if fact == 0.0:
             return self.theResidual
         tmp = Vector(self.numDOF)
         for i in range(0, self.numDOF):
             dof = self.myID[i]
             if dof >= 0:
                 tmp[i] = disp[dof]
             else:
                 tmp[i] = 0.0
         if self.theResidual.addMatrixVector(
                 1.0, self.myEle.getInitialStiff(), tmp, fact) < 0:
             print(
                 'WARNING FE_Element::getKForce() - addMatrixVector returned error.\n'
             )
         return self.theResidual
     else:
         print('WARNING FE_Element::getKForce() - no Element *given.\n')
         return FE_Element.errVector
Beispiel #8
0
 def createVel(self):
     self.vel = np.zeros(2 * self.numberDOF)
     self.trialVel = Vector(self.numberDOF, self.vel[0:self.numberDOF])
     self.commitVel = Vector(self.numberDOF,
                             self.vel[self.numberDOF:2 * self.numberDOF])
     return 0
Beispiel #9
0
class DOF_Group(TaggedObject):
    # static variables - single copy for all objects of the class
    numDOFs = 0
    errVect = Vector(1)

    def __init__(self, tag, node):
        super().__init__(tag)  # tag 从0开始

        # protected variables - a copy for each object of the class
        self.unbalance = None
        self.tangent = None
        self.myNode = node

        # private variables - a copy for each object of the class
        self.myID = np.zeros((node.getNumberDOF(), ), dtype=int)
        self.numDOF = node.getNumberDOF()

        # get number of DOF & verify valid
        numDOF = node.getNumberDOF()
        if (numDOF <= 0):
            print('DOF_Group::DOF_Group() - node must have at least 1 dof. \n')

        # initially set all the IDs to be -2
        for i in range(0, numDOF):
            self.myID[i] = -2

        # if this is the first DOF_Group, we now create the arrays used to store pointers to
        # class wide matrix and vector objects used to return tangent and residual

        DOF_Group.numDOFs += 1

    def setID(self, index, value):  # 有重载,复制函数
        if index >= 0 and index <= self.numDOF:
            self.myID[index] = value
        else:
            print('WARNING DOF_Group::setID - invalid location ' + str(index) +
                  ' in ID of size ' + str(self.numDOF) + '.\n')

    def getID(self):
        return self.myID

    def doneID(self):
        return 0  # 有鬼用

    def getNodeTag(self):
        if self.myNode != None:
            return self.myNode.getTag()
        else:
            return -1

    def getNumDOF(self):
        return self.numDOF

    def getNumFreeDOF(self):
        numFreeDOF = self.numDOF
        for i in range(0, self.numDOF):
            if self.myID[i] == -1 or self.myID[i] == -4:
                numFreeDOF -= 1
        return numFreeDOF

    def getNumConstrainedDOF(self):
        numConstr = 0
        for i in range(0, self.numDOF):
            if self.myID[i] < 0:
                numConstr += 1
        return numConstr

    # methods to form the tangent
    def getTangent(self, theIntegrator):  # 不call还写出来干嘛?
        if theIntegrator != None:
            theIntegrator.formNodTangent(
                self
            )  # StaticIntegrator::formNodTangent() - this method should never have been called!
        return self.tangent  # is Matrix

    def zeroTangent(self):
        self.tangent.Zero()

    def addMtoTang(self, fact=1.0):
        pass

    def addCtoTang(self, fact=1.0):
        pass

    # methods to form the unbalance
    def getUnbalance(self, theIntegrator):
        if theIntegrator != None:
            theIntegrator.formNodUnbalance(self)
        return self.unbalance  # is Vector

    def zeroUnbalance(self):
        self.unbalance.Zero()

    def addPtoUnbalance(self, fact=1.0):
        if self.myNode != None:
            if self.unbalance.addVector(1.0, self.myNode.getUnbalancedLoad(),
                                        fact) < 0:
                print(
                    'DOF_Group::addPIncInertiaToUnbalance() - invoking addVector() on the unbalance failed.\n'
                )
        else:
            print(
                'DOF_Group::addPtoUnbalance() - no Node associated. Subclass should provide the method.\n'
            )

    def addPIncInertiaToUnbalance(self, fact=1.0):
        pass

    def addM_Force(self, udotdot, fact=1.0):
        pass

    def getTangForce(self, x, fact=1.0):
        pass

    def getC_Force(self, x, fact=1.0):
        pass

    def getM_Force(self, x, fact=1.0):
        pass

    # methods to obtain committed responses from the nodes
    def getCommittedDisp(self):
        if self.myNode == None:
            print(
                'DOF_Group::getCommittedDisp: no associated Node, returning the error Vector.\n'
            )
            return DOF_Group.errVect
        return self.myNode.getDisp()

    def getCommittedVel(self):
        if self.myNode == None:
            print(
                'DOF_Group::getCommittedVel: no associated Node, returning the error Vector.\n'
            )
            return DOF_Group.errVect
        return self.myNode.getVel()

    def getCommittedAccel(self):
        if self.myNode == None:
            print(
                'DOF_Group::getCommittedAccel: no associated Node, returning the error Vector.\n'
            )
            return DOF_Group.errVect
        return self.myNode.getAccel()

    # methods to update the trial response at the nodes
    def setNodeDisp(self, u):
        # u is Vector
        if self.myNode == None:
            print('DOF_Group::setNodeDisp: no associated Node.\n')
            return
        disp = self.unbalance  # ????
        disp = self.myNode.getTrialDisp()  # ????
        # get disp for my dof out of vector u
        for i in range(0, self.numDOF):
            loc = self.myID[i]
            if loc >= 0:
                disp[i] = u[loc]
        self.myNode.setTrialDisp(disp)

    def setNodeVel(self, udot):
        if self.myNode == None:
            print('DOF_Group::setNodeVel: no associated Node.\n')
            return
        vel = self.unbalance  # ????
        vel = self.myNode.getTrialVel()  # ????
        # get vel for my dof out of vector u
        for i in range(0, self.numDOF):
            loc = self.myID[i]
            if loc >= 0:
                vel[i] = udot[loc]
        self.myNode.setTrialVel(vel)

    def setNodeAccel(self, udotdot):
        if self.myNode == None:
            print('DOF_Group::setNodeAccel: no associated Node.\n')
            return
        accel = self.unbalance  # ????
        accel = self.myNode.getTrialAccel()  # ????
        # get accel for my dof out of vector u
        for i in range(0, self.numDOF):
            loc = self.myID[i]
            if loc >= 0:
                accel[i] = udotdot[loc]
        self.myNode.setTrialAccel(accel)

    def incrNodeDisp(self, u):  # 有问题
        # u 是 Vector
        if self.myNode == None:
            print('DOF_Group::incrNodeDisp: 0 Node Pointer.\n')

        disp = self.unbalance
        # disp 是 Vector
        if disp.Size() == 0:
            print('DOF_Group::setNodeIncrDisp - out of space.\n')
            return

        # get disp for my dof out of vector u
        for i in range(0, self.numDOF):
            loc = self.myID(i)
            if loc >= 0:
                disp[i] = u[loc]
            else:
                disp[i] = 0.0

        self.myNode.incrTrialDisp(disp)

    def incrNodeVel(self, udot):
        pass

    def incrNodeAccel(self, udotdot):
        pass

    # methods to set the eigen vectors
    # methods added for TransformationDOF_Groups
    def getT(self):
        pass

    # protected:
    def addLocalM_Force(self, udotdot, fact=1.0):
        pass
Beispiel #10
0
class Truss(Element):
    ELE_TAG_Truss = 12
    trussM2 = Matrix(2, 2)
    trussM4 = Matrix(4, 4)
    trussM6 = Matrix(6, 6)
    trussM12 = Matrix(12, 12)
    trussV2 = Vector(2)
    trussV4 = Vector(4)
    trussV6 = Vector(6)
    trussV12 = Vector(12)

    def __init__(self,
                 tag,
                 dim,
                 Nd1,
                 Nd2,
                 theMaterial,
                 A,
                 r=0.0,
                 damp=0,
                 cm=0):
        super().__init__(tag, Truss.ELE_TAG_Truss)
        self.theMaterial = theMaterial

        self.connectedExternalNodes = ID(2)  # 存储节点号
        self.connectedExternalNodes[0] = Nd1
        self.connectedExternalNodes[1] = Nd2

        self.dimension = dim  # truss in 2 or 3d domain
        self.numDOF = 0  # number of dof for truss ??

        self.theLoad = None  # pointer to the load vector P
        self.theMatrix = None  # pointer to objects matrix (a class wide Matrix) ??
        self.theVector = None  # pointer to objects vector (a class wide Vector) ??

        self.L = 0.0  # length of truss based on undeformed configuration
        self.A = A  # area of truss
        self.rho = r  # rho: mass density per unit length

        self.doRayleighDamping = damp  # flag to include Rayleigh damping
        self.cMass = cm  # consistent mass flag

        self.cosX = [0, 0, 0]  # direction cosines
        self.theNodes = [None, None]  # 存储节点本身
        self.initialDisp = None  # narray

    # public methods to obtain information about dof and connectivity
    def getNumExternalNodes(self):
        return 2

    def getExternalNodes(self):
        return self.connectedExternalNodes

    def getNode(self):
        return self.theNodes

    def getNumDOF(self):
        return self.numDOF

    def setDomain(self, theDomain):
        # check Domain is not null - invoked when object removed from the a domain
        if (theDomain == None):
            self.theNodes = [None, None]
            self.L = 0
            return
        # first set the node pointers
        Nd1 = self.connectedExternalNodes[0]
        Nd2 = self.connectedExternalNodes[1]
        self.theNodes[0] = theDomain.getNode(Nd1)
        self.theNodes[1] = theDomain.getNode(Nd2)
        # if can't find both - send a warning message
        if self.theNodes[0] == None or self.theNodes[1] == None:
            if self.theNodes[0] == None:
                print('Truss::setDomain() - truss ' + str(self.getTag()) +
                      ' node ' + str(Nd1) + ' does not exist in the model.\n')
            else:
                print('Truss::setDomain() - truss ' + str(self.getTag()) +
                      ' node ' + str(Nd2) + ' does not exist in the model.\n')
                # fill this in so don't segment fault later
                self.numDOF = 2
                self.theMatrix = Truss.trussM2  # ????
                self.theVector = Truss.trussV2
                return
        # now determine the number of dof and the dimesnion
        dofNd1 = self.theNodes[0].getNumberDOF()
        dofNd2 = self.theNodes[1].getNumberDOF()
        # if differing dof at the ends - print a warning message
        if dofNd1 != dofNd2:
            print('WARNING Truss::setDomain(): nodes ' + str(Nd1) + ' and ' +
                  str(Nd2) + 'have differing dof at ends for truss ' +
                  str(self.getTag()) + '.\n')
            # fill this in so don't segment fault later
            self.numDOF = 2
            self.theMatrix = Truss.trussM2
            self.theVector = Truss.trussV2
            return
        # call the base class method
        super().setDomain(theDomain)
        # now set the number of dof for element and set matrix and vector pointer
        if self.dimension == 1 and dofNd1 == 1:
            self.numDOF = 2
            self.theMatrix = Truss.trussM2  # ????
            self.theVector = Truss.trussV2
        elif self.dimension == 2 and dofNd1 == 2:
            self.numDOF = 4
            self.theMatrix = Truss.trussM4  # ????
            self.theVector = Truss.trussV4
        elif self.dimension == 2 and dofNd1 == 3:
            self.numDOF = 6
            self.theMatrix = Truss.trussM6  # ????
            self.theVector = Truss.trussV6
        elif self.dimension == 3 and dofNd1 == 3:
            self.numDOF = 6
            self.theMatrix = Truss.trussM6  # ????
            self.theVector = Truss.trussV6
        elif self.dimension == 3 and dofNd1 == 6:
            self.numDOF = 12
            self.theMatrix = Truss.trussM12  # ????
            self.theVector = Truss.trussV12
        else:
            print('WARNING Truss::setDomain cannot handle ' +
                  str(self.dimension) + ' dofs at nodes in ' + str(dofNd1) +
                  ' problem.\n')
            self.numDOF = 2
            self.theMatrix = Truss.trussM2  # ????
            self.theVector = Truss.trussV2
            return
        # create the load vector
        if self.theLoad == None:
            self.theLoad = Vector(self.numDOF)
        elif self.theLoad.Size() != self.numDOF:
            self.theLoad = Vector(self.numDOF)
        # now determine the length, cosines and fill in the transformation
        # Note: t = -t(every one else uses for residual calc)
        end1Crd = self.theNodes[0].getCrds()  # 都是Vector
        end2Crd = self.theNodes[1].getCrds()
        end1Disp = self.theNodes[0].getDisp()
        end2Disp = self.theNodes[1].getDisp()

        if self.dimension == 1:
            dx = end2Crd[0] - end1Crd[0]
            if self.initialDisp == None:
                iDisp = end2Disp[0] - end1Disp[0]
                if iDisp != 0:
                    self.initialDisp = np.zeros(1)
                    self.initialDisp[0] = iDisp
                    dx += iDisp
            L = sqrt(dx * dx)
            if L == 0.0:
                print('WARNING Truss::setDomain() - truss ' +
                      str(self.getTag()) + ' has zero length.\n')
                return
            self.cosX[0] = 1.0
        elif self.dimension == 2:
            dx = end2Crd[0] - end1Crd[0]
            dy = end2Crd[1] - end1Crd[1]
            if self.initialDisp == None:
                iDispX = end2Disp[0] - end1Disp[0]
                iDispY = end2Disp[1] - end1Disp[1]
                if iDispX != 0 or iDispY != 0:
                    self.initialDisp = np.zeros(2)
                    self.initialDisp[0] = iDispX
                    self.initialDisp[1] = iDispY
                    dx += iDispX
                    dy += iDispY
            L = sqrt(dx * dx + dy * dy)
            if L == 0.0:
                print('WARNING Truss::setDomain() - truss ' +
                      str(self.getTag()) + ' has zero length.\n')
                return
            self.cosX[0] = dx / L
            self.cosX[1] = dy / L
        else:
            dx = end2Crd[0] - end1Crd[0]
            dy = end2Crd[1] - end1Crd[1]
            dz = end2Crd[2] - end1Crd[2]
            if self.initialDisp == None:
                iDispX = end2Disp[0] - end1Disp[0]
                iDispY = end2Disp[1] - end1Disp[1]
                iDispZ = end2Disp[2] - end1Disp[2]
                if iDispX != 0 or iDispY != 0 or iDispZ != 0:
                    self.initialDisp = np.zeros(3)
                    self.initialDisp[0] = iDispX
                    self.initialDisp[1] = iDispY
                    self.initialDisp[2] = iDispZ
                    dx += iDispX
                    dy += iDispY
                    dz += iDispZ
            L = sqrt(dx * dx + dy * dy + dz * dz)
            if L == 0.0:
                print('WARNING Truss::setDomain() - truss ' +
                      str(self.getTag()) + ' has zero length.\n')
                return
            self.cosX[0] = dx / L
            self.cosX[1] = dy / L
            self.cosX[2] = dz / L

    # public methods to set the state of the element
    def commitState(self):
        if self.Kc != None:
            Kc = self.getTangentStiff()
        retVal = self.theMaterial.commitState()
        return retVal

    def revertToLastCommit(self):
        return self.theMaterial.revertToLastCommit()

    def revertToStart(self):
        pass

    def update(self):
        # determine the current strain given trial displacements at nodes
        strain = self.computeCurrentStrain()
        rate = self.computeCurrentStrainRate()
        return self.theMaterial.setTrialStrain(strain, rate)

    # public methods to obtain stiffness, mass, damping and residual information
    def getKi(self):
        pass

    def getTangentStiff(self):
        if self.L == 0.0:  # - problem in setDomain() no further warnings
            self.theMatrix.Zero()
            return self.theMatrix
        E = self.theMaterial.getTangent()
        # come back later and redo this if too slow
        stiff = self.theMatrix
        numDOF2 = self.numDOF / 2
        EAoverL = E * self.A / self.L
        for i in range(0, self.dimension):
            for j in range(0, self.dimension):
                temp = self.cosX[i] * self.cosX[j] * EAoverL
                stiff[i, j] = temp
                stiff[i + numDOF2, j] = -temp
                stiff[i, j + numDOF2] = -temp
                stiff[i + numDOF2, j + numDOF2] = temp
        return stiff

    def getInitialStiff(self):
        if self.L == 0.0:  # - problem in setDomain() no further warnings
            self.theMatrix.Zero()
            return self.theMatrix
        E = self.theMaterial.getInitialTangent()
        # come back later and redo this if too slow
        stiff = self.theMatrix
        numDOF2 = self.numDOF / 2
        EAoverL = E * self.A / self.L
        for i in range(0, self.dimension):
            for j in range(0, self.dimension):
                temp = self.cosX[i] * self.cosX[j] * EAoverL
                stiff[i, j] = temp
                stiff[i + numDOF2, j] = -temp
                stiff[i, j + numDOF2] = -temp
                stiff[i + numDOF2, j + numDOF2] = temp
        return stiff

    def getDamp(self):
        pass

    def getMass(self):
        pass

    def zeroLoad(self):
        self.theLoad.Zero()

    def addLoad(self, theLoad, loadFactor):  # Truss 单元没有分布力
        print('Truss::addLoad - load type unknown for truss with tag: ' +
              str(self.getTag()) + '.\n')
        return -1

    def addInertiaLoadToUnbalance(self, accel):
        pass

    def getresistingForce(self):
        if self.L == 0.0:  # - problem in setDomain() no further warnings
            self.theVector.Zero()
            return self.theVector

        # R = Ku - Pext
        # Ku = F * transformation
        force = self.A * self.theMaterial.getStress()
        numDOF2 = self.numDOF / 2
        for i in range(0, self.dimension):
            temp = self.cosX[i] * force
            self.theVector[i] = -temp
            self.theVector[i + numDOF2] = temp
        return self.theVector

    def getResistingForceIncInertia(self):
        return super().getResistingForceIncInertia()

    # public methods for element output
    # private
    def computeCurrentStrain(self):
        # Note: method will not be called if L == 0
        # determine the strain
        disp1 = self.theNodes[0].getTrialDisp()  # Vector
        disp2 = self.theNodes[1].getTrialDisp()
        dLength = 0.0
        if self.initialDisp == None:
            for i in range(0, self.dimension):
                dLength += (disp2[i] - disp1[i]) * self.cosX[i]
        else:
            for i in range(0, self.dimension):
                dLength += (disp2[i] - disp1[i] -
                            self.initialDisp[i]) * self.cosX[i]

        # this method should never be called with L == 0
        return dLength / self.L

    def computeCurrentStrainRate(self):
        # Note: method will not be called if L == 0
        # determine the strain
        vel1 = self.theNodes[0].getTrialVel()
        vel2 = self.theNodes[1].getTrialVel()
        dLength = 0.0
        for i in range(0, self.dimension):
            dLength += (vel2[i] - vel1[i]) * self.cosX[i]
        # this method should never be called with L == 0
        return dLength / self.L
Beispiel #11
0
    def setDomain(self, theDomain):
        # check Domain is not null - invoked when object removed from the a domain
        if (theDomain == None):
            self.theNodes = [None, None]
            self.L = 0
            return
        # first set the node pointers
        Nd1 = self.connectedExternalNodes[0]
        Nd2 = self.connectedExternalNodes[1]
        self.theNodes[0] = theDomain.getNode(Nd1)
        self.theNodes[1] = theDomain.getNode(Nd2)
        # if can't find both - send a warning message
        if self.theNodes[0] == None or self.theNodes[1] == None:
            if self.theNodes[0] == None:
                print('Truss::setDomain() - truss ' + str(self.getTag()) +
                      ' node ' + str(Nd1) + ' does not exist in the model.\n')
            else:
                print('Truss::setDomain() - truss ' + str(self.getTag()) +
                      ' node ' + str(Nd2) + ' does not exist in the model.\n')
                # fill this in so don't segment fault later
                self.numDOF = 2
                self.theMatrix = Truss.trussM2  # ????
                self.theVector = Truss.trussV2
                return
        # now determine the number of dof and the dimesnion
        dofNd1 = self.theNodes[0].getNumberDOF()
        dofNd2 = self.theNodes[1].getNumberDOF()
        # if differing dof at the ends - print a warning message
        if dofNd1 != dofNd2:
            print('WARNING Truss::setDomain(): nodes ' + str(Nd1) + ' and ' +
                  str(Nd2) + 'have differing dof at ends for truss ' +
                  str(self.getTag()) + '.\n')
            # fill this in so don't segment fault later
            self.numDOF = 2
            self.theMatrix = Truss.trussM2
            self.theVector = Truss.trussV2
            return
        # call the base class method
        super().setDomain(theDomain)
        # now set the number of dof for element and set matrix and vector pointer
        if self.dimension == 1 and dofNd1 == 1:
            self.numDOF = 2
            self.theMatrix = Truss.trussM2  # ????
            self.theVector = Truss.trussV2
        elif self.dimension == 2 and dofNd1 == 2:
            self.numDOF = 4
            self.theMatrix = Truss.trussM4  # ????
            self.theVector = Truss.trussV4
        elif self.dimension == 2 and dofNd1 == 3:
            self.numDOF = 6
            self.theMatrix = Truss.trussM6  # ????
            self.theVector = Truss.trussV6
        elif self.dimension == 3 and dofNd1 == 3:
            self.numDOF = 6
            self.theMatrix = Truss.trussM6  # ????
            self.theVector = Truss.trussV6
        elif self.dimension == 3 and dofNd1 == 6:
            self.numDOF = 12
            self.theMatrix = Truss.trussM12  # ????
            self.theVector = Truss.trussV12
        else:
            print('WARNING Truss::setDomain cannot handle ' +
                  str(self.dimension) + ' dofs at nodes in ' + str(dofNd1) +
                  ' problem.\n')
            self.numDOF = 2
            self.theMatrix = Truss.trussM2  # ????
            self.theVector = Truss.trussV2
            return
        # create the load vector
        if self.theLoad == None:
            self.theLoad = Vector(self.numDOF)
        elif self.theLoad.Size() != self.numDOF:
            self.theLoad = Vector(self.numDOF)
        # now determine the length, cosines and fill in the transformation
        # Note: t = -t(every one else uses for residual calc)
        end1Crd = self.theNodes[0].getCrds()  # 都是Vector
        end2Crd = self.theNodes[1].getCrds()
        end1Disp = self.theNodes[0].getDisp()
        end2Disp = self.theNodes[1].getDisp()

        if self.dimension == 1:
            dx = end2Crd[0] - end1Crd[0]
            if self.initialDisp == None:
                iDisp = end2Disp[0] - end1Disp[0]
                if iDisp != 0:
                    self.initialDisp = np.zeros(1)
                    self.initialDisp[0] = iDisp
                    dx += iDisp
            L = sqrt(dx * dx)
            if L == 0.0:
                print('WARNING Truss::setDomain() - truss ' +
                      str(self.getTag()) + ' has zero length.\n')
                return
            self.cosX[0] = 1.0
        elif self.dimension == 2:
            dx = end2Crd[0] - end1Crd[0]
            dy = end2Crd[1] - end1Crd[1]
            if self.initialDisp == None:
                iDispX = end2Disp[0] - end1Disp[0]
                iDispY = end2Disp[1] - end1Disp[1]
                if iDispX != 0 or iDispY != 0:
                    self.initialDisp = np.zeros(2)
                    self.initialDisp[0] = iDispX
                    self.initialDisp[1] = iDispY
                    dx += iDispX
                    dy += iDispY
            L = sqrt(dx * dx + dy * dy)
            if L == 0.0:
                print('WARNING Truss::setDomain() - truss ' +
                      str(self.getTag()) + ' has zero length.\n')
                return
            self.cosX[0] = dx / L
            self.cosX[1] = dy / L
        else:
            dx = end2Crd[0] - end1Crd[0]
            dy = end2Crd[1] - end1Crd[1]
            dz = end2Crd[2] - end1Crd[2]
            if self.initialDisp == None:
                iDispX = end2Disp[0] - end1Disp[0]
                iDispY = end2Disp[1] - end1Disp[1]
                iDispZ = end2Disp[2] - end1Disp[2]
                if iDispX != 0 or iDispY != 0 or iDispZ != 0:
                    self.initialDisp = np.zeros(3)
                    self.initialDisp[0] = iDispX
                    self.initialDisp[1] = iDispY
                    self.initialDisp[2] = iDispZ
                    dx += iDispX
                    dy += iDispY
                    dz += iDispZ
            L = sqrt(dx * dx + dy * dy + dz * dz)
            if L == 0.0:
                print('WARNING Truss::setDomain() - truss ' +
                      str(self.getTag()) + ' has zero length.\n')
                return
            self.cosX[0] = dx / L
            self.cosX[1] = dy / L
            self.cosX[2] = dz / L