FiberSection.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.6 $
00022 // $Date: 2003/02/25 23:33:33 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSection.cpp,v $
00024                                                                         
00025 // Written: MHS
00026 // Created: Aug 2000
00027 //
00028 // Description: This file contains the class definition for 
00029 // FiberSection.h. FiberSection provides the abstraction of a 
00030 // section discretized by fibers. The section stiffness and
00031 // stress resultants are obtained by summing fiber contributions.
00032 
00033 #include <stdlib.h>
00034 
00035 #include <Channel.h>
00036 #include <Vector.h>
00037 #include <Matrix.h>
00038 #include <MatrixUtil.h>
00039 #include <Fiber.h>
00040 #include <classTags.h>
00041 #include <FiberSection.h>
00042 #include <ID.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <Information.h>
00045 #include <MaterialResponse.h>
00046 
00047 // constructors:
00048 FiberSection::FiberSection(int tag, int num, Fiber **fibers): 
00049   SectionForceDeformation(tag, SEC_TAG_Fiber),
00050   numFibers(num), theFibers(0), sizeFibers(num),
00051   e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
00052 {
00053     theFibers = new Fiber *[numFibers];
00054 
00055     if (theFibers == 0)
00056                 g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00057                         "FiberSection::FiberSection");
00058 
00059     for (int i = 0; i < numFibers; i++) {
00060                 theFibers[i] = fibers[i]->getCopy();
00061 
00062                 if (theFibers[i] == 0)
00063                         g3ErrorHandler->fatal("%s -- failed to get copy of Fiber",
00064                                 "FiberSection::FiberSection");
00065     }
00066 
00067         order = theFibers[0]->getOrder();
00068 
00069         e = new Vector(order);
00070         eCommit = new Vector(order);
00071         s = new Vector(order);
00072         ks = new Matrix(order,order);
00073 
00074         code = new ID(order);
00075         *code = theFibers[0]->getType();
00076 }
00077 
00078 // constructor for blank object that recvSelf needs to be invoked upon
00079 FiberSection::FiberSection():
00080   SectionForceDeformation(0, SEC_TAG_Fiber),
00081   numFibers(0), theFibers(0), sizeFibers(0),
00082   e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
00083 {
00084 
00085 }
00086 
00087 FiberSection::FiberSection(int tag, int num):
00088   SectionForceDeformation(tag, SEC_TAG_Fiber),
00089   numFibers(0), theFibers(0), sizeFibers(num),
00090   e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
00091 {
00092         // check for zero -- if zero make initial size 2
00093         if (sizeFibers == 0)
00094                 sizeFibers = 2;
00095 
00096         // create the array of fiber pointers
00097         theFibers = new Fiber *[sizeFibers];
00098 
00099         if (theFibers == 0) {
00100                 g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00101                         "FiberSection::FiberSection");
00102 
00103                 sizeFibers  = 0;
00104         }
00105 
00106         // zero the pointers
00107         for (int i = 0; i < sizeFibers; i++)
00108                 theFibers[i] =0;
00109 }
00110 
00111 int
00112 FiberSection::addFiber(Fiber &newFiber)
00113 {
00114         if (order == 0) {
00115                 order = newFiber.getOrder();
00116 
00117                 e = new Vector(order);
00118                 eCommit = new Vector(order);
00119                 s = new Vector(order);
00120                 ks = new Matrix(order,order);
00121 
00122                 code = new ID(order);
00123                 *code = newFiber.getType();
00124         }
00125 
00126         if (numFibers < sizeFibers) {
00127                 // space available in array .. set new pointer and increment number
00128                 theFibers[numFibers] = &newFiber;
00129                 numFibers++;
00130         }
00131         else {
00132                 // need to create a larger array
00133                 int newSize = 2*numFibers;
00134                 if (newSize == 0) 
00135                         newSize = 2; // in case failed in constructor
00136 
00137                 Fiber **newArray = new Fiber *[newSize]; 
00138 
00139             if (newArray == 0) {
00140                         g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00141                                 "FiberSection::addFiber");
00142 
00143                         sizeFibers  = 0;
00144 
00145                         return -1;
00146                 }
00147 
00148                 // set the new size of the array
00149                 sizeFibers = newSize;
00150 
00151                 // copy the old pointers
00152                 for (int i = 0; i < numFibers; i++)
00153                         newArray[i] = theFibers[i];
00154 
00155                 // add the new pointer
00156                 newArray[numFibers] = &newFiber;
00157                 numFibers++;
00158 
00159                 // zero the last elements of the array
00160                 for (int j = numFibers; j < newSize; j++) 
00161                         newArray[j] = 0;
00162     
00163                 delete [] theFibers;
00164                 
00165                 theFibers = newArray;
00166         }
00167   
00168         return 0;
00169 }
00170 
00171 // destructor:
00172 FiberSection::~FiberSection()
00173 {
00174         if (theFibers) {
00175                 for (int i = 0; i < numFibers; i++)
00176                         if (theFibers[i])
00177                                 delete theFibers[i];
00178       
00179                 delete [] theFibers;
00180         }
00181 
00182         if (e)
00183                 delete e;
00184         if (eCommit)
00185                 delete eCommit;
00186         if (s)
00187                 delete s;
00188         if (ks)
00189                 delete ks;
00190         if (code)
00191                 delete code;
00192 }
00193 
00194 int FiberSection::setTrialSectionDeformation (const Vector &deforms)
00195 {
00196         int res = 0;
00197 
00198         *e = deforms;
00199 
00200         for (int i = 0; i < numFibers; i++)
00201                 res += theFibers[i]->setTrialFiberStrain(deforms);
00202 
00203         return res;
00204 }
00205 
00206 const Vector&
00207 FiberSection::getSectionDeformation(void)
00208 {
00209         return *e;
00210 }
00211 
00212 const Matrix&
00213 FiberSection::getSectionTangent(void)
00214 {
00215         ks->Zero();
00216  
00217         for (int i = 0; i < numFibers; i++)
00218                 ks->addMatrix(1.0, theFibers[i]->getFiberTangentStiffContr(), 1.0);
00219 
00220         return *ks;
00221 }
00222 
00223 const Vector&
00224 FiberSection::getStressResultant(void)
00225 {
00226         s->Zero();
00227  
00228         for (int i = 0; i < numFibers; i++)
00229                 s->addVector(1.0, theFibers[i]->getFiberStressResultants(), 1.0);
00230 
00231         return *s;
00232 }
00233 
00234 SectionForceDeformation*
00235 FiberSection::getCopy(void)
00236 {
00237         FiberSection *theCopy = new FiberSection (this->getTag(), numFibers, theFibers);
00238   
00239         *(theCopy->eCommit) = *eCommit;
00240 
00241         return theCopy;
00242 }
00243 
00244 const ID&
00245 FiberSection::getType ()
00246 {
00247     return *code;
00248 }
00249 
00250 int
00251 FiberSection::getOrder () const
00252 {
00253     return order;
00254 }
00255 
00256 int
00257 FiberSection::commitState(void)
00258 {
00259         // commit the fibers state
00260         int err = 0;
00261 
00262         for (int i = 0; i < numFibers; i++)
00263                 err += theFibers[i]->commitState();
00264 
00265         *eCommit = *e;
00266 
00267         return err;
00268 }
00269 
00270 int
00271 FiberSection::revertToLastCommit(void)
00272 {
00273         int err = 0;
00274 
00275         // Last committed section deformations
00276         *e = *eCommit;
00277 
00278         s->Zero();
00279         ks->Zero();
00280 
00281         for (int i = 0; i < numFibers; i++) {
00282                 // Revert the fiber ...
00283                 err += theFibers[i]->revertToLastCommit();
00284                 
00285                 // ... now recompute the section stress resultant and tangent stiffness
00286                 theFibers[i]->setTrialFiberStrain(*e);
00287                 s->addVector(1.0, theFibers[i]->getFiberStressResultants(), 1.0);
00288                 ks->addMatrix(1.0, theFibers[i]->getFiberTangentStiffContr(), 1.0);
00289         }
00290 
00291         return err;
00292 }
00293 
00294 int
00295 FiberSection::revertToStart(void)
00296 {
00297         // revert the fibers to start    
00298         int err = 0;
00299    
00300         for (int i = 0; i < numFibers; i++)
00301                 err += theFibers[i]->revertToStart();
00302     
00303         eCommit->Zero();
00304 
00305         return err;
00306 }
00307 
00308 int
00309 FiberSection::sendSelf(int commitTag, Channel &theChannel)
00310 {
00311         int res = 0;
00312 
00313         // Need two dbTags since data and dbTag ID vectors could be the same size
00314         if (otherDbTag == 0)
00315                 otherDbTag = theChannel.getDbTag();
00316 
00317         // Create an ID with tag, number and size of fibers, and section order
00318         static ID data(5);
00319 
00320         data(0) = this->getTag();
00321         data(1) = numFibers;
00322         data(2) = sizeFibers;
00323         data(3) = order;
00324         data(4) = otherDbTag;
00325 
00326         // Send the data ID
00327         res += theChannel.sendID(this->getDbTag(), commitTag, data);
00328         if (res < 0) {
00329                 g3ErrorHandler->warning("%s -- failed to send data ID",
00330                         "FiberSection::sendSelf");
00331                 return res;
00332         }
00333 
00334         if (order > 0) {
00335                 // Send the committed section deformations
00336                 res += theChannel.sendVector(this->getDbTag(), commitTag, *eCommit);
00337                 if (res < 0) {
00338                         g3ErrorHandler->warning("%s -- failed to send section deformations",
00339                                 "FiberSection::sendSelf");
00340                         return res;
00341                 }
00342         }
00343 
00344         // If there are any fibers to send ...
00345         if (numFibers > 0) {
00346                 // Create an ID for fiber dbTags
00347                 ID dbTags(numFibers+1);
00348                 
00349                 int i;
00350                 int dbTag;
00351                 for (i = 0; i < numFibers; i++) {
00352                         dbTag = theFibers[i]->getDbTag();
00353 
00354                         if (dbTag == 0) {
00355                                 dbTag = theChannel.getDbTag();
00356                                 if (dbTag != 0)
00357                                         theFibers[i]->setDbTag(dbTag);
00358                         }
00359 
00360                         dbTags(i) = dbTag;
00361                 }
00362         
00363                 // Get class tag from first fiber
00364                 dbTags(numFibers) = theFibers[0]->getClassTag();
00365 
00366                 // Send the dbTags ID
00367                 res += theChannel.sendID(otherDbTag, commitTag, dbTags);
00368                 if (res < 0) {
00369                         g3ErrorHandler->warning("%s -- failed to send dbTags ID",
00370                                 "FiberSection::sendSelf");
00371                         return res;
00372                 }
00373 
00374                 // Ask the fibers to send themselves
00375                 for (i = 0; i < numFibers; i++) {
00376                         res += theFibers[i]->sendSelf(commitTag, theChannel);
00377                         if (res < 0) {
00378                                 g3ErrorHandler->warning("%s -- failed to send Fiber %d",
00379                                         "FiberSection::sendSelf", i);
00380                                 return res;
00381                         }
00382                 }
00383         }
00384 
00385         return res;
00386 }
00387 
00388 int
00389 FiberSection::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00390 {
00391         int res = 0;
00392 
00393         // Create an ID for tag, number and size of fibers, and section order
00394         static ID data(5);
00395 
00396         // Receive the data ID
00397         res += theChannel.recvID(this->getDbTag(), commitTag, data);
00398         if (res < 0) {
00399                 g3ErrorHandler->warning("%s -- failed to receive data ID",
00400                         "FiberSection::recvSelf");
00401                 return res;
00402         }
00403 
00404         this->setTag(data(0));
00405         numFibers = data(1);
00406         sizeFibers = data(2);
00407         order = data(3);
00408         otherDbTag = data(4);
00409 
00410         // Check that section variables are of the right size, allocate if needed
00411         if (order > 0) {
00412                 if (e == 0)     
00413                         e = new Vector(order);
00414                 if (eCommit == 0)       
00415                         eCommit = new Vector(order);
00416                 if (s == 0) 
00417                         s = new Vector(order);
00418                 if (ks == 0) 
00419                         ks = new Matrix(order,order);
00420                 if (code == 0) 
00421                         code = new ID(order);
00422 
00423                 if (e->Size() != order) {
00424                         delete e;
00425                         e = new Vector(order);
00426                 }
00427                 if (eCommit->Size() != order) {
00428                         delete eCommit;
00429                         eCommit = new Vector(order);
00430                 }
00431                 if (s->Size() != order) {
00432                         delete s;
00433                         s = new Vector(order);
00434                 }
00435                 if (ks->noRows() != order) {
00436                         delete ks;
00437                         ks = new Matrix(order,order);
00438                 }
00439                 if (code->Size() != order) {
00440                         delete code;
00441                         code = new ID(order);
00442                 }
00443 
00444                 // Receive the committed section deformation
00445                 res += theChannel.recvVector(this->getDbTag(), commitTag, *eCommit);
00446                 if (res < 0) {
00447                         g3ErrorHandler->warning("%s -- failed to receive section deformations",
00448                                 "FiberSection::recvSelf");
00449                         return res;
00450                 }
00451 
00452                 *e = *eCommit;
00453         }
00454 
00455         if (numFibers > 0) {
00456                 // Create an ID for fiber dbTags
00457                 ID dbTags(numFibers+1);
00458 
00459                 // Receive the dbTags ID
00460                 res += theChannel.recvID(otherDbTag, commitTag, dbTags);
00461                 if (res < 0) {
00462                         g3ErrorHandler->warning("%s -- failed to receive dbTags ID",
00463                                 "FiberSection::recvSelf");
00464                         return res;
00465                 }
00466 
00467                 int i;
00468 
00469                 if (theFibers == 0) {
00470                         theFibers = new Fiber *[sizeFibers];
00471                         if (theFibers == 0) {
00472                                 g3ErrorHandler->warning("%s -- failed to allocate Fiber pointers",
00473                                         "FiberSection::recvSelf");
00474                                 return -1;
00475                         }
00476                         for (i = 0; i < sizeFibers; i++)
00477                                 theFibers[i] = 0;
00478                 }
00479 
00480                 int fiberClassTag = dbTags(numFibers);
00481                 for (i = 0; i < numFibers; i++) {
00482                         // Check for null fiber, allocate if so
00483                         if (theFibers[i] == 0)
00484                                 theFibers[i] = theBroker.getNewFiber(fiberClassTag);
00485                 
00486                         // Check that the Fiber is of the right type; if not, delete
00487                         // the current one and get a new one of the right type
00488                         else if (theFibers[i]->getClassTag() != fiberClassTag) {
00489                                 delete theFibers[i];
00490                                 theFibers[i] = theBroker.getNewFiber(fiberClassTag);
00491                         }
00492 
00493                         // Check if either allocation failed
00494                         if (theFibers[i] == 0) {
00495                                 g3ErrorHandler->warning("%s -- could not get Fiber %d",
00496                                         "FiberSection::recvSelf", i);
00497                                 return -1;
00498                         }
00499 
00500                         // Now, receive the Fiber
00501                         theFibers[i]->setDbTag(dbTags(i));
00502                         res += theFibers[i]->recvSelf(commitTag, theChannel, theBroker);
00503                         if (res < 0) {
00504                                 g3ErrorHandler->warning("%s -- could not receive Fiber %d",
00505                                         "FiberSection::recvSelf", i);
00506                                 return res;
00507                         }
00508                 }
00509 
00510                 // Reset the section code
00511                 *code = theFibers[0]->getType();
00512         }
00513 
00514         //this->revertToLastCommit();
00515         
00516         return res;
00517 }
00518 
00519 void
00520 FiberSection::Print(OPS_Stream &s, int flag)
00521 {
00522         s << "\nFiberSection, tag: " << this->getTag() << endln;
00523         s << "\tSection code: " << *code;
00524         s << "\tNumber of Fibers: " << numFibers << endln;
00525         
00526         if (flag == 1)
00527                 for (int i = 0; i < numFibers; i++)
00528                         theFibers[i]->Print(s, flag);
00529 }
00530 
00531 Response*
00532 FiberSection::setResponse(const char **argv, int argc, Information &sectInfo)
00533 {
00534         // See if the response is one of the defaults
00535         Response *res = SectionForceDeformation::setResponse(argv, argc, sectInfo);
00536         if (res != 0)
00537                 return res;
00538 
00539         // Check if fiber response is requested
00540     else if (strcmp(argv[0],"fiber") == 0) {
00541         int key = 0;
00542         int passarg = 2;
00543 
00544         if (argc <= 2)          // not enough data input
00545             return 0;
00546         else if (argc <= 3)             // fiber number was input directly
00547             key = atoi(argv[1]);
00548         else {                  // fiber near-to coordinate specified
00549             double yCoord = atof(argv[1]);
00550                         double zCoord = atof(argv[2]);
00551                         double ySearch, zSearch;
00552                 theFibers[0]->getFiberLocation(ySearch,zSearch);
00553                         double closestDist = sqrt( pow(ySearch-yCoord,2) +
00554                                  pow(zSearch-zCoord,2) );
00555                         double distance;
00556                         for (int j = 1; j < numFibers; j++) {
00557                                 theFibers[j]->getFiberLocation(ySearch,zSearch);
00558                                 distance = sqrt( pow(ySearch-yCoord,2) +
00559                                  pow(zSearch-zCoord,2) );
00560                                 if (distance < closestDist) {
00561                                         closestDist = distance;
00562                                         key = j;
00563                                 }
00564                         }
00565                         theFibers[key]->getFiberLocation(ySearch,zSearch);
00566                     passarg = 3;
00567                 }
00568         
00569         if (key < numFibers)
00570                         return theFibers[key]->setResponse(&argv[passarg],argc-passarg,sectInfo);
00571         else
00572             return 0;
00573     }
00574                         
00575     // otherwise response quantity is unknown for the FiberSection class
00576     else
00577                 return 0;    
00578 }
00579 
00580 int 
00581 FiberSection::getResponse(int responseID, Information &sectInfo)
00582 {
00583         // Just call the base class method ... don't need to define
00584         // this function, but keeping it here just for clarity
00585         return SectionForceDeformation::getResponse(responseID, sectInfo);
00586 }

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