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
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
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
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
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
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')
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
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
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
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
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