const Vector & SectionAggregator::getStressResultantSensitivity(int gradIndex, bool conditional) { int i = 0; int theSectionOrder = 0; if (theSection) { const Vector &dsdh = theSection->getStressResultantSensitivity(gradIndex, conditional); theSectionOrder = theSection->getOrder(); for (i = 0; i < theSectionOrder; i++) (*s)(i) = dsdh(i); } int order = theSectionOrder + numMats; for ( ; i < order; i++) (*s)(i) = theAdditions[i-theSectionOrder]->getStressSensitivity(gradIndex, conditional); return *s; }
const Vector & DispBeamColumn2d::getResistingForceSensitivity(int gradNumber) { double L = crdTransf->getInitialLength(); double oneOverL = 1.0/L; //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); //const Vector &wts = quadRule.getIntegrPointWeights(numSections); double xi[maxNumSections]; beamInt->getSectionLocations(numSections, L, xi); double wt[maxNumSections]; beamInt->getSectionWeights(numSections, L, wt); double dLdh = crdTransf->getdLdh(); double d1oLdh = crdTransf->getd1overLdh(); double dptsdh[maxNumSections]; beamInt->getLocationsDeriv(numSections, L, dLdh, dptsdh); double dwtsdh[maxNumSections]; beamInt->getWeightsDeriv(numSections, L, dLdh, dwtsdh); // Zero for integration static Vector dqdh(3); dqdh.Zero(); // Loop over the integration points for (int i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const ID &code = theSections[i]->getType(); //double xi6 = 6.0*pts(i,0); double xi6 = 6.0*xi[i]; //double wti = wts(i); double wti = wt[i]; // Get section stress resultant gradient const Vector &dsdh = theSections[i]->getStressResultantSensitivity(gradNumber,true); // Perform numerical integration on internal force gradient double sensi; for (int j = 0; j < order; j++) { sensi = dsdh(j)*wti; switch(code(j)) { case SECTION_RESPONSE_P: dqdh(0) += sensi; break; case SECTION_RESPONSE_MZ: dqdh(1) += (xi6-4.0)*sensi; dqdh(2) += (xi6-2.0)*sensi; break; default: break; } } const Vector &s = theSections[i]->getStressResultant(); double dxi6dh = 6.0*dptsdh[i]; double dwtLdh = wt[i]*dLdh + dwtsdh[i]*L; //dwtLdh = dwtsdh[i]; // Perform numerical integration on internal force gradient for (int j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: //dqdh(0) += d1oLdh*s(j)*wti*L; break; case SECTION_RESPONSE_MZ: //dqdh(1) += (dxi6dh*oneOverL + d1oLdh*(xi6-4.0))*s(j)*wti*L; //dqdh(2) += (dxi6dh*oneOverL + d1oLdh*(xi6-2.0))*s(j)*wti*L; //dqdh(1) += oneOverL*(xi6-4.0)*s(j)*dwtLdh; //dqdh(2) += oneOverL*(xi6-2.0)*s(j)*dwtLdh; break; default: break; } } } // Transform forces static Vector dp0dh(3); // No distributed loads P.Zero(); ////////////////////////////////////////////////////////////// if (crdTransf->isShapeSensitivity()) { // Perform numerical integration to obtain basic stiffness matrix // Some extra declarations static Matrix kbmine(3,3); kbmine.Zero(); q.Zero(); double tmp; int j, k; for (int i = 0; i < numSections; i++) { int order = theSections[i]->getOrder(); const ID &code = theSections[i]->getType(); //double xi6 = 6.0*pts(i,0); double xi6 = 6.0*xi[i]; //double wti = wts(i); double wti = wt[i]; const Vector &s = theSections[i]->getStressResultant(); const Matrix &ks = theSections[i]->getSectionTangent(); Matrix ka(workArea, order, 3); ka.Zero(); double si; for (j = 0; j < order; j++) { si = s(j)*wti; switch(code(j)) { case SECTION_RESPONSE_P: q(0) += si; for (k = 0; k < order; k++) { ka(k,0) += ks(k,j)*wti; } break; case SECTION_RESPONSE_MZ: q(1) += (xi6-4.0)*si; q(2) += (xi6-2.0)*si; 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; } } } const Vector &A_u = crdTransf->getBasicTrialDisp(); double dLdh = crdTransf->getdLdh(); double d1overLdh = -dLdh/(L*L); // a^T k_s dadh v dqdh.addMatrixVector(1.0, kbmine, A_u, d1overLdh); // k dAdh u const Vector &dAdh_u = crdTransf->getBasicTrialDispShapeSensitivity(); dqdh.addMatrixVector(1.0, kbmine, dAdh_u, oneOverL); // dAdh^T q P += crdTransf->getGlobalResistingForceShapeSensitivity(q, dp0dh, gradNumber); } // A^T (dqdh + k dAdh u) P += crdTransf->getGlobalResistingForce(dqdh, dp0dh); return P; }
int DispBeamColumn2d::getResponseSensitivity(int responseID, int gradNumber, Information &eleInfo) { // Basic deformation sensitivity if (responseID == 3) { const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); return eleInfo.setVector(dvdh); } // Basic force sensitivity else if (responseID == 9) { static Vector dqdh(3); dqdh.Zero(); return eleInfo.setVector(dqdh); } // dsdh else if (responseID == 76) { int sectionNum = eleInfo.theInt; int order = theSections[sectionNum-1]->getOrder(); const ID &code = theSections[sectionNum-1]->getType(); Vector dsdh(order); dsdh = theSections[sectionNum-1]->getStressResultantSensitivity(gradNumber, true); const Vector &v = crdTransf->getBasicTrialDisp(); const Vector &dvdh = crdTransf->getBasicDisplSensitivity(gradNumber); double L = crdTransf->getInitialLength(); double oneOverL = 1.0/L; const Matrix &ks = theSections[sectionNum-1]->getSectionTangent(); Vector dedh(order); //const Matrix &pts = quadRule.getIntegrPointCoords(numSections); double xi[maxNumSections]; beamInt->getSectionLocations(numSections, L, xi); double x = xi[sectionNum-1]; //double xi6 = 6.0*pts(i,0); double xi6 = 6.0*x; int j; for (j = 0; j < order; j++) { switch(code(j)) { case SECTION_RESPONSE_P: dedh(j) = oneOverL*dvdh(0); break; case SECTION_RESPONSE_MZ: dedh(j) = oneOverL*((xi6-4.0)*dvdh(1) + (xi6-2.0)*dvdh(2)); break; default: dedh(j) = 0.0; break; } } dsdh.addMatrixVector(1.0, ks, dedh, 1.0); return eleInfo.setVector(dsdh); } else return -1; }