ArrayOfTaggedObjects.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.2 $
00022 // $Date: 2003/02/14 23:02:10 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/tagged/storage/ArrayOfTaggedObjects.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/tagged/storage/ArrayOfTaggedObjects.C
00027 //
00028 // Written: fmk 
00029 // Created: 11/96
00030 // Revision: A
00031 //
00032 // Purpose: This file contains the implementation of the ArrayOfTaggedObjects
00033 // class.
00034 //
00035 // What: "@(#) ArrayOfTaggedObjects.C, revA"
00036 
00037 #include <TaggedObject.h>
00038 #include <ArrayOfTaggedObjects.h>
00039 
00040 #include <OPS_Globals.h>
00041 
00042 ArrayOfTaggedObjects::ArrayOfTaggedObjects(int size)
00043 :numComponents(0),sizeComponentArray(0), positionLastEntry(0),
00044  positionLastNoFitEntry(0),fitFlag(true), theComponents(0),
00045  myIter(*this)
00046 {
00047     // get the components array from the heap
00048     theComponents = new TaggedObject *[size];
00049     
00050     // check we obtained enough memory and set the array size
00051     if (theComponents == 0) {
00052       opserr << "ArrayOfTaggedObjects::ArrayOfTaggedObjects - failed to allocate an array of size " << size << endln;
00053     } else 
00054         sizeComponentArray = size;
00055 
00056     // 0 the array 
00057     for (int i=0; i<sizeComponentArray; i++) 
00058         theComponents[i] = 0;
00059 }
00060 
00061 
00062 ArrayOfTaggedObjects::~ArrayOfTaggedObjects()
00063 {
00064     if (theComponents != 0)
00065         delete [] theComponents;
00066 }
00067 
00068 
00069 
00070 int
00071 ArrayOfTaggedObjects::setSize(int newSize)
00072 {
00073     // check a valid size
00074     if (newSize < 0 && newSize > sizeComponentArray) {
00075       opserr << "ArrayOfTaggedObjects::setSize - invalid size " << newSize << endln;
00076       return -1;        
00077     } 
00078 
00079     if (newSize < 2) newSize = 2; // make 2 the min size;
00080     
00081     // get an array of pointers from the heap
00082     // NOTE: cannot use TaggedObject **newArray = new (TaggedObject *)[newSize]; 
00083     // with digital cxx compiler!!!!
00084     TaggedObject **newArray = new TaggedObject *[newSize]; 
00085 
00086     if (newArray == 0) {
00087         // cannot increase size to newSize, keep as is and return error
00088       opserr << "ArrayOfTaggedObjects::setSize - failed to allocate an array of size " << newSize << endln;
00089       return -2;
00090     } 
00091 
00092     // 
00093     // we got the space we needed .. now we populate the new array
00094     // trying to put everything in nicely, i.e. in location given by obj tags.
00095     //
00096     
00097     // first zero the new array
00098     for (int i=0; i<newSize; i++) 
00099         newArray[i] = 0;
00100 
00101     // store the needed info of the old array 
00102     TaggedObject **oldArray = theComponents;
00103     int oldArrayLastEntry = positionLastEntry;
00104 
00105     // set data for new aray
00106     theComponents = newArray;
00107     sizeComponentArray = newSize;               
00108 
00109     int error = 0;
00110     if (fitFlag == true && positionLastEntry <= newSize) { 
00111         // we will copy old to new directly 
00112         // as all fitted well last time this is just a straight assignment
00113         
00114         theComponents = newArray;
00115         sizeComponentArray = newSize;   
00116         for (int i=0; i<=positionLastEntry; i++)
00117             theComponents[i] = oldArray[i];
00118     } else { 
00119         // we will see if the components fit in well this time
00120 
00121         // reset the parameters for the new array       
00122         numComponents = 0;
00123         sizeComponentArray = newSize;
00124         positionLastEntry = 0;
00125         positionLastNoFitEntry = 0;
00126         fitFlag = true;
00127 
00128         // now add all the componets of the old array into the new one
00129         // we add using addComponent() to see if false fitFlag will now be true
00130         for (int j=0; j<=oldArrayLastEntry; j++)
00131             if (oldArray[j] != 0)
00132                 if (this->addComponent(oldArray[j]) == false) {
00133                     // this should never happen - but in case it does
00134                   opserr << "SERIOUS ERROR: ArrayOfTaggedObjects::setSize() - we have lost a component with tag: " <<
00135                     oldArray[j]->getTag() << endln;
00136                   error = -3;
00137                 }    
00138     }
00139 
00140     // delete the old array
00141     if (oldArray != 0)
00142         delete [] oldArray;
00143     
00144     return error;
00145 }
00146 
00147 
00148 bool 
00149 ArrayOfTaggedObjects::addComponent(TaggedObject *newComponent)
00150 {
00151     // check to see that no other component already exists
00152 //    if (allowMultiple == false) {
00153         TaggedObject *other = this->getComponentPtr(newComponent->getTag());
00154         if (other != 0) {
00155           opserr << "WARNING ArrayOfTaggedObjects::addComponent() - component" <<
00156             " with tag already exists, not adding component with tag: " <<
00157             newComponent->getTag() << endln;
00158           return false;
00159         }
00160 //    }
00161     
00162     // check to see if size of current array is big enough. if not resize.
00163     if (numComponents == sizeComponentArray) 
00164         if (this->setSize(2*numComponents) < 0) {
00165           opserr << "ArrayOfTaggedObjects::addComponent()- failed to enlarge the array with size" <<
00166             2*numComponents << endln;
00167           return false;
00168         }
00169     
00170     // we try to the Component in nicely, i.e. in
00171     // position given by the newComponents Tag
00172 
00173     int newComponentTag = newComponent->getTag();
00174     
00175     if ((newComponentTag >= 0) && (newComponentTag < sizeComponentArray)) {
00176         if (theComponents[newComponentTag] == 0)   { // it will go in nicely
00177             theComponents[newComponentTag] = newComponent;
00178             numComponents ++;
00179             if (newComponentTag > positionLastEntry)
00180                 positionLastEntry = newComponentTag;
00181             return true;
00182         }
00183     }
00184 
00185     // it won't go in nicely, so put wherever we can get it in
00186     while (theComponents[positionLastNoFitEntry] != 0 && 
00187            positionLastNoFitEntry < sizeComponentArray )
00188         positionLastNoFitEntry++;
00189 
00190     // just in case we don't get a location ..  though we should!!
00191     if (positionLastNoFitEntry == sizeComponentArray) {
00192       opserr << "ArrayOfTaggedObjects::addComponent() - could not - find a vacant spot after enlarging!!\n";
00193       return false;
00194     }
00195         
00196     theComponents[positionLastNoFitEntry] = newComponent;
00197     numComponents++;
00198     if (positionLastNoFitEntry > positionLastEntry)
00199         positionLastEntry = positionLastNoFitEntry;
00200     fitFlag = false;
00201 
00202     return true;  // o.k.
00203 }
00204 
00205 TaggedObject *
00206 ArrayOfTaggedObjects::removeComponent(int tag)
00207 {
00208     TaggedObject *removed;
00209     
00210     // first check to see if object is located at pos given by tag
00211     if ((tag >= 0) && (tag < sizeComponentArray))
00212         
00213         // if all objects in nicely then has to be at location given by tag
00214         if (fitFlag == true) { 
00215             removed = theComponents[tag];
00216             theComponents[tag] = 0;
00217 
00218             // if the object is there decrement numComponents added and 
00219             // check if need to reset positionLastEntry marker
00220             if (removed != 0) {
00221                 numComponents--;                        
00222                 
00223                 if (positionLastEntry == tag) {
00224                     for (int i = positionLastEntry; i>=0; i--)
00225                         if (theComponents[i] != 0) {
00226                             positionLastEntry = i;
00227                             i = -1; // break out of loop
00228                         }
00229                 }
00230             }
00231             return removed;
00232         }  else  // it still may be at nice location so do as above
00233             if (theComponents[tag] != 0)
00234                 if ((theComponents[tag]->getTag()) == tag) {
00235                     removed = theComponents[tag];                   
00236                     theComponents[tag] = 0;
00237                     if (positionLastEntry == tag) {
00238                         for (int i = positionLastEntry; i>=0; i--)
00239                             if (theComponents[i] != 0) {
00240                                 positionLastEntry = i;
00241                                 i = -1; // break out of loop
00242                             }
00243                     }               
00244                     positionLastNoFitEntry = 0;
00245                     numComponents--;                
00246                     return removed;
00247                 }
00248 
00249     // else we have to look through array until we find it or 
00250     // reach lastPosition used
00251     for (int i=0; i<=positionLastEntry; i++)
00252         if (theComponents[i] != 0)
00253             if (theComponents[i]->getTag() == tag) {
00254                 
00255                 // we found the component so do as above again
00256                 // and then return a pointer to the component
00257                 removed = theComponents[i];
00258                 theComponents[i] = 0;
00259                 if (positionLastEntry == i) {
00260                     for (int j = positionLastEntry; j>=0; j--)
00261                         if (theComponents[j] != 0) {
00262                             positionLastEntry = j;
00263                             j = -1; // break out of loop
00264                         }
00265                 }                               
00266                 positionLastNoFitEntry = 0;
00267                 numComponents--;
00268                 return removed;
00269             }
00270 
00271     // if get here the object is not stored in the array
00272     return 0;
00273 }
00274 
00275 int
00276 ArrayOfTaggedObjects::getNumComponents(void) const
00277 {
00278     return numComponents;
00279 }
00280 
00281 TaggedObject *
00282 ArrayOfTaggedObjects::getComponentPtr(int tag)
00283 {
00284 
00285     // first check it's not where we would like it
00286     if ((tag >= 0) && (tag < sizeComponentArray))
00287         if (fitFlag == true) // either its at nice position or not entered
00288             return theComponents[tag];
00289         else {             // it still may be at nice location
00290             if (theComponents[tag] != 0)
00291                 if ((theComponents[tag]->getTag()) == tag)
00292                     return theComponents[tag];
00293         }
00294 
00295     // else we have to look through array until we find it or 
00296     // reach lastPosition used
00297     for (int i=0; i<=positionLastEntry; i++)
00298         if (theComponents[i] != 0)
00299             if (theComponents[i]->getTag() == tag) 
00300                 return theComponents[i];
00301 
00302     // its not in the array
00303     return 0;
00304 }
00305 
00306 
00307 TaggedObjectIter &
00308 ArrayOfTaggedObjects::getComponents()
00309 {
00310     // reset the iter to point to first component and then return 
00311     // a reference to the iter
00312     myIter.reset();
00313     return myIter;
00314 }
00315 
00316 
00317 ArrayOfTaggedObjectsIter 
00318 ArrayOfTaggedObjects::getIter()
00319 {
00320     // return a new iter to the components, more expensive to use
00321     // this iter as two memory calls to heap .. needed if user needs
00322     // to have multiple iters running in same code segment!
00323     return ArrayOfTaggedObjectsIter(*this);
00324 }
00325 
00326 
00327 TaggedObjectStorage *
00328 ArrayOfTaggedObjects::getEmptyCopy(void)
00329 {
00330     ArrayOfTaggedObjects *theCopy = new ArrayOfTaggedObjects(sizeComponentArray);
00331     
00332     if (theCopy == 0) {
00333       opserr << "ArrayOfTaggedObjects::getEmptyCopy - out of memory\n";
00334     }
00335 
00336     return theCopy;
00337 }
00338 
00339 void
00340 ArrayOfTaggedObjects::clearAll(bool invokeDestructors)
00341 {
00342     if (invokeDestructors == true) {
00343         // go through and invoke the components object destructors
00344         // and set the array pointers to 0
00345         for (int i=0; i<=positionLastEntry; i++) {
00346             if (theComponents[i] != 0) {
00347                 delete theComponents[i];
00348                 theComponents[i] = 0;
00349             }
00350         }
00351     } else {
00352         // just set the array pointers to 0
00353         for (int i=0; i<=positionLastEntry; i++) {
00354             if (theComponents[i] != 0) {
00355                 theComponents[i] = 0;
00356             }
00357         }
00358     }
00359     
00360     positionLastEntry = 0;
00361     positionLastNoFitEntry = 0;
00362     fitFlag = true;
00363     numComponents = 0;
00364 }
00365 
00366 
00367 
00368 
00369 // void Print(OPS_Stream &s, int flag) const
00370 //      method which invokes Print on all components
00371 
00372 void
00373 ArrayOfTaggedObjects::Print(OPS_Stream &s, int flag)
00374 {
00375     // go through the array invoking Print on non-zero entries
00376     for (int i=0; i<=positionLastEntry; i++)
00377         if (theComponents[i] != 0)
00378             theComponents[i]->Print(s, flag);
00379 }
00380 
00381 
00382 

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