int PDeltaCrdTransf2d::computeElemtLengthAndOrient() { // element projection static Vector dx(2); const Vector &ndICoords = nodeIPtr->getCrds(); const Vector &ndJCoords = nodeJPtr->getCrds(); dx(0) = ndJCoords(0) - ndICoords(0); dx(1) = ndJCoords(1) - ndICoords(1); if (nodeIInitialDisp != 0) { dx(0) -= nodeIInitialDisp[0]; dx(1) -= nodeIInitialDisp[1]; } if (nodeJInitialDisp != 0) { dx(0) += nodeJInitialDisp[0]; dx(1) += nodeJInitialDisp[1]; } if (nodeJOffset != 0) { dx(0) += nodeJOffset[0]; dx(1) += nodeJOffset[1]; } if (nodeIOffset != 0) { dx(0) -= nodeIOffset[0]; dx(1) -= nodeIOffset[1]; } // calculate the element length L = dx.Norm(); if (L == 0.0) { opserr << "\nPDeltaCrdTransf2d::computeElemtLengthAndOrien: 0 length\n"; return -2; } // calculate the element local x axis components (direction cosines) // wrt to the global coordinates cosTheta = dx(0)/L; sinTheta = dx(1)/L; return 0; }
// NEW METHOD int XC::DispBeamColumn2d::commitSensitivity(int gradNumber, int numGrads) { // Get basic deformation and sensitivities const XC::Vector &v = theCoordTransf->getBasicTrialDisp(); static XC::Vector vsens(3); vsens = theCoordTransf->getBasicDisplSensitivity(gradNumber); double L = theCoordTransf->getInitialLength(); double oneOverL = 1.0/L; const size_t numSections= getNumSections(); const Matrix &pts = quadRule.getIntegrPointCoords(numSections); // Some extra declarations double d1oLdh = 0.0; // Check if a nodal coordinate is random bool randomNodeCoordinate = false; static XC::ID nodeParameterID(2); nodeParameterID(0) = theNodes[0]->getCrdsSensitivity(); nodeParameterID(1) = theNodes[1]->getCrdsSensitivity(); if(nodeParameterID(0) != 0 || nodeParameterID(1) != 0) { vsens += theCoordTransf->getBasicTrialDispShapeSensitivity(); randomNodeCoordinate = true; const XC::Vector &ndICoords = theNodes[0]->getCrds(); const XC::Vector &ndJCoords = theNodes[1]->getCrds(); double dx = ndJCoords(0) - ndICoords(0); double dy = ndJCoords(1) - ndICoords(1); if(nodeParameterID(0) == 1) // here x1 is random d1oLdh = dx/(L*L*L); if(nodeParameterID(0) == 2) // here y1 is random d1oLdh = dy/(L*L*L); if(nodeParameterID(1) == 1) // here x2 is random d1oLdh = -dx/(L*L*L); if(nodeParameterID(1) == 2) // here y2 is random d1oLdh = -dy/(L*L*L); } // Loop over the integration points for(size_t i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const XC::ID &code = theSections[i]->getType(); Vector e(workArea, order); double xi6 = 6.0*pts(i,0); for(int j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: e(j) = oneOverL*vsens(0) + d1oLdh*v(0); break; case SECTION_RESPONSE_MZ: e(j) = oneOverL*((xi6-4.0)*vsens(1) + (xi6-2.0)*vsens(2)) + d1oLdh*((xi6-4.0)*v(1) + (xi6-2.0)*v(2)); break; default: e(j) = 0.0; break; } } // Set the section deformations theSections[i]->commitSensitivity(e,gradNumber,numGrads); } return 0; }
const XC::Vector &XC::DispBeamColumn2d::getResistingForceSensitivity(int gradNumber) { const size_t numSections= getNumSections(); const Matrix &pts = quadRule.getIntegrPointCoords(numSections); const Vector &wts = quadRule.getIntegrPointWeights(numSections); double L = theCoordTransf->getInitialLength(); double oneOverL = 1.0/L; // Zero for integration q.Zero(); static XC::Vector qsens(3); qsens.Zero(); // Some extra declarations static XC::Matrix kbmine(3,3); kbmine.Zero(); int j, k; double d1oLdh = 0.0; // Check if a nodal coordinate is random bool randomNodeCoordinate = false; static XC::ID nodeParameterID(2); nodeParameterID(0) = theNodes[0]->getCrdsSensitivity(); nodeParameterID(1) = theNodes[1]->getCrdsSensitivity(); if(nodeParameterID(0) != 0 || nodeParameterID(1) != 0) { randomNodeCoordinate = true; const XC::Vector &ndICoords = theNodes[0]->getCrds(); const XC::Vector &ndJCoords = theNodes[1]->getCrds(); double dx = ndJCoords(0) - ndICoords(0); double dy = ndJCoords(1) - ndICoords(1); if(nodeParameterID(0) == 1) // here x1 is random d1oLdh = dx/(L*L*L); if(nodeParameterID(0) == 2) // here y1 is random d1oLdh = dy/(L*L*L); if(nodeParameterID(1) == 1) // here x2 is random d1oLdh = -dx/(L*L*L); if(nodeParameterID(1) == 2) // here y2 is random d1oLdh = -dy/(L*L*L); } // Loop over the integration points for(size_t i= 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const XC::ID &code = theSections[i]->getType(); double xi6 = 6.0*pts(i,0); double wti = wts(i); // Get section stress resultant gradient const XC::Vector &s = theSections[i]->getStressResultant(); const XC::Vector &sens = theSections[i]->getStressResultantSensitivity(gradNumber,true); // Perform numerical integration on internal force gradient //q.addMatrixTransposeVector(1.0, *B, s, wts(i)); double si; double sensi; for(j = 0; j < order; j++) { si = s(j)*wti; sensi = sens(j)*wti; switch(code(j)) { case SECTION_RESPONSE_P: q(0) += si; qsens(0) += sensi; break; case SECTION_RESPONSE_MZ: q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; qsens(1) += (xi6-4.0)*sensi; qsens(2) += (xi6-2.0)*sensi; break; default: break; } } if(randomNodeCoordinate) { // Perform numerical integration to obtain basic stiffness matrix //kb.addMatrixTripleProduct(1.0, *B, ks, wts(i)/L); double tmp; const XC::Matrix &ks = theSections[i]->getSectionTangent(); Matrix ka(workArea, order, 3); ka.Zero(); for(j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: for(k = 0; k < order; k++) { ka(k,0) += ks(k,j)*wti; } break; case SECTION_RESPONSE_MZ: for(k = 0; k < order; k++) { tmp = ks(k,j)*wti; ka(k,1) += (xi6-4.0)*tmp; ka(k,2) += (xi6-2.0)*tmp; } break; default: break; } } for(j = 0; j < order; j++) { switch (code(j)) { case SECTION_RESPONSE_P: for(k = 0; k < 3; k++) { kbmine(0,k) += ka(j,k); } break; case SECTION_RESPONSE_MZ: for(k = 0; k < 3; k++) { tmp = ka(j,k); kbmine(1,k) += (xi6-4.0)*tmp; kbmine(2,k) += (xi6-2.0)*tmp; } break; default: break; } } } } static XC::Vector dqdh(3); const XC::Vector &dAdh_u = theCoordTransf->getBasicTrialDispShapeSensitivity(); //dqdh = (1.0/L) * (kbmine * dAdh_u); dqdh.addMatrixVector(0.0, kbmine, dAdh_u, oneOverL); static XC::Vector dkbdh_v(3); const XC::Vector &A_u = theCoordTransf->getBasicTrialDisp(); //dkbdh_v = (d1oLdh) * (kbmine * A_u); dkbdh_v.addMatrixVector(0.0, kbmine, A_u, d1oLdh); // Transform forces static XC::Vector dummy(3); // No distributed loads // Term 5 P = theCoordTransf->getGlobalResistingForce(qsens,dummy); if(randomNodeCoordinate) { // Term 1 P += theCoordTransf->getGlobalResistingForceShapeSensitivity(q,dummy); // Term 2 P += theCoordTransf->getGlobalResistingForce(dqdh,dummy); // Term 4 P += theCoordTransf->getGlobalResistingForce(dkbdh_v,dummy); } return P; }