SectionAggregator.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.13 $
00022 // $Date: 2006/09/05 23:30:03 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/section/SectionAggregator.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/section/SectionAggregator.C
00027 //
00028 // Written: MHS
00029 // Created: June 2000
00030 // Revision: A
00031 //
00032 // Purpose: This file contains the implementation for the SectionAggregator class. 
00033 
00034 #include <stdlib.h>
00035 
00036 #include <Channel.h>
00037 #include <FEM_ObjectBroker.h>
00038 #include <Vector.h>
00039 #include <Matrix.h>
00040 #include <MatrixUtil.h>
00041 #include <classTags.h>
00042 #include <SectionAggregator.h>
00043 #include <MaterialResponse.h>
00044 #include <ID.h>
00045 
00046 #include <classTags.h>
00047 
00048 #define maxOrder 10
00049 
00050 // Assumes section order is less than or equal to maxOrder.
00051 // Can increase if needed!!!
00052 double SectionAggregator::workArea[2*maxOrder*(maxOrder+1)];
00053 int    SectionAggregator::codeArea[maxOrder];
00054 
00055 // constructors:
00056 SectionAggregator::SectionAggregator (int tag, SectionForceDeformation &theSec,
00057                                       int numAdds, UniaxialMaterial **theAdds,
00058                                       const ID &addCodes): 
00059   SectionForceDeformation(tag, SEC_TAG_Aggregator), 
00060   theSection(0), theAdditions(0), matCodes(0), numMats(numAdds),
00061   e(0), s(0), ks(0), fs(0), theCode(0),
00062   otherDbTag(0)
00063 {
00064     theSection = theSec.getCopy();
00065     
00066     if (!theSection) {
00067       opserr << "SectionAggregator::SectionAggregator -- failed to get copy of section\n";
00068       exit(-1);
00069     }
00070 
00071     if (!theAdds) {
00072       opserr << "SectionAggregator::SectionAggregator -- null uniaxial material array passed\n";
00073       exit(-1);
00074     }
00075     theAdditions = new UniaxialMaterial *[numMats];
00076 
00077     if (!theAdditions) {
00078       opserr << "SectionAggregator::SectionAggregator -- failed to allocate pointers\n";
00079       exit(-1);
00080     }    
00081     int i;
00082     
00083     for (i = 0; i < numMats; i++) {
00084       if (!theAdds[i]) {
00085         opserr << "SectionAggregator::SectionAggregator -- null uniaxial material pointer passed\n";
00086         exit(-1);
00087       } 
00088       theAdditions[i] = theAdds[i]->getCopy(this);
00089       
00090       if (!theAdditions[i]) {
00091         opserr << "SectionAggregator::SectionAggregator -- failed to copy uniaxial material\n";
00092         exit(-1);
00093       }
00094     }
00095 
00096     int order = theSec.getOrder()+numAdds;
00097 
00098     if (order > maxOrder) {
00099       opserr << "SectionAggregator::SectionAggregator -- order too big, need to modify the #define in SectionAggregator.cpp to " <<
00100         order << endln;
00101       exit(-1);
00102     }
00103 
00104     theCode = new ID(codeArea, order);
00105     e = new Vector(workArea, order);
00106     s = new Vector(&workArea[maxOrder], order);
00107     ks = new Matrix(&workArea[2*maxOrder], order, order);
00108     fs = new Matrix(&workArea[maxOrder*(maxOrder+2)], order, order);
00109     matCodes = new ID(addCodes);
00110 
00111     if (theCode == 0 || e == 0 || s == 0 || ks == 0 || fs == 0 || matCodes == 0) {
00112       opserr << "SectionAggregator::SectionAggregator -- out of memory\n";
00113       exit(-1);
00114     }   
00115 }
00116 
00117 SectionAggregator::SectionAggregator (int tag, int numAdds,
00118                                       UniaxialMaterial **theAdds,
00119                                       const ID &addCodes): 
00120   SectionForceDeformation(tag, SEC_TAG_Aggregator), 
00121   theSection(0), theAdditions(0), matCodes(0), numMats(numAdds),
00122   e(0), s(0), ks(0), fs(0), theCode(0),
00123   otherDbTag(0)
00124 {
00125   if (!theAdds) {
00126     opserr << "SectionAggregator::SectionAggregator -- null uniaxial material array passed\n";
00127     exit(-1);
00128   }
00129 
00130   theAdditions = new UniaxialMaterial *[numMats];
00131 
00132   if (!theAdditions) {
00133     opserr << "SectionAggregator::SectionAggregator -- failed to allocate pointers\n";
00134     exit(-1);
00135   }    
00136     int i;
00137     
00138     for (i = 0; i < numMats; i++) {
00139       if (!theAdds[i]) {
00140         opserr << "SectionAggregator::SectionAggregator -- null uniaxial material pointer passed\n";
00141         exit(-1);
00142       }         
00143         
00144       theAdditions[i] = theAdds[i]->getCopy(this);
00145       
00146       if (!theAdditions[i]) {
00147         opserr << "SectionAggregator::SectionAggregator -- failed to copy uniaxial material\n";
00148         exit(-1);
00149       }
00150     }
00151 
00152     int order = numAdds;
00153 
00154     if (order > maxOrder) {
00155       opserr << "SectionAggregator::SectionAggregator -- order too big, need to modify the #define in SectionAggregator.cpp to %d\n";
00156       exit(-1);
00157     }
00158 
00159     theCode = new ID(codeArea, order);
00160     e = new Vector(workArea, order);
00161     s = new Vector(&workArea[maxOrder], order);
00162     ks = new Matrix(&workArea[2*maxOrder], order, order);
00163     fs = new Matrix(&workArea[maxOrder*(maxOrder+2)], order, order);
00164     matCodes = new ID(addCodes);
00165 
00166     if (theCode == 0 || e == 0 || s == 0 || ks == 0 || fs == 0 || matCodes == 0) {
00167       opserr << "SectionAggregator::SectionAggregator -- out of memory\n";
00168       exit(-1);
00169     }
00170 }
00171 
00172 SectionAggregator::SectionAggregator (int tag, SectionForceDeformation &theSec,
00173                                       UniaxialMaterial &theAddition, int c) :
00174   SectionForceDeformation(tag, SEC_TAG_Aggregator),
00175   theSection(0), theAdditions(0), matCodes(0), numMats(1),
00176   e(0), s(0), ks(0), fs(0), theCode(0),
00177   otherDbTag(0)
00178 {
00179   theSection = theSec.getCopy();
00180   
00181   if (!theSection) {
00182     opserr << "SectionAggregator::SectionAggregator -- failed to get copy of section\n";
00183     exit(-1);
00184   }
00185 
00186   theAdditions = new UniaxialMaterial *[1];
00187   
00188   theAdditions[0] = theAddition.getCopy(this);
00189   
00190   if (!theAdditions[0]) {
00191     opserr << "SectionAggregator::SectionAggregator -- failed to copy uniaxial material\n";
00192     exit(-1);
00193   }
00194     
00195   matCodes = new ID(1);
00196   (*matCodes)(0) = c;
00197   
00198   int order = theSec.getOrder()+1;
00199   
00200   if (order > maxOrder) {
00201     opserr << "SectionAggregator::SectionAggregator -- order too big, need to modify the #define in SectionAggregator.cpp to %d\n";
00202     exit(-1);
00203   }
00204   
00205   theCode = new ID(codeArea, order);
00206   e = new Vector(workArea, order);
00207   s = new Vector(&workArea[maxOrder], order);
00208   ks = new Matrix(&workArea[2*maxOrder], order, order);
00209   fs = new Matrix(&workArea[maxOrder*(maxOrder+2)], order, order);
00210   
00211   if (theCode == 0 || e == 0 || s == 0 || ks == 0 || fs == 0 || matCodes == 0) {
00212     opserr << "SectionAggregator::SectionAggregator -- out of memory\n";
00213     exit(-1);
00214   }
00215 }
00216 
00217 // constructor for blank object that recvSelf needs to be invoked upon
00218 SectionAggregator::SectionAggregator():
00219   SectionForceDeformation(0, SEC_TAG_Aggregator),
00220   theSection(0), theAdditions(0), matCodes(0), numMats(0), 
00221   e(0), s(0), ks(0), fs(0), theCode(0),
00222   otherDbTag(0)
00223 {
00224 
00225 }
00226 
00227 // destructor:
00228 SectionAggregator::~SectionAggregator()
00229 {
00230    int i;
00231 
00232    if (theSection)
00233        delete theSection;
00234 
00235    for (i = 0; i < numMats; i++)
00236        if (theAdditions[i])
00237            delete theAdditions[i];
00238 
00239    if (theAdditions)
00240        delete [] theAdditions;
00241    
00242    if (e != 0)
00243      delete e;
00244 
00245    if (s != 0)
00246      delete s;
00247 
00248    if (ks != 0)
00249      delete ks;
00250 
00251    if (fs != 0)
00252      delete fs;
00253 
00254    if (theCode != 0)
00255      delete theCode;
00256 
00257    if (matCodes != 0)
00258      delete matCodes;
00259 }
00260 
00261 int SectionAggregator::setTrialSectionDeformation (const Vector &def)
00262 {
00263   int ret = 0;
00264   int i = 0;
00265 
00266   int theSectionOrder = 0;
00267 
00268   if (theSection) {
00269     theSectionOrder = theSection->getOrder();
00270     Vector v(workArea, theSectionOrder);
00271     
00272     for (i = 0; i < theSectionOrder; i++)
00273       v(i) = def(i);
00274     
00275     ret = theSection->setTrialSectionDeformation(v);
00276   }
00277 
00278   int order = theSectionOrder + numMats;
00279   
00280   for ( ; i < order; i++)
00281     ret += theAdditions[i-theSectionOrder]->setTrialStrain(def(i));
00282   
00283   return ret;
00284 }
00285 
00286 const Vector &
00287 SectionAggregator::getSectionDeformation(void)
00288 {
00289   int i = 0;
00290 
00291   int theSectionOrder = 0;
00292     
00293   if (theSection) {
00294     const Vector &eSec = theSection->getSectionDeformation();
00295     theSectionOrder = theSection->getOrder();
00296     
00297     for (i = 0; i < theSectionOrder; i++)
00298       (*e)(i) = eSec(i);
00299   }
00300   
00301   int order = theSectionOrder + numMats;
00302 
00303   for ( ; i < order; i++)
00304     (*e)(i) = theAdditions[i-theSectionOrder]->getStrain();
00305 
00306   return *e;
00307 }
00308 
00309 const Matrix &
00310 SectionAggregator::getSectionTangent(void)
00311 {
00312   int i = 0;
00313 
00314   int theSectionOrder = 0;
00315 
00316   // Zero before assembly
00317   ks->Zero();
00318 
00319   if (theSection) {
00320     const Matrix &kSec = theSection->getSectionTangent();
00321     theSectionOrder = theSection->getOrder();
00322 
00323     for (i = 0; i < theSectionOrder; i++)
00324       for (int j = 0; j < theSectionOrder; j++)
00325         (*ks)(i,j) = kSec(i,j);
00326   }
00327   
00328   int order = theSectionOrder + numMats;
00329 
00330   for ( ; i < order; i++)
00331     (*ks)(i,i) = theAdditions[i-theSectionOrder]->getTangent();
00332   
00333   return *ks;
00334 }
00335 
00336 const Matrix &
00337 SectionAggregator::getInitialTangent(void)
00338 {
00339   int i = 0;
00340 
00341   int theSectionOrder = 0;
00342 
00343   // Zero before assembly
00344   ks->Zero();
00345 
00346   if (theSection) {
00347     const Matrix &kSec = theSection->getInitialTangent();
00348     theSectionOrder = theSection->getOrder();
00349 
00350     for (i = 0; i < theSectionOrder; i++)
00351       for (int j = 0; j < theSectionOrder; j++)
00352         (*ks)(i,j) = kSec(i,j);
00353   }
00354   
00355   int order = theSectionOrder + numMats;
00356 
00357   for ( ; i < order; i++)
00358     (*ks)(i,i) = theAdditions[i-theSectionOrder]->getInitialTangent();
00359   
00360   return *ks;
00361 }
00362 
00363 const Matrix &
00364 SectionAggregator::getSectionFlexibility(void)
00365 {
00366   int i = 0;
00367     
00368   int theSectionOrder = 0;
00369 
00370   // Zero before assembly
00371   fs->Zero();
00372 
00373   if (theSection) {
00374     const Matrix &fSec = theSection->getSectionFlexibility();
00375     theSectionOrder = theSection->getOrder();
00376 
00377     for (i = 0; i < theSectionOrder; i++)
00378       for (int j = 0; j < theSectionOrder; j++)
00379         (*fs)(i,j) = fSec(i,j);
00380   }
00381   
00382   int order = theSectionOrder + numMats;
00383 
00384   for ( ; i < order; i++) {
00385     double k = theAdditions[i-theSectionOrder]->getTangent();
00386     if (k == 0.0) {
00387       opserr << "SectionAggregator::getSectionFlexibility -- singular section stiffness\n";
00388                                
00389       (*fs)(i,i) = 1.e14;
00390     }
00391     else
00392       (*fs)(i,i) = 1/k;
00393   }     
00394   
00395   return *fs;
00396 }
00397 
00398 const Matrix &
00399 SectionAggregator::getInitialFlexibility(void)
00400 {
00401   int i = 0;
00402     
00403   int theSectionOrder = 0;
00404 
00405   // Zero before assembly
00406   fs->Zero();
00407 
00408   if (theSection) {
00409     const Matrix &fSec = theSection->getInitialFlexibility();
00410     theSectionOrder = theSection->getOrder();
00411 
00412     for (i = 0; i < theSectionOrder; i++)
00413       for (int j = 0; j < theSectionOrder; j++)
00414         (*fs)(i,j) = fSec(i,j);
00415   }
00416   
00417   int order = theSectionOrder + numMats;
00418 
00419   for ( ; i < order; i++) {
00420     double k = theAdditions[i-theSectionOrder]->getInitialTangent();
00421     (*fs)(i,i) = 1.0/k;
00422   }     
00423   
00424   return *fs;
00425 }
00426 
00427 const Vector &
00428 SectionAggregator::getStressResultant(void)
00429 {
00430   int i = 0;
00431 
00432   int theSectionOrder = 0;
00433     
00434   if (theSection) {
00435     const Vector &sSec = theSection->getStressResultant();
00436     theSectionOrder = theSection->getOrder();
00437     
00438     for (i = 0; i < theSectionOrder; i++)
00439       (*s)(i) = sSec(i);
00440   }
00441   
00442   int order = theSectionOrder + numMats;
00443 
00444   for ( ; i < order; i++)
00445     (*s)(i) = theAdditions[i-theSectionOrder]->getStress();
00446   
00447   return *s;
00448 }
00449 
00450 SectionForceDeformation *
00451 SectionAggregator::getCopy(void)
00452 {
00453   SectionAggregator *theCopy = 0;
00454     
00455   if (theSection)
00456     theCopy = new SectionAggregator(this->getTag(), *theSection,
00457                                     numMats, theAdditions, *matCodes);
00458   else
00459     theCopy = new SectionAggregator(this->getTag(), numMats,
00460                                     theAdditions, *matCodes);
00461   
00462   if (theCopy == 0) {
00463     opserr << "SectionAggregator::getCopy -- failed to allocate copy\n";
00464     exit(-1);
00465   }
00466                           
00467   
00468   return theCopy;
00469 }
00470 
00471 const ID&
00472 SectionAggregator::getType ()
00473 {
00474   int i = 0;
00475 
00476   int theSectionOrder = 0;
00477     
00478   if (theSection) {
00479     const ID &secType = theSection->getType();
00480     theSectionOrder = theSection->getOrder();
00481     
00482     for (i = 0; i < theSectionOrder; i++)
00483       (*theCode)(i) = secType(i);
00484   }
00485   
00486   int order = theSectionOrder + numMats;
00487 
00488   for ( ; i < order; i++)
00489     (*theCode)(i) = (*matCodes)(i-theSectionOrder);
00490 
00491   return *theCode;
00492 }
00493 
00494 int
00495 SectionAggregator::getOrder () const
00496 {
00497   int order = numMats;
00498 
00499   if (theSection != 0)
00500     order += theSection->getOrder();
00501 
00502   return order;
00503 }
00504 
00505 int
00506 SectionAggregator::commitState(void)
00507 {
00508   int err = 0;
00509     
00510   if (theSection)
00511     err += theSection->commitState();
00512   
00513   for (int i = 0; i < numMats; i++)
00514     err += theAdditions[i]->commitState();
00515   
00516   return err;
00517 }
00518 
00519 int
00520 SectionAggregator::revertToLastCommit(void)
00521 {
00522   int err = 0;
00523   
00524   int i = 0;
00525   
00526   // Revert the section
00527   if (theSection)
00528     err += theSection->revertToLastCommit();
00529   
00530   // Do the same for the uniaxial materials
00531   for (i = 0; i < numMats; i++)
00532     err += theAdditions[i]->revertToLastCommit();
00533   
00534   return err;
00535 }       
00536 
00537 int
00538 SectionAggregator::revertToStart(void)
00539 {
00540   int err = 0;
00541   
00542   // Revert the section
00543   if (theSection)
00544     err += theSection->revertToStart();
00545   
00546   // Do the same for the uniaxial materials
00547   for (int i = 0; i < numMats; i++)
00548     err += theAdditions[i]->revertToStart();
00549   
00550   return err;
00551 }
00552 
00553 int
00554 SectionAggregator::sendSelf(int cTag, Channel &theChannel)
00555 {
00556   int res = 0;
00557 
00558   // Need otherDbTag since classTags ID and data ID may be the same size
00559   if (otherDbTag == 0) 
00560     otherDbTag = theChannel.getDbTag();
00561   
00562   // Create ID for tag and section order data
00563   static ID data(5);
00564   
00565   int order = this->getOrder();
00566   
00567   data(0) = this->getTag();
00568   data(1) = otherDbTag;
00569   data(2) = order;
00570   data(3) = (theSection != 0) ? theSection->getOrder() : 0;
00571   data(4) = numMats;
00572 
00573   // Send the tag and section order data
00574   res += theChannel.sendID(this->getDbTag(), cTag, data);
00575   if (res < 0) {
00576     opserr << "SectionAggregator::sendSelf -- could not send data ID\n";
00577                             
00578     return res;
00579   }
00580   
00581   // Determine how many classTags there are and allocate ID vector
00582   // for the tags and section code
00583   int numTags = (theSection == 0) ? numMats : numMats + 1;
00584   ID classTags(2*numTags + numMats);
00585   
00586   // Loop over the UniaxialMaterials filling in class and db tags
00587   int i, dbTag;
00588   for (i = 0; i < numMats; i++) {
00589     classTags(i) = theAdditions[i]->getClassTag();
00590     
00591     dbTag = theAdditions[i]->getDbTag();
00592     
00593     if (dbTag == 0) {
00594       dbTag = theChannel.getDbTag();
00595       if (dbTag != 0)
00596         theAdditions[i]->setDbTag(dbTag);
00597     }
00598     
00599     classTags(i+numTags) = dbTag;
00600   }
00601   
00602   // Put the Section class and db tags into the ID vector
00603   if (theSection != 0) {
00604     classTags(numTags-1) = theSection->getClassTag();
00605     
00606     dbTag = theSection->getDbTag();
00607     
00608     if (dbTag == 0) {
00609       dbTag = theChannel.getDbTag();
00610       if (dbTag != 0)
00611         theSection->setDbTag(dbTag);
00612     }
00613     
00614     classTags(2*numTags-1) = dbTag;
00615   }
00616   
00617   // Put the UniaxialMaterial codes into the ID vector
00618   int j = 2*numTags;
00619   for (i = 0; i < numMats; i++, j++)
00620     classTags(j) = (*matCodes)(i);
00621   
00622   // Send the material class and db tags and section code
00623   res += theChannel.sendID(otherDbTag, cTag, classTags);
00624   if (res < 0) {
00625     opserr << "SectionAggregator::sendSelf -- could not send classTags ID\n";
00626     return res;
00627   }
00628 
00629   // Ask the UniaxialMaterials to send themselves
00630   for (i = 0; i < numMats; i++) {
00631     res += theAdditions[i]->sendSelf(cTag, theChannel);
00632     if (res < 0) {
00633       opserr << "SectionAggregator::sendSelf -- could not send UniaxialMaterial, i = " << i << endln;
00634       return res;
00635     }
00636   }
00637   
00638   // Ask the Section to send itself
00639   if (theSection != 0) {
00640     res += theSection->sendSelf(cTag, theChannel);
00641     if (res < 0) {
00642       opserr << "SectionAggregator::sendSelf -- could not send SectionForceDeformation\n";
00643       return res;
00644     }
00645   }
00646   
00647   return res;
00648 }
00649 
00650 
00651 int
00652 SectionAggregator::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00653 {
00654   int res = 0;
00655 
00656   // Create an ID and receive tag and section order
00657   static ID data(5);
00658   res += theChannel.recvID(this->getDbTag(), cTag, data);
00659   if (res < 0) {
00660     opserr << "SectionAggregator::recvSelf -- could not receive data ID\n";
00661     return res;
00662   }
00663   
00664   this->setTag(data(0));
00665   otherDbTag = data(1);
00666   int order = data(2);
00667   int theSectionOrder = data(3);
00668   numMats = data(4);
00669 
00670   if (order > 0) {
00671     if (e == 0 || e->Size() != order) {
00672       if (e != 0) {
00673         delete e;
00674         delete s;
00675         delete ks;
00676         delete fs;
00677         delete theCode;
00678       }
00679       e = new Vector(workArea, order);
00680       s = new Vector(&workArea[maxOrder], order);
00681       ks = new Matrix(&workArea[2*maxOrder], order, order);
00682       fs = new Matrix(&workArea[maxOrder*(maxOrder+2)], order, order);
00683       theCode = new ID(codeArea, order);
00684     }
00685   }
00686 
00687   if (numMats > 0) {
00688     if (matCodes == 0 || matCodes->Size() != numMats) {
00689       if (matCodes != 0)
00690         delete matCodes;
00691 
00692       matCodes = new ID(numMats);
00693     }
00694   }
00695 
00696   // Determine how many classTags there are and allocate ID vector
00697   int numTags = (theSectionOrder == 0) ? numMats : numMats + 1;
00698   ID classTags(numTags*2 + numMats);
00699   
00700   // Receive the material class and db tags
00701   res += theChannel.recvID(otherDbTag, cTag, classTags);
00702   if (res < 0) {
00703     opserr << "SectionAggregator::recvSelf -- could not receive classTags ID\n";
00704     return res;
00705   }
00706 
00707   // Check if null pointer, allocate if so
00708   if (theAdditions == 0) {
00709     theAdditions = new UniaxialMaterial *[numMats];
00710     if (theAdditions == 0) {
00711       opserr << "SectionAggregator::recvSelf -- could not allocate UniaxialMaterial array\n";
00712       return -1;
00713     }
00714     // Set pointers to null ... will get allocated by theBroker
00715     for (int j = 0; j < numMats; j++)
00716       theAdditions[j] = 0;
00717   }
00718   
00719   // Loop over the UniaxialMaterials
00720   int i, classTag;
00721   for (i = 0; i < numMats; i++) {
00722     classTag = classTags(i);
00723     
00724     // Check if the UniaxialMaterial is null; if so, get a new one
00725     if (theAdditions[i] == 0)
00726       theAdditions[i] = theBroker.getNewUniaxialMaterial(classTag);
00727     
00728     // Check that the UniaxialMaterial is of the right type; if not, delete
00729     // the current one and get a new one of the right type
00730     else if (theAdditions[i]->getClassTag() != classTag) {
00731       delete theAdditions[i];
00732       theAdditions[i] = theBroker.getNewUniaxialMaterial(classTag);
00733     }
00734     
00735     // Check if either allocation failed
00736     if (theAdditions[i] == 0) {
00737       opserr << "SectionAggregator::recvSelf -- could not get UniaxialMaterial, i = " << i << endln;
00738       return -1;
00739     }
00740     
00741     // Now, receive the UniaxialMaterial
00742     theAdditions[i]->setDbTag(classTags(i+numTags));
00743     res += theAdditions[i]->recvSelf(cTag, theChannel, theBroker);
00744     if (res < 0) {
00745       opserr << "SectionAggregator::recvSelf -- could not receive UniaxialMaterial, i = " << i << endln;
00746       return res;
00747     }
00748   }
00749 
00750   // If there is no Section to receive, return
00751   if (theSectionOrder == 0)
00752     return res;
00753   
00754   classTag = classTags(numTags-1);
00755   
00756   // Check if the Section is null; if so, get a new one
00757   if (theSection == 0)
00758     theSection = theBroker.getNewSection(classTag);
00759   
00760   // Check that the Section is of the right type; if not, delete
00761   // the current one and get a new one of the right type
00762   else if (theSection->getClassTag() != classTag) {
00763     delete theSection;
00764     theSection = theBroker.getNewSection(classTag);
00765   }
00766   
00767   // Check if either allocation failed
00768   if (theSection == 0) {
00769     opserr << "SectionAggregator::recvSelf -- could not get a SectionForceDeformation\n";
00770     return -1;
00771   }
00772 
00773   // Now, receive the Section
00774   theSection->setDbTag(classTags(2*numTags-1));
00775   res += theSection->recvSelf(cTag, theChannel, theBroker);
00776   if (res < 0) {
00777     opserr << "SectionAggregator::recvSelf -- could not receive SectionForceDeformation\n";
00778     return res;
00779   }
00780   
00781   // Fill in the section code
00782   int j = 2*numTags;
00783   for (i = 0; i < numMats; i++, j++)
00784     (*matCodes)(i) = classTags(j);
00785 
00786   return res;
00787 }
00788 
00789 void
00790 SectionAggregator::Print(OPS_Stream &s, int flag)
00791 {
00792   if (flag == 2) {
00793       theSection->Print(s, flag);
00794   } else {
00795     s << "\nSection Aggregator, tag: " << this->getTag() << endln;
00796     if (theSection) {
00797       s << "\tSection, tag: " << theSection->getTag() << endln;
00798       theSection->Print(s, flag);
00799     }
00800     s << "\tUniaxial Additions" << endln;
00801     for (int i = 0; i < numMats; i++)
00802       s << "\t\tUniaxial Material, tag: " << theAdditions[i]->getTag() << endln;
00803     s << "\tUniaxial codes " << *matCodes << endln;
00804   }
00805 }
00806 
00807 Response*
00808 SectionAggregator::setResponse(const char **argv, int argc, Information &info, OPS_Stream &output)
00809 {
00810   // See if the response is one of the defaults
00811   Response *res = SectionForceDeformation::setResponse(argv, argc, info, output);
00812   if (res != 0)
00813     return res;
00814   
00815   // If not, forward the request to the section (need to do this to get fiber response)
00816   // CURRENTLY NOT SENDING ANYTHING OFF TO THE UniaxialMaterials ... Probably
00817   // don't need anything more from them than stress, strain, and stiffness, 
00818   // which are covered in base class method ... can change if need arises
00819   else if (theSection != 0)
00820     return theSection->setResponse(argv, argc, info,output);
00821   
00822   else
00823     return 0;
00824 }
00825 
00826 int
00827 SectionAggregator::getResponse(int responseID, Information &info)
00828 {
00829   // Just call the base class method ... don't need to define
00830   // this function, but keeping it here just for clarity
00831   return SectionForceDeformation::getResponse(responseID, info);
00832 }
00833 
00834 int
00835 SectionAggregator::setVariable(const char *argv)
00836 {
00837   // Axial strain
00838   if (strcmp(argv,"axialStrain") == 0)
00839     return 1;
00840   // Curvature about the section z-axis
00841   else if (strcmp(argv,"curvatureZ") == 0)
00842     return 2;
00843   // Curvature about the section y-axis
00844   else if (strcmp(argv,"curvatureY") == 0)
00845     return 3;
00846   else
00847     return -1;
00848 }
00849 
00850 int
00851 SectionAggregator::getVariable(int variableID, double &info)
00852 {
00853   int i;
00854 
00855   info = 0.0;
00856 
00857   int order = numMats;
00858   if (theSection != 0)
00859     order += theSection->getOrder();
00860 
00861   const Vector &e = this->getSectionDeformation();
00862   const ID &code  = this->getType();
00863 
00864   switch (variableID) {
00865   case 1:       // Axial strain
00866     // Series model ... add all sources of deformation
00867     for (i = 0; i < order; i++)
00868       if (code(i) == SECTION_RESPONSE_P)
00869         info += e(i);
00870     return 0;
00871   case 2:       // Curvature about the section z-axis
00872     for (i = 0; i < order; i++)
00873       if (code(i) == SECTION_RESPONSE_MZ)
00874         info += e(i);
00875     return 0;
00876   case 3:       // Curvature about the section y-axis
00877     for (i = 0; i < order; i++)
00878       if (code(i) == SECTION_RESPONSE_MY)
00879         info += e(i);
00880     return 0;
00881   default:
00882     return -1;
00883   }
00884 }
00885 
00886 // AddingSensitivity:BEGIN ////////////////////////////////////
00887 int
00888 SectionAggregator::setParameter(const char **argv, int argc, Parameter &param)
00889 {
00890   if (argc < 1)
00891     return -1;
00892 
00893   // Check if the parameter belongs to the material (only option for now)
00894   if (strstr(argv[0],"material") != 0) {
00895     
00896     if (argc < 3)
00897       return -1;
00898 
00899     // Get the tag of the material
00900     int materialTag = atoi(argv[1]);
00901     
00902     // Loop to find the right material
00903     int ok = 0;
00904     for (int i = 0; i < numMats; i++)
00905       if (materialTag == theAdditions[i]->getTag())
00906         ok += theAdditions[i]->setParameter(&argv[2], argc-2, param);
00907 
00908     return ok;
00909   } 
00910   
00911   else if (theSection != 0)
00912     return theSection->setParameter(argv, argc, param);
00913 
00914   else {
00915     opserr << "SectionAggregator::setParameter() - could not set parameter. " << endln;
00916     return -1;
00917   }
00918 }
00919 
00920 const Vector &
00921 SectionAggregator::getSectionDeformationSensitivity(int gradNumber)
00922 {
00923   s->Zero();
00924 
00925   return *s;
00926 }
00927 
00928 const Vector &
00929 SectionAggregator::getStressResultantSensitivity(int gradNumber,
00930                                                  bool conditional)
00931 {
00932   int i = 0;
00933 
00934   int theSectionOrder = 0;
00935     
00936   if (theSection) {
00937     const Vector &dsdh = theSection->getStressResultantSensitivity(gradNumber,
00938                                                                    conditional);
00939     theSectionOrder = theSection->getOrder();
00940     
00941     for (i = 0; i < theSectionOrder; i++)
00942       (*s)(i) = dsdh(i);
00943   }
00944   
00945   int order = theSectionOrder + numMats;
00946 
00947   for ( ; i < order; i++)
00948     (*s)(i) = theAdditions[i-theSectionOrder]->getStressSensitivity(gradNumber,
00949                                                                     conditional);
00950   
00951   return *s;
00952 }
00953 
00954 const Matrix &
00955 SectionAggregator::getSectionTangentSensitivity(int gradNumber)
00956 {
00957   ks->Zero();
00958   
00959   return *ks;
00960 }
00961 
00962 int
00963 SectionAggregator::commitSensitivity(const Vector& defSens,
00964                                      int gradNumber, int numGrads)
00965 {
00966   int ret = 0;
00967   int i = 0;
00968 
00969   dedh = defSens;
00970 
00971   int theSectionOrder = 0;
00972 
00973   if (theSection) {
00974     theSectionOrder = theSection->getOrder();
00975     Vector dedh(workArea, theSectionOrder);
00976     
00977     for (i = 0; i < theSectionOrder; i++)
00978       dedh(i) = defSens(i);
00979     
00980     ret = theSection->commitSensitivity(dedh, gradNumber, numGrads);
00981   }
00982 
00983   int order = theSectionOrder + numMats;
00984   
00985   for ( ; i < order; i++)
00986     ret += theAdditions[i-theSectionOrder]->commitSensitivity(defSens(i),
00987                                                               gradNumber,
00988                                                               numGrads);
00989   
00990   return ret;
00991 }
00992 
00993 // AddingSensitivity:END ///////////////////////////////////
00994 
00995 const Vector&
00996 SectionAggregator::getdedh(void)
00997 {
00998   return dedh;
00999 }

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