Truss2::Truss2(int tag, int dim, int Nd1, int Nd2, int oNd1, int oNd2, UniaxialMaterial &theMat, double a, double r, int damp) :Element(tag,ELE_TAG_Truss2), theMaterial(0), theBetaMaterial(0), connectedExternalNodes(2), connectedExternalOtherNodes(2), dimension(dim), numDOF(0), theLoad(0), theMatrix(0), theVector(0), L(0.0), A(a), rho(r), doRayleighDamping(damp) { // get a copy of the material and check we obtained a valid copy theMaterial = theMat.getCopy(); if (theMaterial == 0) { opserr << "FATAL Truss2::Truss2 - " << tag << "failed to get a copy of material with tag " << theMat.getTag() << endln; exit(-1); } else if (theMaterial->getClassTag() == MAT_TAG_ConcretewBeta) { theBetaMaterial = (ConcretewBeta *) theMaterial; } // ensure the connectedExternalNode ID is of correct size & set values if (connectedExternalNodes.Size() != 2 || connectedExternalOtherNodes.Size() != 2) { opserr << "FATAL Truss2::Truss2 - " << tag << "failed to create an ID of size 2\n"; exit(-1); } connectedExternalNodes(0) = Nd1; connectedExternalNodes(1) = Nd2; /// some work to save the other nodes: connectedExternalOtherNodes(0) = oNd1; connectedExternalOtherNodes(1) = oNd2; // set node pointers to NULL for (int i=0; i<2; i++) { theNodes[i] = 0; theOtherNodes[i] = 0; } cosX[0] = 0.0; cosX[1] = 0.0; cosX[2] = 0.0; // AddingSensitivity:BEGIN ///////////////////////////////////// parameterID = 0; theLoadSens = 0; // AddingSensitivity:END ////////////////////////////////////// }
// method: setDomain() // to set a link to the enclosing Domain and to set the node pointers. // also determines the number of dof associated // with the truss element, we set matrix and vector pointers, // allocate space for t matrix, determine the length // and set the transformation matrix. void Truss2::setDomain(Domain *theDomain) { // check Domain is not null - invoked when object removed from a domain if (theDomain == 0) { theNodes[0] = 0; theNodes[1] = 0; L = 0; theOtherNodes[0] = 0; theOtherNodes[1] = 0; otherLength = 0; return; } // first set the node pointers int Nd1 = connectedExternalNodes(0); int Nd2 = connectedExternalNodes(1); theNodes[0] = theDomain->getNode(Nd1); theNodes[1] = theDomain->getNode(Nd2); // and the other node pointers (will be reordered later) int oNd1 = connectedExternalOtherNodes(0); int oNd2 = connectedExternalOtherNodes(1); theOtherNodes[0] = theDomain->getNode(oNd1); theOtherNodes[1] = theDomain->getNode(oNd2); // if can't find both - send a warning message if ((theNodes[0] == 0) || (theNodes[1] == 0) || theOtherNodes[0] == 0 || theOtherNodes[1] == 0) { if (theNodes[0] == 0) opserr <<"Truss2::setDomain() - truss" << this->getTag() << " node " << Nd1 << " does not exist in the model\n"; else if (theNodes[1] == 0) opserr <<"Truss2::setDomain() - truss" << this->getTag() << " node " << Nd2 << " does not exist in the model\n"; else if (theOtherNodes[0] == 0) opserr <<"Truss2::setDomain() - truss" << this->getTag() << " node " << oNd1 << " does not exist in the model\n"; else opserr <<"Truss2::setDomain() - truss" << this->getTag() << " node " << oNd2 << " does not exist in the model\n"; // fill this in so don't segment fault later numDOF = 2; theMatrix = &trussM2; theVector = &trussV2; return; } // now determine the number of dof and the dimesnion int dofNd1 = theNodes[0]->getNumberDOF(); int dofNd2 = theNodes[1]->getNumberDOF(); // if differing dof at the ends - print a warning message if (dofNd1 != dofNd2) { opserr <<"WARNING Truss2::setDomain(): nodes " << Nd1 << " and " << Nd2 << "have differing dof at ends for truss " << this->getTag() << endln; // fill this in so don't segment fault later numDOF = 2; theMatrix = &trussM2; theVector = &trussV2; return; } // call the base class method this->DomainComponent::setDomain(theDomain); // now set the number of dof for element and set matrix and vector pointer if (dimension == 1 && dofNd1 == 1) { numDOF = 2; theMatrix = &trussM2; theVector = &trussV2; } else if (dimension == 2 && dofNd1 == 2) { numDOF = 4; theMatrix = &trussM4; theVector = &trussV4; } else if (dimension == 2 && dofNd1 == 3) { numDOF = 6; theMatrix = &trussM6; theVector = &trussV6; } else if (dimension == 3 && dofNd1 == 3) { numDOF = 6; theMatrix = &trussM6; theVector = &trussV6; } else if (dimension == 3 && dofNd1 == 6) { numDOF = 12; theMatrix = &trussM12; theVector = &trussV12; } else { opserr <<"WARNING Truss2::setDomain cannot handle " << dimension << " dofs at nodes in " << dofNd1 << " problem\n"; numDOF = 2; theMatrix = &trussM2; theVector = &trussV2; return; } if (theLoad == 0) theLoad = new Vector(numDOF); else if (theLoad->Size() != numDOF) { delete theLoad; theLoad = new Vector(numDOF); } if (theLoad == 0) { opserr << "Truss2::setDomain - truss " << this->getTag() << "out of memory creating vector of size" << numDOF << endln; exit(-1); return; } // now determine the length, cosines and fill in the transformation // NOTE t = -t(every one else uses for residual calc) const Vector &end1Crd = theNodes[0]->getCrds(); const Vector &end2Crd = theNodes[1]->getCrds(); if (dimension == 1) { double dx = end2Crd(0)-end1Crd(0); L = sqrt(dx*dx); if (L == 0.0) { opserr <<"WARNING Truss2::setDomain() - truss " << this->getTag() << " has zero length\n"; return; } cosX[0] = 1.0; const Vector &end1Crd2 = theOtherNodes[0]->getCrds(); const Vector &end2Crd2 = theOtherNodes[1]->getCrds(); dx = end2Crd2(0)-end1Crd2(0); otherLength = sqrt(dx*dx); otherCosX[0] = 0; } else if (dimension == 2) { double dx = end2Crd(0)-end1Crd(0); double dy = end2Crd(1)-end1Crd(1); L = sqrt(dx*dx + dy*dy); if (L == 0.0) { opserr <<"WARNING Truss2::setDomain() - truss " << this->getTag() << " has zero length\n"; return; } cosX[0] = dx/L; cosX[1] = dy/L; const Vector &end1Crd2 = theOtherNodes[0]->getCrds(); const Vector &end2Crd2 = theOtherNodes[1]->getCrds(); double dx2 = end2Crd2(0)-end1Crd2(0); double dy2 = end2Crd2(1)-end1Crd2(1); otherLength = sqrt(dx2*dx2 + dy2*dy2); if (otherLength == 0.0) { opserr <<"WARNING Truss2::setDomain() - truss " << this->getTag() << " has auxiliary nodes that are the same point\n"; otherCosX[0] = 0; otherCosX[1] = 0; return; } otherCosX[0] = dx2/otherLength; otherCosX[1] = dy2/otherLength; // project on normal of truss direction. theta = acos((dx*dx2+dy*dy2)/(L*otherLength)); // cos*theta = a*b/(|a|*|b|) if (theta == 0.0) { opserr << "WARNING Truss2::setDomain() - truss2 " << this->getTag() << " has theta = 0, disabling biaxial effects\n"; } } else { double dx = end2Crd(0)-end1Crd(0); double dy = end2Crd(1)-end1Crd(1); double dz = end2Crd(2)-end1Crd(2); L = sqrt(dx*dx + dy*dy + dz*dz); if (L == 0.0) { opserr <<"WARNING Truss2::setDomain() - truss " << this->getTag() << " has zero length\n"; return; } cosX[0] = dx/L; cosX[1] = dy/L; cosX[2] = dz/L; const Vector &end1Crd2 = theOtherNodes[0]->getCrds(); const Vector &end2Crd2 = theOtherNodes[1]->getCrds(); double dx2 = end2Crd2(0)-end1Crd2(0); double dy2 = end2Crd2(1)-end1Crd2(1); double dz2 = end2Crd2(2)-end1Crd2(2); otherLength = sqrt(dx2*dx2 + dy2*dy2 + dz2*dz2); if (otherLength == 0.0) { opserr <<"WARNING Truss2::setDomain() - truss " << this->getTag() << " has auxiliary nodes that are the same point\n"; otherCosX[0] = 0; otherCosX[1] = 0; otherCosX[2] = 0; return; } otherCosX[0] = dx2/otherLength; otherCosX[1] = dy2/otherLength; otherCosX[2] = dz2/otherLength; // project on normal of truss direction. theta = acos((dx*dx2+dy*dy2+dz*dz2)/(L*otherLength)); // cos*theta = a*b/(|a|*|b|) if (theta == 0.0) { opserr << "WARNING Truss2::setDomain() - truss2 " << this->getTag() << " has theta = 0, disabling biaxial effects\n"; } } }
void Truss2::Print(OPS_Stream &s, int flag) { // compute the strain and axial force in the member double strain, force; strain = theMaterial->getStrain(); force = A * theMaterial->getStress(); if (flag == OPS_PRINT_CURRENTSTATE) { // print everything s << "Element: " << this->getTag(); s << " type: Truss2 iNode: " << connectedExternalNodes(0); s << " jNode: " << connectedExternalNodes(1); s << " Area: " << A << " Mass/Length: " << rho; s << " \n\t strain: " << strain; s << " axial load: " << force; if (L != 0.0) { int numDOF2 = numDOF / 2; double temp; for (int i = 0; i < dimension; i++) { temp = cosX[i] * force; (*theVector)(i) = -temp; (*theVector)(i + numDOF2) = temp; } s << " \n\t unbalanced load: " << *theVector; } s << " \t Material: " << *theMaterial; s << endln; } if (flag == 1) { s << this->getTag() << " " << strain << " "; s << force << endln; } if (flag == OPS_PRINT_PRINTMODEL_JSON) { s << "\t\t\t{"; s << "\"name\": " << this->getTag() << ", "; s << "\"type\": \"Truss2\", "; s << "\"nodes\": [" << connectedExternalNodes(0) << ", " << connectedExternalNodes(1) << ", " << connectedExternalOtherNodes(0) << ", " << connectedExternalOtherNodes(1) << "], "; s << "\"A\": " << A << ", "; s << "\"massperlength\": " << rho << ", "; s << "\"material\": \"" << theMaterial->getTag() << "\"}"; } }