Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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.3 $
00022 // $Date: 2001/06/14 22:17:05 $
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 
00045 ID FiberSection2d::code(2);
00046 
00047 // constructors:
00048 FiberSection2d::FiberSection2d(int tag, int num, Fiber **fibers): 
00049   SectionForceDeformation(tag, SEC_TAG_FiberSection2d),
00050   numFibers(num), theMaterials(0), matData(0), e(2), eCommit(2), s(0), ks(0)
00051 {
00052   if (numFibers != 0) {
00053     theMaterials = new UniaxialMaterial *[numFibers];
00054 
00055     if (theMaterials == 0)
00056       g3ErrorHandler->fatal("%s -- failed to allocate Material pointers",
00057        "FiberSection2d::FiberSection2d");
00058 
00059     matData = new double [numFibers*2];
00060 
00061     if (matData == 0)
00062       g3ErrorHandler->fatal("%s -- failed to allocate double array for material data",
00063        "FiberSection2d::FiberSection2d");
00064     
00065     for (int i = 0; i < numFibers; i++) {
00066       Fiber *theFiber = fibers[i];
00067       double yLoc, zLoc, Area;
00068       theFiber->getFiberLocation(yLoc, zLoc);
00069       Area = theFiber->getArea();
00070       matData[i*2] = -yLoc;
00071       matData[i*2+1] = Area;
00072       UniaxialMaterial *theMat = theFiber->getMaterial();
00073       theMaterials[i] = theMat->getCopy();
00074 
00075       if (theMaterials[i] == 0)
00076  g3ErrorHandler->fatal("%s -- failed to get copy of a Material",
00077          "FiberSection2d::FiberSection2d");
00078       
00079     }    
00080   }
00081 
00082   s = new Vector(sData, 2);
00083   ks = new Matrix(kData, 2, 2);
00084 
00085   sData[0] = 0.0;
00086   sData[1] = 0.0;
00087 
00088   kData[0] = 0.0;
00089   kData[1] = 0.0;
00090   kData[2] = 0.0;
00091   kData[3] = 0.0;
00092 
00093   code(0) = SECTION_RESPONSE_P;
00094   code(1) = SECTION_RESPONSE_MZ;
00095 }
00096 
00097 // constructor for blank object that recvSelf needs to be invoked upon
00098 FiberSection2d::FiberSection2d():
00099   SectionForceDeformation(0, SEC_TAG_FiberSection2d),
00100   numFibers(0), theMaterials(0), matData(0), e(2), eCommit(2), s(0), ks(0)
00101 {
00102   s = new Vector(sData, 2);
00103   ks = new Matrix(kData, 2, 2);
00104 
00105   sData[0] = 0.0;
00106   sData[1] = 0.0;
00107 
00108   kData[0] = 0.0;
00109   kData[1] = 0.0;
00110   kData[2] = 0.0;
00111   kData[3] = 0.0;
00112 
00113   code(0) = SECTION_RESPONSE_P;
00114   code(1) = SECTION_RESPONSE_MZ;
00115 }
00116 
00117 int
00118 FiberSection2d::addFiber(Fiber &newFiber)
00119 {
00120   // need to create larger arrays
00121   int newSize = numFibers+1;
00122   UniaxialMaterial **newArray = new UniaxialMaterial *[newSize]; 
00123   double *newMatData = new double [2 * newSize];
00124   if (newArray == 0 || newMatData == 0) {
00125     g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00126      "FiberSection2d::addFiber");
00127     return -1;
00128   }
00129 
00130   // copy the old pointers and data
00131   for (int i = 0; i < numFibers; i++) {
00132     newArray[i] = theMaterials[i];
00133     newMatData[2*i] = matData[2*i];
00134     newMatData[2*i+1] = matData[2*i+1];
00135   }
00136 
00137   // set the new pointers and data
00138   double yLoc, zLoc, Area;
00139   newFiber.getFiberLocation(yLoc, zLoc);
00140   Area = newFiber.getArea();
00141   newMatData[numFibers*2] = -yLoc;
00142   newMatData[numFibers*2+1] = Area;
00143   UniaxialMaterial *theMat = newFiber.getMaterial();
00144   newArray[numFibers] = theMat->getCopy();
00145 
00146   if (newArray[numFibers] == 0) {
00147     g3ErrorHandler->fatal("%s -- failed to get copy of a Material",
00148      "FiberSection2d::addFiber");
00149 
00150     delete [] newArray;
00151     delete [] newMatData;
00152     return -1;
00153   }
00154 
00155   numFibers++;
00156 
00157   if (theMaterials != 0) {
00158     delete [] theMaterials;
00159     delete [] matData;
00160   }
00161 
00162   theMaterials = newArray;
00163   matData = newMatData;
00164 
00165   return 0;
00166 }
00167 
00168 
00169 
00170 // destructor:
00171 FiberSection2d::~FiberSection2d()
00172 {
00173   if (theMaterials != 0) {
00174     for (int i = 0; i < numFibers; i++)
00175       if (theMaterials[i] != 0)
00176  delete theMaterials[i];
00177       
00178     delete [] theMaterials;
00179   }
00180 
00181   if (matData != 0)
00182     delete [] matData;
00183 
00184   if (s != 0)
00185     delete s;
00186 
00187   if (ks != 0)
00188     delete ks;
00189 }
00190 
00191 int FiberSection2d::setTrialSectionDeformation (const Vector &deforms)
00192 {
00193   int res = 0;
00194 
00195   e = deforms;
00196 
00197   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00198   sData[0] = 0.0; sData[1] = 0.0;
00199 
00200   int loc = 0;
00201 
00202   double d0 = deforms(0);
00203   double d1 = deforms(1);
00204 
00205   for (int i = 0; i < numFibers; i++) {
00206     UniaxialMaterial *theMat = theMaterials[i];
00207     double y = matData[loc++];
00208     double A = matData[loc++];
00209 
00210     // determine material strain and set it
00211     double strain = d0 + y*d1;
00212     double tangent, stress;
00213     res = theMat->setTrial(strain, stress, tangent);
00214 
00215     double ks0 = tangent * A;
00216     double ks1 = ks0 * y;
00217     kData[0] += ks0;
00218     kData[1] += ks1;
00219     kData[3] += ks1 * y;
00220 
00221     double fs0 = stress * A;
00222     sData[0] += fs0;
00223     sData[1] += fs0 * y;
00224   }
00225 
00226   kData[2] = kData[1];
00227 
00228   return res;
00229 }
00230 
00231 const Vector&
00232 FiberSection2d::getSectionDeformation(void)
00233 {
00234   return e;
00235 }
00236 
00237 const Matrix&
00238 FiberSection2d::getSectionTangent(void)
00239 {
00240   return *ks;
00241 }
00242 
00243 const Matrix&
00244 FiberSection2d::getSectionSecant(void)
00245 {
00246   return *ks;
00247 }
00248 
00249 const Vector&
00250 FiberSection2d::getStressResultant(void)
00251 {
00252   return *s;
00253 }
00254 
00255 SectionForceDeformation*
00256 FiberSection2d::getCopy(void)
00257 {
00258   FiberSection2d *theCopy = new FiberSection2d ();
00259   theCopy->setTag(this->getTag());
00260 
00261   theCopy->numFibers = numFibers;
00262 
00263   if (numFibers != 0) {
00264     theCopy->theMaterials = new UniaxialMaterial *[numFibers];
00265 
00266     if (theCopy->theMaterials == 0)
00267       g3ErrorHandler->fatal("%s -- failed to allocate Material pointers",
00268        "FiberSection2d::FiberSection2d");
00269 
00270     theCopy->matData = new double [numFibers*2];
00271 
00272     if (theCopy->matData == 0)
00273       g3ErrorHandler->fatal("%s -- failed to allocate double array for material data",
00274        "FiberSection2d::FiberSection2d");
00275     
00276     for (int i = 0; i < numFibers; i++) {
00277       theCopy->matData[i*2] = matData[i*2];
00278       theCopy->matData[i*2+1] = matData[i*2+1];
00279       theCopy->theMaterials[i] = theMaterials[i]->getCopy();
00280 
00281       if (theCopy->theMaterials[i] == 0)
00282  g3ErrorHandler->fatal("%s -- failed to get copy of a Material",
00283          "FiberSection2d::getCopy");
00284     }    
00285   }
00286 
00287   theCopy->eCommit = eCommit;
00288   theCopy->e = e;
00289 
00290   theCopy->kData[0] = kData[0];
00291   theCopy->kData[1] = kData[1];
00292   theCopy->kData[2] = kData[2];
00293   theCopy->kData[3] = kData[3];
00294 
00295   theCopy->sData[0] = sData[0];
00296   theCopy->sData[1] = sData[1];
00297 
00298   theCopy->s = new Vector(theCopy->sData, 2);
00299   theCopy->ks = new Matrix(theCopy->kData, 2, 2);
00300 
00301   return theCopy;
00302 }
00303 
00304 const ID&
00305 FiberSection2d::getType () const
00306 {
00307   return code;
00308 }
00309 
00310 int
00311 FiberSection2d::getOrder () const
00312 {
00313   return 2;
00314 }
00315 
00316 int
00317 FiberSection2d::commitState(void)
00318 {
00319   int err = 0;
00320 
00321   for (int i = 0; i < numFibers; i++)
00322     err += theMaterials[i]->commitState();
00323 
00324   eCommit = e;
00325 
00326   return err;
00327 }
00328 
00329 int
00330 FiberSection2d::revertToLastCommit(void)
00331 {
00332   int err = 0;
00333 
00334   // Last committed section deformations
00335   e = eCommit;
00336 
00337 
00338   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00339   sData[0] = 0.0; sData[1] = 0.0;
00340   
00341   int loc = 0;
00342   for (int i = 0; i < numFibers; i++) {
00343     UniaxialMaterial *theMat = theMaterials[i];
00344     double y = matData[loc++];
00345     double A = matData[loc++];
00346 
00347     // invoke revertToLast on the material
00348     err += theMat->revertToLastCommit();
00349 
00350     // get material stress & tangent for this strain and determine ks and fs
00351     double tangent = theMat->getTangent();
00352     double stress = theMat->getStress();
00353     double ks0 = tangent * A;
00354     double ks1 = ks0 * y;
00355     kData[0] += ks0;
00356     kData[1] += ks1;
00357     kData[3] += ks1 * y;
00358 
00359     double fs0 = stress * A;
00360     sData[0] = fs0;
00361     sData[1] = fs0 * y;
00362   }
00363 
00364   kData[2] = kData[1];
00365 
00366   return err;
00367 }
00368 
00369 int
00370 FiberSection2d::revertToStart(void)
00371 {
00372   // revert the fibers to start    
00373   int err = 0;
00374 
00375   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00376   sData[0] = 0.0; sData[1] = 0.0;
00377   
00378   int loc = 0;
00379   for (int i = 0; i < numFibers; i++) {
00380     UniaxialMaterial *theMat = theMaterials[i];
00381     double y = matData[loc++];
00382     double A = matData[loc++];
00383 
00384     // invoke revertToLast on the material
00385     err += theMat->revertToStart();
00386 
00387     // get material stress & tangent for this strain and determine ks and fs
00388     double tangent = theMat->getTangent();
00389     double stress = theMat->getStress();
00390     double ks0 = tangent * A;
00391     double ks1 = ks0 * y;
00392     kData[0] += ks0;
00393     kData[1] += ks1;
00394     kData[3] += ks1 * y;
00395 
00396     double fs0 = stress * A;
00397     sData[0] = fs0;
00398     sData[1] = fs0 * y;
00399   }
00400 
00401   kData[2] = kData[1];
00402 
00403   return err;
00404 }
00405 
00406 int
00407 FiberSection2d::sendSelf(int commitTag, Channel &theChannel)
00408 {
00409   int res = 0;
00410 
00411   // create an id to send objects tag and numFibers, 
00412   //     size 3 so no conflict with matData below if just 1 fiber
00413   static ID data(3);
00414   data(0) = this->getTag();
00415   data(1) = numFibers;
00416   int dbTag = this->getDbTag();
00417   res += theChannel.sendID(dbTag, commitTag, data);
00418   if (res < 0) {
00419     g3ErrorHandler->warning("%s - failed to send ID data",
00420        "FiberSection2d::sendSelf");
00421     return res;
00422   }    
00423 
00424   if (numFibers != 0) {
00425     
00426     // create an id containingg classTag and dbTag for each material & send it
00427     ID materialData(2*numFibers);
00428     for (int i=0; i<numFibers; i++) {
00429       UniaxialMaterial *theMat = theMaterials[i];
00430       materialData(2*i) = theMat->getClassTag();
00431       int matDbTag = theMat->getDbTag();
00432       if (matDbTag == 0) {
00433  matDbTag = theChannel.getDbTag();
00434  if (matDbTag != 0)
00435    theMat->setDbTag(matDbTag);
00436       }
00437       materialData(2*i+1) = matDbTag;
00438     }    
00439     
00440     res += theChannel.sendID(dbTag, commitTag, materialData);
00441     if (res < 0) {
00442       g3ErrorHandler->warning("%s - failed to send material data",
00443          "FiberSection2d::sendSelf");
00444       return res;
00445     }    
00446 
00447     // send the fiber data, i.e. area and loc
00448     Vector fiberData(matData, 2*numFibers);
00449     res += theChannel.sendVector(dbTag, commitTag, fiberData);
00450     if (res < 0) {
00451       g3ErrorHandler->warning("%s - failed to send material data",
00452          "FiberSection2d::sendSelf");
00453       return res;
00454     }    
00455 
00456     // now invoke send(0 on all the materials
00457     for (int j=0; j<numFibers; j++)
00458       theMaterials[j]->sendSelf(commitTag, theChannel);
00459 
00460   }
00461 
00462   
00463   return res;
00464 }
00465 
00466 int
00467 FiberSection2d::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00468 {
00469   int res = 0;
00470 
00471   static ID data(3);
00472   
00473   int dbTag = this->getDbTag();
00474   res += theChannel.recvID(dbTag, commitTag, data);
00475   if (res < 0) {
00476     g3ErrorHandler->warning("%s - failed to recv ID data",
00477        "FiberSection2d::recvSelf");
00478     return res;
00479   }    
00480   this->setTag(data(0));
00481 
00482   // recv data about materials objects, classTag and dbTag
00483   if (data(1) != 0) {
00484     ID materialData(2*data(1));
00485     res += theChannel.recvID(dbTag, commitTag, materialData);
00486     if (res < 0) {
00487       g3ErrorHandler->warning("%s - failed to send material data",
00488          "FiberSection2d::recvSelf");
00489       return res;
00490     }    
00491 
00492     // if current arrays not of correct size, release old and resize
00493     if (theMaterials == 0 || numFibers != data(1)) {
00494       // delete old stuff if outa date
00495       if (theMaterials != 0) {
00496  for (int i=0; i<numFibers; i++)
00497    delete theMaterials[i];
00498  delete [] theMaterials;
00499  if (matData != 0)
00500    delete [] matData;
00501  matData = 0;
00502  theMaterials = 0;
00503       }
00504 
00505       // create memory to hold material pointers and fiber data
00506       numFibers = data(1);
00507       if (numFibers != 0) {
00508  theMaterials = new UniaxialMaterial *[numFibers];
00509  
00510  if (theMaterials == 0)
00511    g3ErrorHandler->fatal("%s -- failed to allocate Material pointers",
00512     "FiberSection2d::recvSelf");
00513  
00514  for (int j=0; j<numFibers; j++)
00515    theMaterials[j] = 0;
00516 
00517  matData = new double [numFibers*2];
00518 
00519  if (matData == 0)
00520    g3ErrorHandler->fatal("%s -- failed to allocate double array for material data",
00521     "FiberSection2d::recvSelf");
00522  
00523       }
00524     }
00525 
00526     Vector fiberData(matData, 2*numFibers);
00527     res += theChannel.recvVector(dbTag, commitTag, fiberData);
00528     if (res < 0) {
00529       g3ErrorHandler->warning("%s - failed to send material data",
00530          "FiberSection2d::recvSelf");
00531       return res;
00532     }    
00533 
00534     for (int i=0; i<numFibers; i++) {
00535       int classTag = materialData(2*i);
00536       int dbTag = materialData(2*i+1);
00537 
00538       // if material pointed to is blank or not of corrcet type, 
00539       // release old and create a new one
00540       if (theMaterials[i] == 0)
00541  theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);
00542       else if (theMaterials[i]->getClassTag() != classTag) {
00543  delete theMaterials[i];
00544  theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);      
00545       }
00546 
00547       if (theMaterials[i] == 0) 
00548  g3ErrorHandler->fatal("%s -- failed to allocate double array for material data",
00549          "FiberSection2d::recvSelf"); 
00550 
00551       theMaterials[i]->setDbTag(dbTag);
00552       res += theMaterials[i]->recvSelf(commitTag, theChannel, theBroker);
00553     }
00554   }    
00555 
00556   return res;
00557 }
00558 
00559 void
00560 FiberSection2d::Print(ostream &s, int flag)
00561 {
00562   s << "\nFiberSection2d, tag: " << this->getTag() << endl;
00563   s << "\tSection code: " << code;
00564   s << "\tNumber of Fibers: " << numFibers << endl;
00565   
00566   if (flag == 1)
00567    for (int i = 0; i < numFibers; i++)
00568     theMaterials[i]->Print(s, flag);
00569 }
00570 
00571 Response*
00572 FiberSection2d::setResponse(char **argv, int argc, Information &sectInfo)
00573 {
00574  // See if the response is one of the defaults
00575  Response *res = SectionForceDeformation::setResponse(argv, argc, sectInfo);
00576  if (res != 0)
00577   return res;
00578 
00579  // Check if fiber response is requested
00580     else if (strcmp(argv[0],"fiber") == 0) {
00581         int key = 0;
00582         int passarg = 2;
00583 
00584         if (argc <= 2)          // not enough data input
00585             return 0;
00586         else if (argc <= 3)  // fiber number was input directly
00587             key = atoi(argv[1]);
00588         else {                  // fiber near-to coordinate specified
00589             double yCoord = atof(argv[1]);
00590    double zCoord = atof(argv[2]);
00591    double ySearch = -matData[0];
00592    double closestDist = fabs(ySearch-yCoord);
00593    double distance;
00594    for (int j = 1; j < numFibers; j++) {
00595     ySearch = -matData[2*j];
00596     distance = fabs(ySearch-yCoord);
00597     if (distance < closestDist) {
00598      closestDist = distance;
00599      key = j;
00600     }
00601    }
00602    passarg = 3;
00603   }
00604  
00605         if (key < numFibers)
00606    return theMaterials[key]->setResponse(&argv[passarg],argc-passarg,sectInfo);
00607         else
00608             return 0;
00609     }
00610    
00611     // otherwise response quantity is unknown for the FiberSection class
00612     else
00613   return 0;
00614 }
00615 
00616 
00617 int 
00618 FiberSection2d::getResponse(int responseID, Information &sectInfo)
00619 {
00620   // Just call the base class method ... don't need to define
00621   // this function, but keeping it here just for clarity
00622   return SectionForceDeformation::getResponse(responseID, sectInfo);
00623 }
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
Copyright Contact Us