FiberSection3d.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.23 $
00022 // $Date: 2006/09/05 23:29:17 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSection3d.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 <FiberSection3d.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 FiberSection3d::code(3);
00046 
00047 // constructors:
00048 FiberSection3d::FiberSection3d(int tag, int num, Fiber **fibers): 
00049   SectionForceDeformation(tag, SEC_TAG_FiberSection3d),
00050   numFibers(num), theMaterials(0), matData(0),
00051   yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0)
00052 {
00053   if (numFibers != 0) {
00054     theMaterials = new UniaxialMaterial *[numFibers];
00055 
00056     if (theMaterials == 0) {
00057       opserr << "FiberSection3d::FiberSection3d -- failed to allocate Material pointers\n";
00058       exit(-1);
00059     }
00060 
00061     matData = new double [numFibers*3];
00062 
00063     if (matData == 0) {
00064       opserr << "FiberSection3d::FiberSection3d -- failed to allocate double array for material data\n";
00065       exit(-1);
00066     }
00067 
00068     double Qz = 0.0;
00069     double Qy = 0.0;
00070     double A  = 0.0;
00071     
00072     for (int i = 0; i < numFibers; i++) {
00073       Fiber *theFiber = fibers[i];
00074       double yLoc, zLoc, Area;
00075       theFiber->getFiberLocation(yLoc, zLoc);
00076       Area = theFiber->getArea();
00077 
00078       Qz += yLoc*Area;
00079       Qy += zLoc*Area;
00080       A  += Area;
00081 
00082       matData[i*3] = -yLoc;
00083       matData[i*3+1] = zLoc;
00084       matData[i*3+2] = Area;
00085       UniaxialMaterial *theMat = theFiber->getMaterial();
00086       theMaterials[i] = theMat->getCopy();
00087 
00088       if (theMaterials[i] == 0) {
00089         opserr << "FiberSection3d::FiberSection3d -- failed to get copy of a Material\n";
00090         exit(-1);
00091       }
00092     }
00093 
00094     yBar = -Qz/A;
00095     zBar = Qy/A;
00096   }
00097 
00098   s = new Vector(sData, 3);
00099   ks = new Matrix(kData, 3, 3);
00100 
00101   sData[0] = 0.0;
00102   sData[1] = 0.0;
00103   sData[2] = 0.0;
00104 
00105   for (int i=0; i<9; i++)
00106     kData[i] = 0.0;
00107 
00108   code(0) = SECTION_RESPONSE_P;
00109   code(1) = SECTION_RESPONSE_MZ;
00110   code(2) = SECTION_RESPONSE_MY;
00111 }
00112 
00113 // constructor for blank object that recvSelf needs to be invoked upon
00114 FiberSection3d::FiberSection3d():
00115   SectionForceDeformation(0, SEC_TAG_FiberSection3d),
00116   numFibers(0), theMaterials(0), matData(0),
00117   yBar(0.0), zBar(0.0), e(3), eCommit(3), s(0), ks(0)
00118 {
00119   s = new Vector(sData, 3);
00120   ks = new Matrix(kData, 3, 3);
00121 
00122   sData[0] = 0.0;
00123   sData[1] = 0.0;
00124   sData[2] = 0.0;
00125 
00126   for (int i=0; i<9; i++)
00127     kData[i] = 0.0;
00128 
00129   code(0) = SECTION_RESPONSE_P;
00130   code(1) = SECTION_RESPONSE_MZ;
00131   code(2) = SECTION_RESPONSE_MY;
00132 
00133 }
00134 
00135 int
00136 FiberSection3d::addFiber(Fiber &newFiber)
00137 {
00138   // need to create a larger array
00139   int newSize = numFibers+1;
00140 
00141   UniaxialMaterial **newArray = new UniaxialMaterial *[newSize]; 
00142   double *newMatData = new double [3 * newSize];
00143   
00144   if (newArray == 0 || newMatData == 0) {
00145     opserr << "FiberSection3d::addFiber -- failed to allocate Fiber pointers\n";
00146     exit(-1);
00147   }
00148 
00149   // copy the old pointers
00150   int i;
00151   for (i = 0; i < numFibers; i++) {
00152     newArray[i] = theMaterials[i];
00153     newMatData[3*i] = matData[3*i];
00154     newMatData[3*i+1] = matData[3*i+1];
00155     newMatData[3*i+2] = matData[3*i+2];
00156   }
00157   // set the new pointers
00158   double yLoc, zLoc, Area;
00159   newFiber.getFiberLocation(yLoc, zLoc);
00160   Area = newFiber.getArea();
00161   newMatData[numFibers*3] = -yLoc;
00162   newMatData[numFibers*3+1] = zLoc;
00163   newMatData[numFibers*3+2] = Area;
00164   UniaxialMaterial *theMat = newFiber.getMaterial();
00165   newArray[numFibers] = theMat->getCopy();
00166 
00167   if (newArray[numFibers] == 0) {
00168     opserr << "FiberSection3d::addFiber -- failed to get copy of a Material\n";
00169     exit(-1);
00170 
00171     delete [] newArray;
00172     delete [] newMatData;
00173     return -1;
00174   }
00175 
00176   numFibers++;
00177   
00178   if (theMaterials != 0) {
00179     delete [] theMaterials;
00180     delete [] matData;
00181   }
00182 
00183   theMaterials = newArray;
00184   matData = newMatData;
00185 
00186   double Qz = 0.0;
00187   double Qy = 0.0;
00188   double A  = 0.0;
00189 
00190   // Recompute centroid
00191   for (i = 0; i < numFibers; i++) {
00192     yLoc = -matData[3*i];
00193     zLoc = matData[3*i+1];
00194     Area = matData[3*i+2];
00195     A  += Area;
00196     Qz += yLoc*Area;
00197     Qy += zLoc*Area;
00198   }
00199 
00200   yBar = -Qz/A;
00201   zBar = Qy/A;
00202 
00203   return 0;
00204 }
00205 
00206 
00207 
00208 // destructor:
00209 FiberSection3d::~FiberSection3d()
00210 {
00211   if (theMaterials != 0) {
00212     for (int i = 0; i < numFibers; i++)
00213       if (theMaterials[i] != 0)
00214         delete theMaterials[i];
00215       
00216     delete [] theMaterials;
00217   }
00218 
00219   if (matData != 0)
00220     delete [] matData;
00221 
00222   if (s != 0)
00223     delete s;
00224 
00225   if (ks != 0)
00226     delete ks;
00227 }
00228 
00229 int
00230 FiberSection3d::setTrialSectionDeformation (const Vector &deforms)
00231 {
00232   int res = 0;
00233   e = deforms;
00234 
00235   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00236   kData[4] = 0.0; kData[5] = 0.0; kData[6] = 0.0; kData[7] = 0.0;
00237   kData[8] = 0.0; 
00238   sData[0] = 0.0; sData[1] = 0.0;  sData[2] = 0.0; 
00239 
00240   int loc = 0;
00241 
00242   double d0 = deforms(0);
00243   double d1 = deforms(1);
00244   double d2 = deforms(2);
00245 
00246   for (int i = 0; i < numFibers; i++) {
00247     UniaxialMaterial *theMat = theMaterials[i];
00248     double y = matData[loc++] - yBar;
00249     double z = matData[loc++] - zBar;
00250     double A = matData[loc++];
00251 
00252     // determine material strain and set it
00253     double strain = d0 + y*d1 + z*d2;
00254     double tangent, stress;
00255     res = theMat->setTrial(strain, stress, tangent);
00256 
00257     double value = tangent * A;
00258     double vas1 = y*value;
00259     double vas2 = z*value;
00260     double vas1as2 = vas1*z;
00261 
00262     kData[0] += value;
00263     kData[1] += vas1;
00264     kData[2] += vas2;
00265     
00266     kData[4] += vas1 * y;
00267     kData[5] += vas1as2;
00268     
00269     kData[8] += vas2 * z; 
00270 
00271     double fs0 = stress * A;
00272 
00273     sData[0] += fs0;
00274     sData[1] += fs0 * y;
00275     sData[2] += fs0 * z;
00276   }
00277 
00278   kData[3] = kData[1];
00279   kData[6] = kData[2];
00280   kData[7] = kData[5];
00281 
00282   return res;
00283 }
00284 
00285 const Matrix&
00286 FiberSection3d::getInitialTangent(void)
00287 {
00288   static double kInitialData[9];
00289   static Matrix kInitial(kInitialData, 3, 3);
00290   
00291   kInitialData[0] = 0.0; kInitialData[1] = 0.0; 
00292   kInitialData[2] = 0.0; kInitialData[3] = 0.0;
00293   kInitialData[4] = 0.0; kInitialData[5] = 0.0; 
00294   kInitialData[6] = 0.0; kInitialData[7] = 0.0;
00295   kInitialData[8] = 0.0; 
00296 
00297   int loc = 0;
00298 
00299   for (int i = 0; i < numFibers; i++) {
00300     UniaxialMaterial *theMat = theMaterials[i];
00301     double y = matData[loc++] - yBar;
00302     double z = matData[loc++] - zBar;
00303     double A = matData[loc++];
00304 
00305     double tangent = theMat->getInitialTangent();
00306 
00307     double value = tangent * A;
00308     double vas1 = y*value;
00309     double vas2 = z*value;
00310     double vas1as2 = vas1*z;
00311 
00312     kInitialData[0] += value;
00313     kInitialData[1] += vas1;
00314     kInitialData[2] += vas2;
00315     
00316     kInitialData[4] += vas1 * y;
00317     kInitialData[5] += vas1as2;
00318     
00319     kInitialData[8] += vas2 * z; 
00320   }
00321 
00322   kInitialData[3] = kInitialData[1];
00323   kInitialData[6] = kInitialData[2];
00324   kInitialData[7] = kInitialData[5];
00325 
00326   return kInitial;
00327 }
00328 
00329 const Vector&
00330 FiberSection3d::getSectionDeformation(void)
00331 {
00332   return e;
00333 }
00334 
00335 const Matrix&
00336 FiberSection3d::getSectionTangent(void)
00337 {
00338   return *ks;
00339 }
00340 
00341 const Vector&
00342 FiberSection3d::getStressResultant(void)
00343 {
00344   return *s;
00345 }
00346 
00347 SectionForceDeformation*
00348 FiberSection3d::getCopy(void)
00349 {
00350   FiberSection3d *theCopy = new FiberSection3d ();
00351   theCopy->setTag(this->getTag());
00352 
00353   theCopy->numFibers = numFibers;
00354 
00355   if (numFibers != 0) {
00356     theCopy->theMaterials = new UniaxialMaterial *[numFibers];
00357 
00358     if (theCopy->theMaterials == 0) {
00359       opserr << "FiberSection3d::FiberSection3d -- failed to allocate Material pointers\n";
00360       exit(-1);                     
00361     }
00362 
00363     theCopy->matData = new double [numFibers*3];
00364 
00365     if (theCopy->matData == 0) {
00366       opserr << "FiberSection3d::FiberSection3d -- failed to allocate double array for material data\n";
00367       exit(-1);
00368     }
00369                             
00370     
00371     for (int i = 0; i < numFibers; i++) {
00372       theCopy->matData[i*3] = matData[i*3];
00373       theCopy->matData[i*3+1] = matData[i*3+1];
00374       theCopy->matData[i*3+2] = matData[i*3+2];
00375       theCopy->theMaterials[i] = theMaterials[i]->getCopy();
00376 
00377       if (theCopy->theMaterials[i] == 0) {
00378         opserr << "FiberSection3d::getCopy -- failed to get copy of a Material\n";
00379         exit(-1);
00380       }
00381     }    
00382   }
00383 
00384   theCopy->eCommit = eCommit;
00385   theCopy->e = e;
00386   theCopy->yBar = yBar;
00387   theCopy->zBar = zBar;
00388 
00389   for (int i=0; i<9; i++)
00390     theCopy->kData[i] = kData[i];
00391 
00392   theCopy->sData[0] = sData[0];
00393   theCopy->sData[1] = sData[1];
00394   theCopy->sData[2] = sData[2];
00395 
00396   return theCopy;
00397 }
00398 
00399 const ID&
00400 FiberSection3d::getType ()
00401 {
00402   return code;
00403 }
00404 
00405 int
00406 FiberSection3d::getOrder () const
00407 {
00408   return 3;
00409 }
00410 
00411 int
00412 FiberSection3d::commitState(void)
00413 {
00414   int err = 0;
00415 
00416   for (int i = 0; i < numFibers; i++)
00417     err += theMaterials[i]->commitState();
00418 
00419   eCommit = e;
00420 
00421   return err;
00422 }
00423 
00424 int
00425 FiberSection3d::revertToLastCommit(void)
00426 {
00427   int err = 0;
00428 
00429   // Last committed section deformations
00430   e = eCommit;
00431 
00432 
00433   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00434   kData[4] = 0.0; kData[5] = 0.0; kData[6] = 0.0; kData[7] = 0.0;
00435   kData[8] = 0.0; 
00436   sData[0] = 0.0; sData[1] = 0.0;  sData[2] = 0.0; 
00437 
00438   int loc = 0;
00439 
00440   for (int i = 0; i < numFibers; i++) {
00441     UniaxialMaterial *theMat = theMaterials[i];
00442     double y = matData[loc++] - yBar;
00443     double z = matData[loc++] - zBar;
00444     double A = matData[loc++];
00445 
00446     // invoke revertToLast on the material
00447     err += theMat->revertToLastCommit();
00448 
00449     double tangent = theMat->getTangent();
00450     double stress = theMat->getStress();
00451 
00452     double value = tangent * A;
00453     double vas1 = y*value;
00454     double vas2 = z*value;
00455     double vas1as2 = vas1*z;
00456 
00457     kData[0] += value;
00458     kData[1] += vas1;
00459     kData[2] += vas2;
00460     
00461     kData[4] += vas1 * y;
00462     kData[5] += vas1as2;
00463     
00464     kData[8] += vas2 * z; 
00465 
00466     double fs0 = stress * A;
00467     sData[0] += fs0;
00468     sData[1] += fs0 * y;
00469     sData[2] += fs0 * z;
00470   }
00471 
00472   kData[3] = kData[1];
00473   kData[6] = kData[2];
00474   kData[7] = kData[5];
00475 
00476   return err;
00477 }
00478 
00479 int
00480 FiberSection3d::revertToStart(void)
00481 {
00482   // revert the fibers to start    
00483   int err = 0;
00484 
00485 
00486   kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00487   kData[4] = 0.0; kData[5] = 0.0; kData[6] = 0.0; kData[7] = 0.0;
00488   kData[8] = 0.0; 
00489   sData[0] = 0.0; sData[1] = 0.0;  sData[2] = 0.0; 
00490 
00491   int loc = 0;
00492 
00493   for (int i = 0; i < numFibers; i++) {
00494     UniaxialMaterial *theMat = theMaterials[i];
00495     double y = matData[loc++] - yBar;
00496     double z = matData[loc++] - zBar;
00497     double A = matData[loc++];
00498 
00499     // invoke revertToStart on the material
00500     err += theMat->revertToStart();
00501 
00502     double tangent = theMat->getTangent();
00503     double stress = theMat->getStress();
00504 
00505     double value = tangent * A;
00506     double vas1 = y*value;
00507     double vas2 = z*value;
00508     double vas1as2 = vas1*z;
00509 
00510     kData[0] += value;
00511     kData[1] += vas1;
00512     kData[2] += vas2;
00513     
00514     kData[4] += vas1 * y;
00515     kData[5] += vas1as2;
00516     
00517     kData[8] += vas2 * z; 
00518 
00519     double fs0 = stress * A;
00520     sData[0] += fs0;
00521     sData[1] += fs0 * y;
00522     sData[2] += fs0 * z;
00523   }
00524 
00525   kData[3] = kData[1];
00526   kData[6] = kData[2];
00527   kData[7] = kData[5];
00528 
00529   return err;
00530 }
00531 
00532 int
00533 FiberSection3d::sendSelf(int commitTag, Channel &theChannel)
00534 {
00535   int res = 0;
00536 
00537   // create an id to send objects tag and numFibers, 
00538   //     size 3 so no conflict with matData below if just 1 fiber
00539   static ID data(3);
00540   data(0) = this->getTag();
00541   data(1) = numFibers;
00542   int dbTag = this->getDbTag();
00543   res += theChannel.sendID(dbTag, commitTag, data);
00544   if (res < 0) {
00545     opserr << "FiberSection2d::sendSelf - failed to send ID data\n";
00546     return res;
00547   }    
00548 
00549   if (numFibers != 0) {
00550     
00551     // create an id containingg classTag and dbTag for each material & send it
00552     ID materialData(2*numFibers);
00553     for (int i=0; i<numFibers; i++) {
00554       UniaxialMaterial *theMat = theMaterials[i];
00555       materialData(2*i) = theMat->getClassTag();
00556       int matDbTag = theMat->getDbTag();
00557       if (matDbTag == 0) {
00558         matDbTag = theChannel.getDbTag();
00559         if (matDbTag != 0)
00560           theMat->setDbTag(matDbTag);
00561       }
00562       materialData(2*i+1) = matDbTag;
00563     }    
00564     
00565     res += theChannel.sendID(dbTag, commitTag, materialData);
00566     if (res < 0) {
00567      opserr << "FiberSection2d::sendSelf - failed to send material data\n";
00568      return res;
00569     }    
00570 
00571     // send the fiber data, i.e. area and loc
00572     Vector fiberData(matData, 3*numFibers);
00573     res += theChannel.sendVector(dbTag, commitTag, fiberData);
00574     if (res < 0) {
00575      opserr << "FiberSection2d::sendSelf - failed to send material data\n";
00576      return res;
00577     }    
00578 
00579     // now invoke send(0 on all the materials
00580     for (int j=0; j<numFibers; j++)
00581       theMaterials[j]->sendSelf(commitTag, theChannel);
00582   }
00583 
00584   return res;
00585 }
00586 
00587 int
00588 FiberSection3d::recvSelf(int commitTag, Channel &theChannel,
00589                          FEM_ObjectBroker &theBroker)
00590 {
00591   int res = 0;
00592 
00593   static ID data(3);
00594   
00595   int dbTag = this->getDbTag();
00596   res += theChannel.recvID(dbTag, commitTag, data);
00597 
00598   if (res < 0) {
00599    opserr << "FiberSection2d::sendSelf - failed to recv ID data\n";
00600    return res;
00601   } 
00602    
00603   this->setTag(data(0));
00604 
00605   // recv data about materials objects, classTag and dbTag
00606   if (data(1) != 0) {
00607     ID materialData(2*data(1));
00608     res += theChannel.recvID(dbTag, commitTag, materialData);
00609     if (res < 0) {
00610      opserr << "FiberSection2d::sendSelf - failed to send material data\n";
00611      return res;
00612     }    
00613 
00614     // if current arrays not of correct size, release old and resize
00615     if (theMaterials == 0 || numFibers != data(1)) {
00616       // delete old stuff if outa date
00617       if (theMaterials != 0) {
00618         for (int i=0; i<numFibers; i++)
00619           delete theMaterials[i];
00620         delete [] theMaterials;
00621         if (matData != 0)
00622           delete [] matData;
00623         matData = 0;
00624         theMaterials = 0;
00625       }
00626 
00627       // create memory to hold material pointers and fiber data
00628       numFibers = data(1);
00629       if (numFibers != 0) {
00630 
00631         theMaterials = new UniaxialMaterial *[numFibers];
00632         
00633         if (theMaterials == 0) {
00634           opserr << "FiberSection2d::recvSelf -- failed to allocate Material pointers\n";
00635           exit(-1);
00636         }
00637 
00638         for (int j=0; j<numFibers; j++)
00639           theMaterials[j] = 0;
00640         
00641         matData = new double [numFibers*3];
00642 
00643         if (matData == 0) {
00644           opserr << "FiberSection2d::recvSelf  -- failed to allocate double array for material data\n";
00645           exit(-1);
00646         }
00647       }
00648     }
00649 
00650     Vector fiberData(matData, 3*numFibers);
00651     res += theChannel.recvVector(dbTag, commitTag, fiberData);
00652     if (res < 0) {
00653      opserr << "FiberSection2d::sendSelf - failed to send material data\n";
00654      return res;
00655     }    
00656     
00657     int i;
00658     for (i=0; i<numFibers; i++) {
00659       int classTag = materialData(2*i);
00660       int dbTag = materialData(2*i+1);
00661 
00662       // if material pointed to is blank or not of corrcet type, 
00663       // release old and create a new one
00664       if (theMaterials[i] == 0)
00665         theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);
00666       else if (theMaterials[i]->getClassTag() != classTag) {
00667         delete theMaterials[i];
00668         theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);      
00669       }
00670 
00671       if (theMaterials[i] == 0) {
00672         opserr << "FiberSection2d::recvSelf -- failed to allocate double array for material data\n";
00673         exit(-1);
00674       }
00675 
00676       theMaterials[i]->setDbTag(dbTag);
00677       res += theMaterials[i]->recvSelf(commitTag, theChannel, theBroker);
00678     }
00679 
00680     double Qz = 0.0;
00681     double Qy = 0.0;
00682     double A  = 0.0;
00683     double yLoc, zLoc, Area;
00684 
00685     // Recompute centroid
00686     for (i = 0; i < numFibers; i++) {
00687       yLoc = -matData[3*i];
00688       zLoc = matData[3*i+1];
00689       Area = matData[3*i+2];
00690       A  += Area;
00691       Qz += yLoc*Area;
00692       Qy += zLoc*Area;
00693     }
00694     
00695     yBar = -Qz/A;
00696     zBar = Qy/A;
00697   }    
00698 
00699   return res;
00700 }
00701 
00702 void
00703 FiberSection3d::Print(OPS_Stream &s, int flag)
00704 {
00705   if (flag == 2) {
00706     for (int i = 0; i < numFibers; i++) {
00707       s << -matData[3*i] << " "  << matData[3*i+1] << " "  << matData[3*i+2] << " " ;
00708       s << theMaterials[i]->getStress() << " "  << theMaterials[i]->getStrain() << endln;
00709     } 
00710   } else {
00711     s << "\nFiberSection3d, tag: " << this->getTag() << endln;
00712     s << "\tSection code: " << code;
00713     s << "\tNumber of Fibers: " << numFibers << endln;
00714     s << "\tCentroid: (" << -yBar << ", " << zBar << ')' << endln;
00715     
00716     if (flag == 1) {
00717       for (int i = 0; i < numFibers; i++) {
00718         s << "\nLocation (y, z) = (" << -matData[3*i] << ", " << matData[3*i+1] << ")";
00719         s << "\nArea = " << matData[3*i+2] << endln;
00720       theMaterials[i]->Print(s, flag);
00721       }
00722     }
00723   }
00724 }
00725 
00726 Response*
00727 FiberSection3d::setResponse(const char **argv, int argc, Information &sectInfo, OPS_Stream &output)
00728 {
00729 
00730   const ID &type = this->getType();
00731   int typeSize = this->getOrder();
00732 
00733   Response *theResponse =0;
00734 
00735   output.tag("SectionOutput");
00736   output.attr("secType", this->getClassType());
00737   output.attr("secTag", this->getTag());
00738 
00739   // deformations
00740   if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) {
00741     for (int i=0; i<typeSize; i++) {
00742       int code = type(i);
00743       switch (code){
00744       case SECTION_RESPONSE_MZ:
00745         output.tag("ResponseType","kappaZ");
00746         break;
00747       case SECTION_RESPONSE_P:
00748         output.tag("ResponseType","eps");
00749         break;
00750       case SECTION_RESPONSE_VY:
00751         output.tag("ResponseType","gammaY");
00752         break;
00753       case SECTION_RESPONSE_MY:
00754         output.tag("ResponseType","kappaY");
00755         break;
00756       case SECTION_RESPONSE_VZ:
00757         output.tag("ResponseType","gammaZ");
00758         break;
00759       case SECTION_RESPONSE_T:
00760         output.tag("ResponseType","theta");
00761         break;
00762       default:
00763         output.tag("ResponseType","Unknown");
00764       }
00765     }
00766     theResponse =  new MaterialResponse(this, 1, this->getSectionDeformation());
00767   
00768   // forces
00769   } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) {
00770     for (int i=0; i<typeSize; i++) {
00771       int code = type(i);
00772       switch (code){
00773       case SECTION_RESPONSE_MZ:
00774         output.tag("ResponseType","Mz");
00775         break;
00776       case SECTION_RESPONSE_P:
00777         output.tag("ResponseType","P");
00778         break;
00779       case SECTION_RESPONSE_VY:
00780         output.tag("ResponseType","Vy");
00781         break;
00782       case SECTION_RESPONSE_MY:
00783         output.tag("ResponseType","My");
00784         break;
00785       case SECTION_RESPONSE_VZ:
00786         output.tag("ResponseType","Vz");
00787         break;
00788       case SECTION_RESPONSE_T:
00789         output.tag("ResponseType","T");
00790         break;
00791       default:
00792         output.tag("ResponseType","Unknown");
00793       }
00794     }
00795     theResponse =  new MaterialResponse(this, 2, this->getStressResultant());
00796   
00797   // force and deformation
00798   } else if (strcmp(argv[0],"forceAndDeformation") == 0) { 
00799     for (int i=0; i<typeSize; i++) {
00800       int code = type(i);
00801       switch (code){
00802       case SECTION_RESPONSE_MZ:
00803         output.tag("ResponseType","kappaZ");
00804         break;
00805       case SECTION_RESPONSE_P:
00806         output.tag("ResponseType","eps");
00807         break;
00808       case SECTION_RESPONSE_VY:
00809         output.tag("ResponseType","gammaY");
00810         break;
00811       case SECTION_RESPONSE_MY:
00812         output.tag("ResponseType","kappaY");
00813         break;
00814       case SECTION_RESPONSE_VZ:
00815         output.tag("ResponseType","gammaZ");
00816         break;
00817       case SECTION_RESPONSE_T:
00818         output.tag("ResponseType","theta");
00819         break;
00820       default:
00821         output.tag("ResponseType","Unknown");
00822       }
00823     }
00824     for (int j=0; j<typeSize; j++) {
00825       int code = type(j);
00826       switch (code){
00827       case SECTION_RESPONSE_MZ:
00828         output.tag("ResponseType","Mz");
00829         break;
00830       case SECTION_RESPONSE_P:
00831         output.tag("ResponseType","P");
00832         break;
00833       case SECTION_RESPONSE_VY:
00834         output.tag("ResponseType","Vy");
00835         break;
00836       case SECTION_RESPONSE_MY:
00837         output.tag("ResponseType","My");
00838         break;
00839       case SECTION_RESPONSE_VZ:
00840         output.tag("ResponseType","Vz");
00841         break;
00842       case SECTION_RESPONSE_T:
00843         output.tag("ResponseType","T");
00844         break;
00845       default:
00846         output.tag("ResponseType","Unknown");
00847       }
00848     }
00849 
00850     theResponse =  new MaterialResponse(this, 4, Vector(2*this->getOrder()));
00851   
00852   }  
00853   
00854   else {
00855     if (argc > 2 || strcmp(argv[0],"fiber") == 0) {
00856 
00857 
00858       int key = numFibers;
00859       int passarg = 2;
00860       
00861       
00862       if (argc <= 3)    {  // fiber number was input directly
00863         
00864         key = atoi(argv[1]);
00865         
00866       } else if (argc > 4) {         // find fiber closest to coord. with mat tag
00867         int matTag = atoi(argv[3]);
00868         double yCoord = atof(argv[1]);
00869         double zCoord = atof(argv[2]);
00870         double closestDist;
00871         double ySearch, zSearch, dy, dz;
00872         double distance;
00873         int j;
00874         
00875         // Find first fiber with specified material tag
00876         for (j = 0; j < numFibers; j++) {
00877           if (matTag == theMaterials[j]->getTag()) {
00878             ySearch = -matData[3*j];
00879             zSearch =  matData[3*j+1];
00880             dy = ySearch-yCoord;
00881             dz = zSearch-zCoord;
00882             closestDist = sqrt(dy*dy + dz*dz);
00883             key = j;
00884             break;
00885           }
00886         }
00887         
00888         // Search the remaining fibers
00889         for ( ; j < numFibers; j++) {
00890           if (matTag == theMaterials[j]->getTag()) {
00891             ySearch = -matData[3*j];
00892             zSearch =  matData[3*j+1];
00893             dy = ySearch-yCoord;
00894             dz = zSearch-zCoord;
00895             distance = sqrt(dy*dy + dz*dz);
00896             if (distance < closestDist) {
00897               closestDist = distance;
00898               key = j;
00899             }
00900           }
00901         }
00902         passarg = 4;
00903       }
00904       
00905       else {                  // fiber near-to coordinate specified
00906         double yCoord = atof(argv[1]);
00907         double zCoord = atof(argv[2]);
00908         double closestDist;
00909         double ySearch, zSearch, dy, dz;
00910         double distance;
00911         ySearch = -matData[0];
00912         zSearch =  matData[1];
00913         dy = ySearch-yCoord;
00914         dz = zSearch-zCoord;
00915         closestDist = sqrt(dy*dy + dz*dz);
00916         key = 0;
00917         for (int j = 1; j < numFibers; j++) {
00918           ySearch = -matData[3*j];
00919           zSearch =  matData[3*j+1];
00920           dy = ySearch-yCoord;
00921           dz = zSearch-zCoord;
00922           distance = sqrt(dy*dy + dz*dz);
00923           if (distance < closestDist) {
00924             closestDist = distance;
00925             key = j;
00926           }
00927         }
00928         passarg = 3;
00929       }
00930       
00931       if (key < numFibers && key >= 0) {
00932         output.tag("FiberOutput");
00933         output.attr("yLoc",-matData[2*key]);
00934         output.attr("zLoc",matData[2*key+1]);
00935         output.attr("area",matData[2*key+2]);
00936         
00937         theResponse =  theMaterials[key]->setResponse(&argv[passarg], argc-passarg, sectInfo, output);
00938         
00939         output.endTag();
00940       }
00941     }
00942   }
00943 
00944   output.endTag();
00945   return theResponse;
00946 }
00947 
00948 
00949 int 
00950 FiberSection3d::getResponse(int responseID, Information &sectInfo)
00951 {
00952   // Just call the base class method ... don't need to define
00953   // this function, but keeping it here just for clarity
00954   return SectionForceDeformation::getResponse(responseID, sectInfo);
00955 }
00956 
00957 int
00958 FiberSection3d::setParameter(const char **argv, int argc, Parameter &param)
00959 {
00960   if (argc < 3)
00961     return -1;
00962 
00963   // A material parameter
00964   if (strstr(argv[0],"material") != 0) {
00965 
00966     // Get the tag of the material
00967     int paramMatTag = atoi(argv[1]);
00968 
00969     // Loop over fibers to find the right material(s)
00970     int ok = 0;
00971     for (int i = 0; i < numFibers; i++)
00972       if (paramMatTag == theMaterials[i]->getTag())
00973         ok += theMaterials[i]->setParameter(&argv[2], argc-2, param);
00974 
00975     return ok;
00976   }
00977 
00978   else
00979     return -1;
00980 }

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