FiberSection2d.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.26 $
00022 // $Date: 2006/09/05 23:29:17 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSection2d.cpp,v $
00024                                                                         
00025 // Written: fmk
00026 // Created: 04/04
00027 //
00028 // Description: This file contains the class implementation of FiberSection2d.
00029 
00030 #include <stdlib.h>
00031 
00032 #include <Channel.h>
00033 #include <Vector.h>
00034 #include <Matrix.h>
00035 #include <MatrixUtil.h>
00036 #include <Fiber.h>
00037 #include <classTags.h>
00038 #include <FiberSection2d.h>
00039 #include <ID.h>
00040 #include <FEM_ObjectBroker.h>
00041 #include <Information.h>
00042 #include <MaterialResponse.h>
00043 #include <UniaxialMaterial.h>
00044 #include <SectionIntegration.h>
00045 
00046 ID FiberSection2d::code(2);
00047 
00048 // constructors:
00049 FiberSection2d::FiberSection2d(int tag, int num, Fiber **fibers): 
00050   SectionForceDeformation(tag, SEC_TAG_FiberSection2d),
00051   numFibers(num), theMaterials(0), matData(0),
00052   yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)
00053 {
00054   if (numFibers != 0) {
00055     theMaterials = new UniaxialMaterial *[numFibers];
00056 
00057     if (theMaterials == 0) {
00058       opserr << "FiberSection2d::FiberSection2d -- failed to allocate Material pointers";
00059       exit(-1);
00060     }
00061 
00062     matData = new double [numFibers*2];
00063 
00064     if (matData == 0) {
00065       opserr << "FiberSection2d::FiberSection2d -- failed to allocate double array for material data\n";
00066       exit(-1);
00067     }
00068 
00069 
00070     double Qz = 0.0;
00071     double A  = 0.0;
00072     
00073     for (int i = 0; i < numFibers; i++) {
00074       Fiber *theFiber = fibers[i];
00075       double yLoc, zLoc, Area;
00076       theFiber->getFiberLocation(yLoc, zLoc);
00077       Area = theFiber->getArea();
00078       A  += Area;
00079       Qz += yLoc*Area;
00080       matData[i*2] = yLoc;
00081       matData[i*2+1] = Area;
00082       UniaxialMaterial *theMat = theFiber->getMaterial();
00083       theMaterials[i] = theMat->getCopy();
00084 
00085       if (theMaterials[i] == 0) {
00086         opserr << "FiberSection2d::FiberSection2d -- failed to get copy of a Material\n";
00087         exit(-1);
00088       }
00089     }    
00090 
00091     yBar = Qz/A;  
00092   }
00093 
00094   s = new Vector(sData, 2);
00095   ks = new Matrix(kData, 2, 2);
00096 
00097   sData[0] = 0.0;
00098   sData[1] = 0.0;
00099 
00100   kData[0] = 0.0;
00101   kData[1] = 0.0;
00102   kData[2] = 0.0;
00103   kData[3] = 0.0;
00104 
00105   code(0) = SECTION_RESPONSE_P;
00106   code(1) = SECTION_RESPONSE_MZ;
00107 }
00108 
00109 FiberSection2d::FiberSection2d(int tag, int num, UniaxialMaterial **mats,
00110                                SectionIntegration &si):
00111   SectionForceDeformation(tag, SEC_TAG_FiberSection2d),
00112   numFibers(num), theMaterials(0), matData(0),
00113   yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)
00114 {
00115   if (numFibers != 0) {
00116     theMaterials = new UniaxialMaterial *[numFibers];
00117 
00118     if (theMaterials == 0) {
00119       opserr << "FiberSection2d::FiberSection2d -- failed to allocate Material pointers";
00120       exit(-1);
00121     }
00122     matData = new double [numFibers*2];
00123 
00124     if (matData == 0) {
00125       opserr << "FiberSection2d::FiberSection2d -- failed to allocate double array for material data\n";
00126       exit(-1);
00127     }
00128   }
00129 
00130   sectionIntegr = si.getCopy();
00131   if (sectionIntegr == 0) {
00132     opserr << "Error: FiberSection2d::FiberSection2d: could not create copy of section integration object" << endln;
00133     exit(-1);
00134   }
00135 
00136   double fiberLocs[10000];
00137   sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00138   
00139   double fiberArea[10000];
00140   sectionIntegr->getFiberWeights(numFibers, fiberArea);
00141 
00142   double Qz = 0.0;
00143   double A  = 0.0;
00144   
00145   for (int i = 0; i < numFibers; i++) {
00146 
00147     A  += fiberArea[i];
00148     Qz += fiberLocs[i]*fiberArea[i];
00149 
00150     theMaterials[i] = mats[i]->getCopy();
00151     
00152     if (theMaterials[i] == 0) {
00153       opserr << "FiberSection2d::FiberSection2d -- failed to get copy of a Material\n";
00154       exit(-1);
00155     }
00156   }    
00157   
00158   yBar = Qz/A;  
00159 
00160   s = new Vector(sData, 2);
00161   ks = new Matrix(kData, 2, 2);
00162   
00163   sData[0] = 0.0;
00164   sData[1] = 0.0;
00165   
00166   kData[0] = 0.0;
00167   kData[1] = 0.0;
00168   kData[2] = 0.0;
00169   kData[3] = 0.0;
00170   
00171   code(0) = SECTION_RESPONSE_P;
00172   code(1) = SECTION_RESPONSE_MZ;
00173 }
00174 
00175 // constructor for blank object that recvSelf needs to be invoked upon
00176 FiberSection2d::FiberSection2d():
00177   SectionForceDeformation(0, SEC_TAG_FiberSection2d),
00178   numFibers(0), theMaterials(0), matData(0),
00179   yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)
00180 {
00181   s = new Vector(sData, 2);
00182   ks = new Matrix(kData, 2, 2);
00183 
00184   sData[0] = 0.0;
00185   sData[1] = 0.0;
00186 
00187   kData[0] = 0.0;
00188   kData[1] = 0.0;
00189   kData[2] = 0.0;
00190   kData[3] = 0.0;
00191 
00192   code(0) = SECTION_RESPONSE_P;
00193   code(1) = SECTION_RESPONSE_MZ;
00194 }
00195 
00196 int
00197 FiberSection2d::addFiber(Fiber &newFiber)
00198 {
00199   // need to create larger arrays
00200   int newSize = numFibers+1;
00201   UniaxialMaterial **newArray = new UniaxialMaterial *[newSize]; 
00202   double *newMatData = new double [2 * newSize];
00203   if (newArray == 0 || newMatData == 0) {
00204     opserr <<"FiberSection2d::addFiber -- failed to allocate Fiber pointers\n";
00205     return -1;
00206   }
00207 
00208   // copy the old pointers and data
00209   int i;
00210   for (i = 0; i < numFibers; i++) {
00211     newArray[i] = theMaterials[i];
00212     newMatData[2*i] = matData[2*i];
00213     newMatData[2*i+1] = matData[2*i+1];
00214   }
00215 
00216   // set the new pointers and data
00217   double yLoc, zLoc, Area;
00218   newFiber.getFiberLocation(yLoc, zLoc);
00219   Area = newFiber.getArea();
00220   newMatData[numFibers*2] = yLoc;
00221   newMatData[numFibers*2+1] = Area;
00222   UniaxialMaterial *theMat = newFiber.getMaterial();
00223   newArray[numFibers] = theMat->getCopy();
00224 
00225   if (newArray[numFibers] == 0) {
00226     opserr <<"FiberSection2d::addFiber -- failed to get copy of a Material\n";
00227     delete [] newMatData;
00228     return -1;
00229   }
00230 
00231   numFibers++;
00232 
00233   if (theMaterials != 0) {
00234     delete [] theMaterials;
00235     delete [] matData;
00236   }
00237 
00238   theMaterials = newArray;
00239   matData = newMatData;
00240 
00241   double Qz = 0.0;
00242   double A  = 0.0;
00243 
00244   // Recompute centroid
00245   for (i = 0; i < numFibers; i++) {
00246     yLoc = -matData[2*i];
00247     Area = matData[2*i+1];
00248     A  += Area;
00249     Qz += yLoc*Area;
00250   }
00251 
00252   yBar = Qz/A;
00253 
00254   return 0;
00255 }
00256 
00257 
00258 
00259 // destructor:
00260 FiberSection2d::~FiberSection2d()
00261 {
00262   if (theMaterials != 0) {
00263     for (int i = 0; i < numFibers; i++)
00264       if (theMaterials[i] != 0)
00265         delete theMaterials[i];
00266       
00267     delete [] theMaterials;
00268   }
00269 
00270   if (matData != 0)
00271     delete [] matData;
00272 
00273   if (s != 0)
00274     delete s;
00275 
00276   if (ks != 0)
00277     delete ks;
00278 
00279   if (sectionIntegr != 0)
00280     delete sectionIntegr;
00281 }
00282 
00283 int
00284 FiberSection2d::setTrialSectionDeformation (const Vector &deforms)
00285 {
00286   int res = 0;
00287 
00288   e = deforms;
00289 
00290   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00291   sData[0] = 0.0; sData[1] = 0.0;
00292 
00293   double d0 = deforms(0);
00294   double d1 = deforms(1);
00295 
00296   double fiberLocs[10000];
00297   double fiberArea[10000];
00298 
00299   if (sectionIntegr != 0) {
00300     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00301     sectionIntegr->getFiberWeights(numFibers, fiberArea);
00302   }  
00303   else {
00304     for (int i = 0; i < numFibers; i++) {
00305       fiberLocs[i] = matData[2*i];
00306       fiberArea[i] = matData[2*i+1];
00307     }
00308   }
00309   
00310   for (int i = 0; i < numFibers; i++) {
00311     UniaxialMaterial *theMat = theMaterials[i];
00312     double y = fiberLocs[i] - yBar;
00313     double A = fiberArea[i];
00314 
00315     // determine material strain and set it
00316     double strain = d0 - y*d1;
00317     double tangent, stress;
00318     res = theMat->setTrial(strain, stress, tangent);
00319 
00320     double ks0 = tangent * A;
00321     double ks1 = ks0 * -y;
00322     kData[0] += ks0;
00323     kData[1] += ks1;
00324     kData[3] += ks1 * -y;
00325 
00326     double fs0 = stress * A;
00327     sData[0] += fs0;
00328     sData[1] += fs0 * -y;
00329   }
00330 
00331   kData[2] = kData[1];
00332 
00333   return res;
00334 }
00335 
00336 const Vector&
00337 FiberSection2d::getSectionDeformation(void)
00338 {
00339   return e;
00340 }
00341 
00342 const Matrix&
00343 FiberSection2d::getInitialTangent(void)
00344 {
00345   static double kInitial[4];
00346   static Matrix kInitialMatrix(kInitial, 2, 2);
00347   kInitial[0] = 0.0; kInitial[1] = 0.0; kInitial[2] = 0.0; kInitial[3] = 0.0;
00348 
00349   double fiberLocs[10000];
00350   double fiberArea[10000];
00351 
00352   if (sectionIntegr != 0) {
00353     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00354     sectionIntegr->getFiberWeights(numFibers, fiberArea);
00355   }  
00356   else {
00357     for (int i = 0; i < numFibers; i++) {
00358       fiberLocs[i] = matData[2*i];
00359       fiberArea[i] = matData[2*i+1];
00360     }
00361   }
00362 
00363   for (int i = 0; i < numFibers; i++) {
00364     UniaxialMaterial *theMat = theMaterials[i];
00365     double y = fiberLocs[i] - yBar;
00366     double A = fiberArea[i];
00367 
00368     double tangent = theMat->getInitialTangent();
00369 
00370     double ks0 = tangent * A;
00371     double ks1 = ks0 * -y;
00372     kInitial[0] += ks0;
00373     kInitial[1] += ks1;
00374     kInitial[3] += ks1 * -y;
00375   }
00376 
00377   kInitial[2] = kInitial[1];
00378 
00379   return kInitialMatrix;
00380 }
00381 
00382 const Matrix&
00383 FiberSection2d::getSectionTangent(void)
00384 {
00385   return *ks;
00386 }
00387 
00388 const Vector&
00389 FiberSection2d::getStressResultant(void)
00390 {
00391   return *s;
00392 }
00393 
00394 SectionForceDeformation*
00395 FiberSection2d::getCopy(void)
00396 {
00397   FiberSection2d *theCopy = new FiberSection2d ();
00398   theCopy->setTag(this->getTag());
00399 
00400   theCopy->numFibers = numFibers;
00401 
00402   if (numFibers != 0) {
00403     theCopy->theMaterials = new UniaxialMaterial *[numFibers];
00404 
00405     if (theCopy->theMaterials == 0) {
00406       opserr <<"FiberSection2d::getCopy -- failed to allocate Material pointers\n";
00407       exit(-1);
00408     }
00409   
00410     theCopy->matData = new double [numFibers*2];
00411 
00412     if (theCopy->matData == 0) {
00413       opserr << "FiberSection2d::getCopy -- failed to allocate double array for material data\n";
00414       exit(-1);
00415     }
00416                             
00417     for (int i = 0; i < numFibers; i++) {
00418       theCopy->matData[i*2] = matData[i*2];
00419       theCopy->matData[i*2+1] = matData[i*2+1];
00420       theCopy->theMaterials[i] = theMaterials[i]->getCopy();
00421 
00422       if (theCopy->theMaterials[i] == 0) {
00423         opserr <<"FiberSection2d::getCopy -- failed to get copy of a Material";
00424         exit(-1);
00425       }
00426     }  
00427   }
00428 
00429   theCopy->eCommit = eCommit;
00430   theCopy->e = e;
00431   theCopy->yBar = yBar;
00432 
00433   theCopy->kData[0] = kData[0];
00434   theCopy->kData[1] = kData[1];
00435   theCopy->kData[2] = kData[2];
00436   theCopy->kData[3] = kData[3];
00437 
00438   theCopy->sData[0] = sData[0];
00439   theCopy->sData[1] = sData[1];
00440 
00441   if (sectionIntegr != 0)
00442     theCopy->sectionIntegr = sectionIntegr->getCopy();
00443   else
00444     theCopy->sectionIntegr = 0;
00445 
00446   return theCopy;
00447 }
00448 
00449 const ID&
00450 FiberSection2d::getType ()
00451 {
00452   return code;
00453 }
00454 
00455 int
00456 FiberSection2d::getOrder () const
00457 {
00458   return 2;
00459 }
00460 
00461 int
00462 FiberSection2d::commitState(void)
00463 {
00464   int err = 0;
00465 
00466   for (int i = 0; i < numFibers; i++)
00467     err += theMaterials[i]->commitState();
00468 
00469   eCommit = e;
00470 
00471   return err;
00472 }
00473 
00474 int
00475 FiberSection2d::revertToLastCommit(void)
00476 {
00477   int err = 0;
00478 
00479   // Last committed section deformations
00480   e = eCommit;
00481 
00482 
00483   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00484   sData[0] = 0.0; sData[1] = 0.0;
00485   
00486   double fiberLocs[10000];
00487   double fiberArea[10000];
00488 
00489   if (sectionIntegr != 0) {
00490     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00491     sectionIntegr->getFiberWeights(numFibers, fiberArea);
00492   }  
00493   else {
00494     for (int i = 0; i < numFibers; i++) {
00495       fiberLocs[i] = matData[2*i];
00496       fiberArea[i] = matData[2*i+1];
00497     }
00498   }
00499 
00500   for (int i = 0; i < numFibers; i++) {
00501     UniaxialMaterial *theMat = theMaterials[i];
00502     double y = fiberLocs[i] - yBar;
00503     double A = fiberArea[i];
00504 
00505     // invoke revertToLast on the material
00506     err += theMat->revertToLastCommit();
00507 
00508     // get material stress & tangent for this strain and determine ks and fs
00509     double tangent = theMat->getTangent();
00510     double stress = theMat->getStress();
00511     double ks0 = tangent * A;
00512     double ks1 = ks0 * -y;
00513     kData[0] += ks0;
00514     kData[1] += ks1;
00515     kData[3] += ks1 * -y;
00516 
00517     double fs0 = stress * A;
00518     sData[0] = fs0;
00519     sData[1] = fs0 * -y;
00520   }
00521 
00522   kData[2] = kData[1];
00523 
00524   return err;
00525 }
00526 
00527 int
00528 FiberSection2d::revertToStart(void)
00529 {
00530   // revert the fibers to start    
00531   int err = 0;
00532 
00533   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00534   sData[0] = 0.0; sData[1] = 0.0;
00535   
00536   double fiberLocs[10000];
00537   double fiberArea[10000];
00538 
00539   if (sectionIntegr != 0) {
00540     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00541     sectionIntegr->getFiberWeights(numFibers, fiberArea);
00542   }  
00543   else {
00544     for (int i = 0; i < numFibers; i++) {
00545       fiberLocs[i] = matData[2*i];
00546       fiberArea[i] = matData[2*i+1];
00547     }
00548   }
00549 
00550   for (int i = 0; i < numFibers; i++) {
00551     UniaxialMaterial *theMat = theMaterials[i];
00552     double y = fiberLocs[i] - yBar;
00553     double A = fiberArea[i];
00554 
00555     // invoke revertToLast on the material
00556     err += theMat->revertToStart();
00557 
00558     // get material stress & tangent for this strain and determine ks and fs
00559     double tangent = theMat->getTangent();
00560     double stress = theMat->getStress();
00561     double ks0 = tangent * A;
00562     double ks1 = ks0 * -y;
00563     kData[0] += ks0;
00564     kData[1] += ks1;
00565     kData[3] += ks1 * -y;
00566 
00567     double fs0 = stress * A;
00568     sData[0] = fs0;
00569     sData[1] = fs0 * -y;
00570   }
00571 
00572   kData[2] = kData[1];
00573 
00574   return err;
00575 }
00576 
00577 int
00578 FiberSection2d::sendSelf(int commitTag, Channel &theChannel)
00579 {
00580   int res = 0;
00581 
00582   // create an id to send objects tag and numFibers, 
00583   //     size 3 so no conflict with matData below if just 1 fiber
00584   static ID data(3);
00585   data(0) = this->getTag();
00586   data(1) = numFibers;
00587   int dbTag = this->getDbTag();
00588   res += theChannel.sendID(dbTag, commitTag, data);
00589   if (res < 0) {
00590     opserr <<  "FiberSection2d::sendSelf - failed to send ID data\n";
00591     return res;
00592   }    
00593 
00594   if (numFibers != 0) {
00595     
00596     // create an id containingg classTag and dbTag for each material & send it
00597     ID materialData(2*numFibers);
00598     for (int i=0; i<numFibers; i++) {
00599       UniaxialMaterial *theMat = theMaterials[i];
00600       materialData(2*i) = theMat->getClassTag();
00601       int matDbTag = theMat->getDbTag();
00602       if (matDbTag == 0) {
00603         matDbTag = theChannel.getDbTag();
00604         if (matDbTag != 0)
00605           theMat->setDbTag(matDbTag);
00606       }
00607       materialData(2*i+1) = matDbTag;
00608     }    
00609     
00610     res += theChannel.sendID(dbTag, commitTag, materialData);
00611     if (res < 0) {
00612       opserr <<  "FiberSection2d::sendSelf - failed to send material data\n";
00613       return res;
00614     }    
00615 
00616     // send the fiber data, i.e. area and loc
00617     Vector fiberData(matData, 2*numFibers);
00618     res += theChannel.sendVector(dbTag, commitTag, fiberData);
00619     if (res < 0) {
00620       opserr <<  "FiberSection2d::sendSelf - failed to send material data\n";
00621       return res;
00622     }    
00623 
00624     // now invoke send(0 on all the materials
00625     for (int j=0; j<numFibers; j++)
00626       theMaterials[j]->sendSelf(commitTag, theChannel);
00627 
00628   }
00629 
00630   return res;
00631 }
00632 
00633 int
00634 FiberSection2d::recvSelf(int commitTag, Channel &theChannel,
00635                          FEM_ObjectBroker &theBroker)
00636 {
00637   int res = 0;
00638 
00639   static ID data(3);
00640   
00641   int dbTag = this->getDbTag();
00642   res += theChannel.recvID(dbTag, commitTag, data);
00643   if (res < 0) {
00644     opserr <<  "FiberSection2d::recvSelf - failed to recv ID data\n";
00645     return res;
00646   }    
00647   this->setTag(data(0));
00648 
00649   // recv data about materials objects, classTag and dbTag
00650   if (data(1) != 0) {
00651     ID materialData(2*data(1));
00652     res += theChannel.recvID(dbTag, commitTag, materialData);
00653     if (res < 0) {
00654       opserr <<  "FiberSection2d::recvSelf - failed to recv material data\n";
00655       return res;
00656     }    
00657 
00658     // if current arrays not of correct size, release old and resize
00659     if (theMaterials == 0 || numFibers != data(1)) {
00660       // delete old stuff if outa date
00661       if (theMaterials != 0) {
00662         for (int i=0; i<numFibers; i++)
00663           delete theMaterials[i];
00664         delete [] theMaterials;
00665         if (matData != 0)
00666           delete [] matData;
00667         matData = 0;
00668         theMaterials = 0;
00669       }
00670 
00671       // create memory to hold material pointers and fiber data
00672       numFibers = data(1);
00673       if (numFibers != 0) {
00674         theMaterials = new UniaxialMaterial *[numFibers];
00675         
00676         if (theMaterials == 0) {
00677           opserr <<"FiberSection2d::recvSelf -- failed to allocate Material pointers\n";
00678           exit(-1);
00679         }
00680         
00681         for (int j=0; j<numFibers; j++)
00682           theMaterials[j] = 0;
00683 
00684         matData = new double [numFibers*2];
00685 
00686         if (matData == 0) {
00687           opserr <<"FiberSection2d::recvSelf  -- failed to allocate double array for material data\n";
00688           exit(-1);
00689         }
00690       }
00691     }
00692 
00693     Vector fiberData(matData, 2*numFibers);
00694     res += theChannel.recvVector(dbTag, commitTag, fiberData);
00695     if (res < 0) {
00696       opserr <<  "FiberSection2d::recvSelf - failed to recv material data\n";
00697       return res;
00698     }    
00699 
00700     int i;
00701     for (i=0; i<numFibers; i++) {
00702       int classTag = materialData(2*i);
00703       int dbTag = materialData(2*i+1);
00704 
00705       // if material pointed to is blank or not of corrcet type, 
00706       // release old and create a new one
00707       if (theMaterials[i] == 0)
00708         theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);
00709       else if (theMaterials[i]->getClassTag() != classTag) {
00710         delete theMaterials[i];
00711         theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);      
00712       }
00713 
00714       if (theMaterials[i] == 0) {
00715         opserr <<"FiberSection2d::recvSelf -- failed to allocate double array for material data\n";
00716         exit(-1);
00717       }
00718 
00719       theMaterials[i]->setDbTag(dbTag);
00720       res += theMaterials[i]->recvSelf(commitTag, theChannel, theBroker);
00721     }
00722 
00723     double Qz = 0.0;
00724     double A  = 0.0;
00725     double yLoc, Area;
00726 
00727     // Recompute centroid
00728     for (i = 0; i < numFibers; i++) {
00729       yLoc = matData[2*i];
00730       Area = matData[2*i+1];
00731       A  += Area;
00732       Qz += yLoc*Area;
00733     }
00734     
00735     yBar = Qz/A;
00736   }    
00737 
00738   return res;
00739 }
00740 
00741 void
00742 FiberSection2d::Print(OPS_Stream &s, int flag)
00743 {
00744   s << "\nFiberSection2d, tag: " << this->getTag() << endln;
00745   s << "\tSection code: " << code;
00746   s << "\tNumber of Fibers: " << numFibers << endln;
00747   s << "\tCentroid: " << yBar << endln;
00748 
00749   if (flag == 1) {
00750     for (int i = 0; i < numFibers; i++) {
00751       s << "\nLocation (y) = (" << matData[2*i] << ")";
00752       s << "\nArea = " << matData[2*i+1] << endln;
00753       theMaterials[i]->Print(s, flag);
00754     }
00755   }
00756 }
00757 
00758 Response*
00759 FiberSection2d::setResponse(const char **argv, int argc,
00760                             Information &sectInfo, OPS_Stream &output)
00761 {
00762 
00763   const ID &type = this->getType();
00764   int typeSize = this->getOrder();
00765 
00766 
00767   Response *theResponse =0;
00768 
00769   output.tag("SectionOutput");
00770   output.attr("secType", this->getClassType());
00771   output.attr("secTag", this->getTag());
00772 
00773   // deformations
00774   if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) {
00775     for (int i=0; i<typeSize; i++) {
00776       int code = type(i);
00777       switch (code){
00778       case SECTION_RESPONSE_MZ:
00779         output.tag("ResponseType","kappaZ");
00780         break;
00781       case SECTION_RESPONSE_P:
00782         output.tag("ResponseType","eps");
00783         break;
00784       case SECTION_RESPONSE_VY:
00785         output.tag("ResponseType","gammaY");
00786         break;
00787       case SECTION_RESPONSE_MY:
00788         output.tag("ResponseType","kappaY");
00789         break;
00790       case SECTION_RESPONSE_VZ:
00791         output.tag("ResponseType","gammaZ");
00792         break;
00793       case SECTION_RESPONSE_T:
00794         output.tag("ResponseType","theta");
00795         break;
00796       default:
00797         output.tag("ResponseType","Unknown");
00798       }
00799     }
00800     theResponse =  new MaterialResponse(this, 1, this->getSectionDeformation());
00801   
00802   // forces
00803   } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) {
00804     for (int i=0; i<typeSize; i++) {
00805       int code = type(i);
00806       switch (code){
00807       case SECTION_RESPONSE_MZ:
00808         output.tag("ResponseType","Mz");
00809         break;
00810       case SECTION_RESPONSE_P:
00811         output.tag("ResponseType","P");
00812         break;
00813       case SECTION_RESPONSE_VY:
00814         output.tag("ResponseType","Vy");
00815         break;
00816       case SECTION_RESPONSE_MY:
00817         output.tag("ResponseType","My");
00818         break;
00819       case SECTION_RESPONSE_VZ:
00820         output.tag("ResponseType","Vz");
00821         break;
00822       case SECTION_RESPONSE_T:
00823         output.tag("ResponseType","T");
00824         break;
00825       default:
00826         output.tag("ResponseType","Unknown");
00827       }
00828     }
00829     theResponse =  new MaterialResponse(this, 2, this->getStressResultant());
00830   
00831   // force and deformation
00832   } else if (strcmp(argv[0],"forceAndDeformation") == 0) { 
00833     for (int j=0; j<typeSize; j++) {
00834       int code = type(j);
00835       switch (code){
00836       case SECTION_RESPONSE_MZ:
00837         output.tag("ResponseType","kappaZ");
00838         break;
00839       case SECTION_RESPONSE_P:
00840         output.tag("ResponseType","eps");
00841         break;
00842       case SECTION_RESPONSE_VY:
00843         output.tag("ResponseType","gammaY");
00844         break;
00845       case SECTION_RESPONSE_MY:
00846         output.tag("ResponseType","kappaY");
00847         break;
00848       case SECTION_RESPONSE_VZ:
00849         output.tag("ResponseType","gammaZ");
00850         break;
00851       case SECTION_RESPONSE_T:
00852         output.tag("ResponseType","theta");
00853         break;
00854       default:
00855         output.tag("ResponseType","Unknown");
00856       }
00857     }
00858     for (int i=0; i<typeSize; i++) {
00859       int code = type(i);
00860       switch (code){
00861       case SECTION_RESPONSE_MZ:
00862         output.tag("ResponseType","Mz");
00863         break;
00864       case SECTION_RESPONSE_P:
00865         output.tag("ResponseType","P");
00866         break;
00867       case SECTION_RESPONSE_VY:
00868         output.tag("ResponseType","Vy");
00869         break;
00870       case SECTION_RESPONSE_MY:
00871         output.tag("ResponseType","My");
00872         break;
00873       case SECTION_RESPONSE_VZ:
00874         output.tag("ResponseType","Vz");
00875         break;
00876       case SECTION_RESPONSE_T:
00877         output.tag("ResponseType","T");
00878         break;
00879       default:
00880         output.tag("ResponseType","Unknown");
00881       }
00882     }
00883 
00884     theResponse =  new MaterialResponse(this, 4, Vector(2*this->getOrder()));
00885   
00886   }  
00887   
00888   else {
00889     if (argc > 2 || strcmp(argv[0],"fiber") == 0) {
00890     
00891       int key = numFibers;
00892       int passarg = 2;
00893       
00894       if (argc <= 3) {            // fiber number was input directly
00895         
00896         key = atoi(argv[1]);
00897       
00898       } else if (argc > 4) {  // find fiber closest to coord. with mat tag
00899         
00900         int matTag = atoi(argv[3]);
00901         double yCoord = atof(argv[1]);
00902         double closestDist;
00903         double ySearch, dy;
00904         double distance;
00905         int j;
00906         // Find first fiber with specified material tag
00907         for (j = 0; j < numFibers; j++) {
00908           if (matTag == theMaterials[j]->getTag()) {
00909             ySearch = -matData[2*j];
00910             dy = ySearch-yCoord;
00911             closestDist = fabs(dy);
00912             key = j;
00913             break;
00914           }
00915         }
00916         // Search the remaining fibers
00917         for ( ; j < numFibers; j++) {
00918           if (matTag == theMaterials[j]->getTag()) {
00919             ySearch = -matData[2*j];
00920             dy = ySearch-yCoord;
00921             distance = fabs(dy);
00922             if (distance < closestDist) {
00923               closestDist = distance;
00924               key = j;
00925             }
00926           }
00927         }
00928         passarg = 4;
00929       }
00930       
00931       else {                  // fiber near-to coordinate specified
00932         double yCoord = atof(argv[1]);
00933         double closestDist;
00934         double ySearch, dy;
00935         double distance;
00936         ySearch = -matData[0];
00937         dy = ySearch-yCoord;
00938         closestDist = fabs(dy);
00939         key = 0;
00940         for (int j = 1; j < numFibers; j++) {
00941           ySearch = -matData[2*j];
00942           dy = ySearch-yCoord;
00943           distance = fabs(dy);
00944           if (distance < closestDist) {
00945             closestDist = distance;
00946             key = j;
00947           }
00948         }
00949         passarg = 3;
00950       }
00951       
00952       
00953       if (key < numFibers && key >= 0) {
00954         output.tag("FiberOutput");
00955         output.attr("yLoc",-matData[2*key]);
00956         output.attr("zLoc",0.0);
00957         output.attr("area",matData[2*key+1]);
00958         
00959         theResponse =  theMaterials[key]->setResponse(&argv[passarg], argc-passarg, sectInfo, output);
00960 
00961         output.endTag();
00962       }
00963     }
00964   }
00965 
00966   output.endTag();
00967   return theResponse;
00968 }
00969 
00970 
00971 int 
00972 FiberSection2d::getResponse(int responseID, Information &sectInfo)
00973 {
00974   // Just call the base class method ... don't need to define
00975   // this function, but keeping it here just for clarity
00976   return SectionForceDeformation::getResponse(responseID, sectInfo);
00977 }
00978 
00979 
00980 
00981 // AddingSensitivity:BEGIN ////////////////////////////////////
00982 int
00983 FiberSection2d::setParameter(const char **argv, int argc, Parameter &param)
00984 {
00985   if (argc < 1)
00986     return -1;
00987 
00988   // Check if the parameter belongs to the material (only option for now)
00989   if (strstr(argv[0],"material") != 0) {
00990     
00991     if (argc < 3)
00992       return 0;
00993 
00994     // Get the tag of the material
00995     int materialTag = atoi(argv[1]);
00996     
00997     // Loop over fibers to find the right material
00998     int ok = 0;
00999     for (int i = 0; i < numFibers; i++)
01000       if (materialTag == theMaterials[i]->getTag())
01001         ok += theMaterials[i]->setParameter(&argv[2], argc-2, param);
01002 
01003     return ok;
01004   } 
01005   
01006   else
01007     return sectionIntegr->setParameter(argv, argc, param);
01008 }
01009 
01010 const Vector &
01011 FiberSection2d::getSectionDeformationSensitivity(int gradNumber)
01012 {
01013   static Vector dummy(2);
01014 
01015   return dummy;
01016 }
01017 
01018 const Vector &
01019 FiberSection2d::getStressResultantSensitivity(int gradNumber, bool conditional)
01020 {
01021   static Vector ds(2);
01022   
01023   ds.Zero();
01024   
01025   double y, A, stressGradient, stress, tangent, sig_dAdh;
01026 
01027   double fiberLocs[10000];
01028   double fiberArea[10000];
01029 
01030   if (sectionIntegr != 0) {
01031     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
01032     sectionIntegr->getFiberWeights(numFibers, fiberArea);
01033   }  
01034   else {
01035     for (int i = 0; i < numFibers; i++) {
01036       fiberLocs[i] = matData[2*i];
01037       fiberArea[i] = matData[2*i+1];
01038     }
01039   }
01040 
01041   double locsDeriv[10000];
01042   double areaDeriv[10000];
01043 
01044   if (sectionIntegr != 0) {
01045     sectionIntegr->getLocationsDeriv(numFibers, locsDeriv);  
01046     sectionIntegr->getWeightsDeriv(numFibers, areaDeriv);
01047   }
01048   else {
01049     for (int i = 0; i < numFibers; i++) {
01050       locsDeriv[i] = 0.0;
01051       areaDeriv[i] = 0.0;
01052     }
01053   }
01054   
01055   for (int i = 0; i < numFibers; i++) {
01056     y = fiberLocs[i] - yBar;
01057     A = fiberArea[i];
01058     
01059     stressGradient = theMaterials[i]->getStressSensitivity(gradNumber,true);
01060     stressGradient = stressGradient * A;
01061 
01062     ds(0) += stressGradient;
01063     ds(1) += stressGradient * -y;
01064 
01065     stress = theMaterials[i]->getStress();
01066     sig_dAdh = stress*areaDeriv[i];
01067 
01068     ds(0) += sig_dAdh;
01069     ds(1) += sig_dAdh * -y;
01070 
01071     //ds(0) += 0.0;
01072     ds(1) += (stress*A) * -locsDeriv[i];
01073 
01074     tangent = theMaterials[i]->getTangent();
01075     tangent = tangent * A * e(1);
01076 
01077     ds(0) += -locsDeriv[i]*tangent;
01078     ds(1) += fiberLocs[i]*locsDeriv[i]*tangent;
01079 
01080     //opserr << locsDeriv[i] << ' ' << areaDeriv[i] << endln;
01081   }
01082   
01083   return ds;
01084 }
01085 
01086 const Matrix &
01087 FiberSection2d::getInitialTangentSensitivity(int gradNumber)
01088 {
01089   static Matrix dksdh(2,2);
01090   
01091   dksdh.Zero();
01092 
01093   double y, A, dydh, dAdh, tangent, dtangentdh;
01094 
01095   double fiberLocs[10000];
01096   double fiberArea[10000];
01097 
01098   if (sectionIntegr != 0) {
01099     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
01100     sectionIntegr->getFiberWeights(numFibers, fiberArea);
01101   }  
01102   else {
01103     for (int i = 0; i < numFibers; i++) {
01104       fiberLocs[i] = matData[2*i];
01105       fiberArea[i] = matData[2*i+1];
01106     }
01107   }
01108 
01109   double locsDeriv[10000];
01110   double areaDeriv[10000];
01111 
01112   if (sectionIntegr != 0) {
01113     sectionIntegr->getLocationsDeriv(numFibers, locsDeriv);  
01114     sectionIntegr->getWeightsDeriv(numFibers, areaDeriv);
01115   }
01116   else {
01117     for (int i = 0; i < numFibers; i++) {
01118       locsDeriv[i] = 0.0;
01119       areaDeriv[i] = 0.0;
01120     }
01121   }
01122   
01123   for (int i = 0; i < numFibers; i++) {
01124     y = fiberLocs[i] - yBar;
01125     A = fiberArea[i];
01126     dydh = locsDeriv[i];
01127     dAdh = areaDeriv[i];
01128     
01129     tangent = theMaterials[i]->getInitialTangent();
01130     dtangentdh = theMaterials[i]->getInitialTangentSensitivity(gradNumber);
01131 
01132     dksdh(0,0) += dtangentdh*A + tangent*dAdh;
01133 
01134     dksdh(0,1) += -y*(dtangentdh*A+tangent*dAdh) - dydh*(tangent*A);
01135 
01136     dksdh(1,1) += 2*(y*dydh*tangent*A) + y*y*(dtangentdh*A+tangent*dAdh);
01137   }
01138 
01139   dksdh(1,0) = dksdh(0,1);
01140 
01141   return dksdh;
01142 }
01143 
01144 int
01145 FiberSection2d::commitSensitivity(const Vector& defSens,
01146                                   int gradNumber, int numGrads)
01147 {
01148   double d0 = defSens(0);
01149   double d1 = defSens(1);
01150 
01151   dedh = defSens;
01152 
01153   double fiberLocs[10000];
01154 
01155   if (sectionIntegr != 0)
01156     sectionIntegr->getFiberLocations(numFibers, fiberLocs);
01157   else {
01158     for (int i = 0; i < numFibers; i++)
01159       fiberLocs[i] = matData[2*i];
01160   }
01161 
01162   double locsDeriv[10000];
01163   double areaDeriv[10000];
01164 
01165   if (sectionIntegr != 0) {
01166     sectionIntegr->getLocationsDeriv(numFibers, locsDeriv);  
01167     sectionIntegr->getWeightsDeriv(numFibers, areaDeriv);
01168   }
01169   else {
01170     for (int i = 0; i < numFibers; i++) {
01171       locsDeriv[i] = 0.0;
01172       areaDeriv[i] = 0.0;
01173     }
01174   }
01175 
01176   double y;
01177   double kappa = e(1);
01178 
01179   for (int i = 0; i < numFibers; i++) {
01180     UniaxialMaterial *theMat = theMaterials[i];
01181     y = fiberLocs[i] - yBar;
01182 
01183     // determine material strain and set it
01184     double strainSens = d0 - y*d1 - locsDeriv[i]*kappa;
01185     theMat->commitSensitivity(strainSens,gradNumber,numGrads);
01186   }
01187 
01188   return 0;
01189 }
01190 
01191 // AddingSensitivity:END ///////////////////////////////////

Generated on Mon Oct 23 15:05:18 2006 for OpenSees by doxygen 1.5.0