ElementRecorder.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.26 $
00022 // $Date: 2006/08/04 22:33:53 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/recorder/ElementRecorder.cpp,v $
00024                                                                         
00025 // Written: fmk 
00026 // Created: 09/99
00027 //
00028 // Description: This file contains the class implementatation of ElementRecorder.
00029 //
00030 // What: "@(#) ElementRecorder.C, revA"
00031 
00032 #include <ElementRecorder.h>
00033 #include <Domain.h>
00034 #include <Element.h>
00035 #include <Matrix.h>
00036 #include <Vector.h>
00037 #include <ID.h>
00038 #include <string.h>
00039 #include <Response.h>
00040 #include <FE_Datastore.h>
00041 #include <OPS_Globals.h>
00042 #include <Message.h>
00043 #include <Channel.h>
00044 #include <FEM_ObjectBroker.h>
00045 
00046 ElementRecorder::ElementRecorder()
00047 :Recorder(RECORDER_TAGS_ElementRecorder),
00048  numEle(0), eleID(0), theResponses(0), 
00049  theDomain(0), theOutputHandler(0),
00050  echoTimeFlag(true), deltaT(0), nextTimeStampToRecord(0.0), data(0), 
00051  initializationDone(false), responseArgs(0), numArgs(0)
00052 {
00053 
00054 }
00055 
00056 ElementRecorder::ElementRecorder(const ID &ele,
00057                                  const char **argv, 
00058                                  int argc,
00059                                  bool echoTime, 
00060                                  Domain &theDom, 
00061                                  OPS_Stream &theOutputHandler,
00062                                  double dT)
00063 :Recorder(RECORDER_TAGS_ElementRecorder),
00064  numEle(ele.Size()), eleID(ele), theResponses(0), 
00065  theDomain(&theDom), theOutputHandler(&theOutputHandler),
00066  echoTimeFlag(echoTime), deltaT(dT), nextTimeStampToRecord(0.0), data(0),
00067  initializationDone(false), responseArgs(0), numArgs(0)
00068 {
00069   //
00070   // create a copy of the response request
00071   //
00072 
00073   responseArgs = new char *[argc];
00074   if (responseArgs == 0) {
00075     opserr << "ElementRecorder::ElementRecorder() - out of memory\n";
00076     numEle = 0;
00077   }
00078   
00079   for (int i=0; i<argc; i++) {
00080     responseArgs[i] = new char[strlen(argv[i])+1];
00081     if (responseArgs[i] == 0) {
00082       delete [] responseArgs;
00083       opserr << "ElementRecorder::ElementRecorder() - out of memory\n";
00084       numEle = 0;
00085     }
00086     strcpy(responseArgs[i], argv[i]);
00087   }
00088   
00089   numArgs = argc;
00090 }
00091 
00092 
00093 ElementRecorder::~ElementRecorder()
00094 {
00095   //
00096   // invoke the destructor on the response objects
00097   //
00098 
00099   if (theResponses != 0) {
00100     for (int i = 0; i < numEle; i++)
00101       delete theResponses[i];
00102     delete [] theResponses;
00103   }
00104 
00105   if (data != 0)
00106     delete data;
00107   
00108   // 
00109   // invoke destructor on response args
00110   //
00111   
00112   for (int i=0; i<numArgs; i++)
00113     delete [] responseArgs[i];
00114   delete [] responseArgs;
00115 
00116   theOutputHandler->endTag(); // Data
00117   theOutputHandler->endTag(); // OpenSeesOutput
00118 
00119   if (theOutputHandler != 0)
00120     delete theOutputHandler;
00121 }
00122 
00123 
00124 int 
00125 ElementRecorder::record(int commitTag, double timeStamp)
00126 {
00127   // 
00128   // check that initialization has been done
00129   //
00130 
00131   if (initializationDone == false) {
00132     if (this->initialize() != 0) {
00133       opserr << "ElementRecorder::record() - failed to initialize\n";
00134       return -1;
00135     }
00136   }
00137 
00138   int result = 0;
00139   if (deltaT == 0.0 || timeStamp >= nextTimeStampToRecord) {
00140 
00141     if (deltaT != 0.0) 
00142       nextTimeStampToRecord = timeStamp + deltaT;
00143 
00144     int loc = 0;
00145     if (echoTimeFlag == true) 
00146       (*data)(loc++) = timeStamp;
00147     
00148     //
00149     // for each element if responses exist, put them in response vector
00150     //
00151 
00152     for (int i=0; i< numEle; i++) {
00153       if (theResponses[i] != 0) {
00154         // ask the element for the reponse
00155         int res;
00156         if (( res = theResponses[i]->getResponse()) < 0)
00157           result += res;
00158         else {
00159           Information &eleInfo = theResponses[i]->getInformation();
00160           const Vector &eleData = eleInfo.getData();
00161           for (int j=0; j<eleData.Size(); j++)
00162             (*data)(loc++) = eleData(j);
00163         }
00164       } 
00165     }
00166 
00167     //
00168     // send the response vector to the output handler for o/p
00169     //
00170 
00171     theOutputHandler->write(*data);
00172   }
00173   
00174   // succesfull completion - return 0
00175   return result;
00176 }
00177 
00178 int
00179 ElementRecorder::restart(void)
00180 {
00181   if (data != 0)
00182     data->Zero();
00183   return 0;
00184 }
00185 
00186 
00187 int 
00188 ElementRecorder::setDomain(Domain &theDom)
00189 {
00190   theDomain = &theDom;
00191   return 0;
00192 }
00193 
00194 int
00195 ElementRecorder::sendSelf(int commitTag, Channel &theChannel)
00196 {
00197   if (theChannel.isDatastore() == 1) {
00198     opserr << "ElementRecorder::sendSelf() - does not send data to a datastore\n";
00199     return -1;
00200   }
00201 
00202   //
00203   // into an ID, place & send eleID size, numArgs and length of all responseArgs
00204   //
00205 
00206   static ID idData(4);
00207   idData(0) = eleID.Size();
00208   idData(1) = numArgs;
00209 
00210   int msgLength = 0;
00211   for (int i=0; i<numArgs; i++) 
00212     msgLength += strlen(responseArgs[i])+1;
00213   idData(2) = msgLength;
00214 
00215   if (theOutputHandler != 0) {
00216     idData(3) = theOutputHandler->getClassTag();
00217   } else 
00218     idData(3) = 0;
00219 
00220   if (theChannel.sendID(0, commitTag, idData) < 0) {
00221     opserr << "ElementRecorder::sendSelf() - failed to send idData\n";
00222     return -1;
00223   }
00224 
00225   //
00226   // send the eleID
00227   //
00228 
00229   if (eleID.Size() == 0 || theChannel.sendID(0, commitTag, eleID) < 0) {
00230     opserr << "ElementRecorder::sendSelf() - failed to send idData\n";
00231     return -1;
00232   }
00233 
00234   //
00235   // create a single char array holding all strings
00236   //    will use string terminating character to differentiate strings on other side
00237   //
00238 
00239   if (msgLength ==  0) {
00240     opserr << "ElementRecorder::sendSelf() - no data to send!!\n";
00241     return -1;
00242   }
00243 
00244   char *allResponseArgs = new char[msgLength];
00245   if (allResponseArgs == 0) {
00246     opserr << "ElementRecorder::sendSelf() - out of memory\n";
00247     return -1;
00248   }
00249 
00250   char *currentLoc = allResponseArgs;
00251   for (int j=0; j<numArgs; j++) {
00252     strcpy(currentLoc, responseArgs[j]);
00253     currentLoc += strlen(responseArgs[j]);
00254     currentLoc++;
00255   }
00256 
00257   //
00258   // send this single char array
00259   //
00260 
00261   Message theMessage(allResponseArgs, msgLength);
00262   if (theChannel.sendMsg(0, commitTag, theMessage) < 0) {
00263     opserr << "ElementRecorder::sendSelf() - failed to send message\n";
00264     return -1;
00265   }
00266 
00267   //
00268   // invoke sendSelf() on the output handler
00269   //
00270 
00271   if (theOutputHandler == 0 || theOutputHandler->sendSelf(commitTag, theChannel) < 0) {
00272     opserr << "ElementRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00273     return -1;
00274   }
00275 
00276   //
00277   // clean up & return success
00278   //
00279 
00280   delete [] allResponseArgs;
00281   return 0;
00282 }
00283 
00284 int 
00285 ElementRecorder::recvSelf(int commitTag, Channel &theChannel, 
00286                  FEM_ObjectBroker &theBroker)
00287 {
00288   if (theChannel.isDatastore() == 1) {
00289     opserr << "ElementRecorder::recvSelf() - does not recv data to a datastore\n";
00290     return -1;
00291   }
00292 
00293   //
00294   // into an ID of size 2 recv eleID size and length of all responseArgs
00295   //
00296 
00297   static ID idData(4);
00298   if (theChannel.recvID(0, commitTag, idData) < 0) {
00299     opserr << "ElementRecorder::recvSelf() - failed to recv idData\n";
00300     return -1;
00301   }
00302 
00303   int eleSize = idData(0);
00304   int numArgs = idData(1);
00305   int msgLength = idData(2);
00306 
00307   numEle = eleSize;
00308 
00309   //
00310   // resize & recv the eleID
00311   //
00312 
00313   if (eleSize == 0) {
00314     opserr << "ElementRecorder::recvSelf() - 0 sized eleID\n";
00315     return -1;
00316   }
00317 
00318   int *eleData = new int [eleSize];
00319   eleID.setData(eleData, eleSize, true);
00320   if (theChannel.recvID(0, commitTag, eleID) < 0) {
00321     opserr << "ElementRecorder::recvSelf() - failed to recv idData\n";
00322     return -1;
00323   }
00324 
00325   //
00326   // recv the single char array of element response args
00327   //
00328 
00329   if (msgLength == 0) {
00330     opserr << "ElementRecorder::recvSelf() - 0 sized string for responses\n";
00331     return -1;
00332   }
00333 
00334   char *allResponseArgs = new char[msgLength];
00335   if (allResponseArgs == 0) {
00336     opserr << "ElementRecorder::recvSelf() - out of memory\n";
00337     return -1;
00338   }
00339 
00340   Message theMessage(allResponseArgs, msgLength);
00341   if (theChannel.recvMsg(0, commitTag, theMessage) < 0) {
00342     opserr << "ElementRecorder::recvSelf() - failed to recv message\n";
00343     return -1;
00344   }
00345 
00346   //
00347   // now break this single array into many
00348   // 
00349 
00350   responseArgs = new char *[numArgs];
00351   if (responseArgs == 0) {
00352     opserr << "ElementRecorder::recvSelf() - out of memory\n";
00353     return -1;
00354   }
00355 
00356   char *currentLoc = allResponseArgs;
00357   for (int j=0; j<numArgs; j++) {
00358     int argLength = strlen(currentLoc)+1;
00359     responseArgs[j] = new char[argLength];
00360     if (responseArgs[j] == 0) {
00361       opserr << "ElementRecorder::recvSelf() - out of memory\n";
00362       return -1;
00363     }
00364     opserr << argLength << responseArgs[j] << endln;
00365     strcpy(responseArgs[j], currentLoc);
00366     currentLoc += argLength;
00367   }
00368 
00369   //
00370   // create a new handler object and invoke recvSelf() on it
00371   //
00372 
00373   if (theOutputHandler != 0)
00374     delete theOutputHandler;
00375 
00376   theOutputHandler = theBroker.getPtrNewStream(idData(3));
00377   if (theOutputHandler == 0) {
00378     opserr << "NodeRecorder::sendSelf() - failed to get a data output handler\n";
00379     return -1;
00380   }
00381 
00382   if (theOutputHandler->recvSelf(commitTag, theChannel, theBroker) < 0) {
00383     opserr << "NodeRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00384     return -1;
00385   }
00386 
00387   //
00388   // clean up & return success
00389   //
00390 
00391   delete [] allResponseArgs;
00392   return 0;
00393 }
00394 
00395 int 
00396 ElementRecorder::initialize(void)
00397 {
00398   if (numEle == 0 || theDomain == 0)
00399     return 0;
00400 
00401   theOutputHandler->tag("OpenSeesOutput");
00402 
00403   int numDbColumns = 0;
00404   if (echoTimeFlag == true) {
00405     theOutputHandler->tag("TimeOutput");
00406     theOutputHandler->tag("ResponseType", "time");
00407     theOutputHandler->endTag(); // TimeOutput
00408     numDbColumns += 1;
00409   }
00410 
00411   // Set the response objects:
00412   //   1. create an array of pointers for them
00413   //   2. iterate over the elements invoking setResponse() to get the new objects & determine size of data
00414   //
00415 
00416   theResponses = new Response *[numEle];
00417   for (int k=0; k<numEle; k++)
00418     theResponses[k] = 0;
00419 
00420   Information eleInfo(1.0);
00421   int i;
00422 
00423   for (i=0; i<numEle; i++) {
00424     Element *theEle = theDomain->getElement(eleID(i));
00425     if (theEle == 0) {
00426       theResponses[i] = 0;
00427     } else {
00428       theResponses[i] = theEle->setResponse((const char **)responseArgs, numArgs, eleInfo, *theOutputHandler);
00429       if (theResponses[i] != 0) {
00430         // from the response type determine no of cols for each
00431         Information &eleInfo = theResponses[i]->getInformation();
00432         const Vector &eleData = eleInfo.getData();
00433         numDbColumns += eleData.Size();
00434       }
00435     }
00436   }
00437 
00438 
00439   // create the vector to hold the data
00440   data = new Vector(numDbColumns);
00441 
00442   if (data == 0) {
00443     opserr << "ElementRecorder::initialize() - out of memory\n";
00444     return -1;
00445   }
00446   
00447   theOutputHandler->tag("Data");
00448 
00449   initializationDone = true;
00450   return 0;
00451 }

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