EnvelopeElementRecorder.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.17 $
00022 // $Date: 2006/08/17 22:27:28 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/recorder/EnvelopeElementRecorder.cpp,v $
00024                                                                         
00025 // Written: fmk 
00026 //
00027 // Description: This file contains the class implementatation of 
00028 // EnvelopeElementRecorder.
00029 //
00030 // What: "@(#) EnvelopeElementRecorder.C, revA"
00031 
00032 #include <EnvelopeElementRecorder.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 <Information.h>
00042 
00043 #include <Message.h>
00044 #include <FEM_ObjectBroker.h>
00045 
00046 EnvelopeElementRecorder::EnvelopeElementRecorder()
00047 :Recorder(RECORDER_TAGS_EnvelopeElementRecorder),
00048  numEle(0), eleID(0), theResponses(0), theDomain(0),
00049  theHandler(0), deltaT(0), nextTimeStampToRecord(0.0), 
00050  data(0), currentData(0), first(true),
00051  initializationDone(false), responseArgs(0), numArgs(0), echoTimeFlag(false)
00052 {
00053 
00054 }
00055 
00056 
00057 EnvelopeElementRecorder::EnvelopeElementRecorder(const ID &theEleID, 
00058                                                  const char **argv, 
00059                                                  int argc,
00060                                                  Domain &theDom, 
00061                                                  OPS_Stream &theOutputHandler,
00062                                                  double dT, bool echoTime)
00063 :Recorder(RECORDER_TAGS_EnvelopeElementRecorder),
00064  numEle(theEleID.Size()), eleID(theEleID), theResponses(0), theDomain(&theDom),
00065  theHandler(&theOutputHandler), deltaT(dT), nextTimeStampToRecord(0.0), 
00066  data(0), currentData(0), first(true),
00067  initializationDone(false), responseArgs(0), numArgs(0), echoTimeFlag(echoTime)
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 EnvelopeElementRecorder::~EnvelopeElementRecorder()
00093 {
00094   //
00095   // write the data
00096   //
00097 
00098 
00099   if (theHandler != 0 && currentData != 0) {
00100 
00101     theHandler->tag("Data"); // Data
00102 
00103     for (int i=0; i<3; i++) {
00104       int size = currentData->Size();
00105       for (int j=0; j<size; j++)
00106         (*currentData)(j) = (*data)(i,j);
00107       theHandler->write(*currentData);
00108     }
00109 
00110     theHandler->endTag(); // Data
00111     theHandler->endTag(); // OpenSeesOutput
00112   }
00113 
00114   if (theHandler != 0)
00115     delete theHandler;
00116 
00117 
00118   if (data != 0)
00119     delete data;
00120   
00121   if (currentData != 0)
00122     delete currentData;
00123 
00124 
00125   //
00126   // clean up the memory
00127   //
00128 
00129   if (theResponses != 0) {
00130     for (int i = 0; i < numEle; i++) 
00131       if (theResponses[i] != 0)
00132         delete theResponses[i];
00133 
00134     delete [] theResponses;
00135   }
00136 
00137 
00138 
00139   // 
00140   // invoke destructor on response args
00141   //
00142 
00143   for (int i=0; i<numArgs; i++)
00144     delete [] responseArgs[i];
00145   delete [] responseArgs;
00146   /*  
00147 
00148   */
00149 }
00150 
00151 
00152 int 
00153 EnvelopeElementRecorder::record(int commitTag, double timeStamp)
00154 {
00155   // 
00156   // check that initialization has been done
00157   //
00158 
00159   if (initializationDone == false) {
00160     if (this->initialize() != 0) {
00161       opserr << "ElementRecorder::record() - failed to initialize\n";
00162       return -1;
00163     }
00164   }
00165 
00166   int result = 0;
00167   if (deltaT == 0.0 || timeStamp >= nextTimeStampToRecord) {
00168       
00169     if (deltaT != 0.0) 
00170       nextTimeStampToRecord = timeStamp + deltaT;
00171     
00172     int loc = 0;
00173     // for each element do a getResponse() & put the result in current data
00174     for (int i=0; i< numEle; i++) {
00175       if (theResponses[i] != 0) {
00176         // ask the element for the reponse
00177         int res;
00178         if (( res = theResponses[i]->getResponse()) < 0)
00179           result += res;
00180         else {
00181           // from the response determine no of cols for each
00182           Information &eleInfo = theResponses[i]->getInformation();
00183           const Vector &eleData = eleInfo.getData();
00184           for (int j=0; j<eleData.Size(); j++) 
00185             (*currentData)(loc++) = eleData(j);
00186         }
00187       }
00188     }
00189 
00190 
00191     int sizeData = currentData->Size();
00192     if (echoTimeFlag == false) {
00193 
00194       bool writeIt = false;
00195       if (first == true) {
00196         for (int i=0; i<sizeData; i++) {
00197           (*data)(0,i) = (*currentData)(i);
00198           (*data)(1,i) = (*currentData)(i);
00199           (*data)(2,i) = fabs((*currentData)(i));
00200           first = false;
00201           writeIt = true;
00202         } 
00203       } else {
00204         for (int i=0; i<sizeData; i++) {
00205           double value = (*currentData)(i);
00206           if ((*data)(0,i) > value) {
00207             (*data)(0,i) = value;
00208             double absValue = fabs(value);
00209             if ((*data)(2,i) < absValue) 
00210               (*data)(2,i) = absValue;
00211             writeIt = true;
00212           } else if ((*data)(1,i) < value) {
00213             (*data)(1,i) = value;
00214             double absValue = fabs(value);
00215             if ((*data)(2,i) < absValue) 
00216               (*data)(2,i) = absValue;
00217             writeIt = true;
00218           }
00219         }
00220       }
00221     } else {
00222       sizeData /= 2;
00223       bool writeIt = false;
00224       if (first == true) {
00225         for (int i=0; i<sizeData; i++) {
00226           
00227           (*data)(0,i*2) = timeStamp;
00228           (*data)(1,i*2) = timeStamp;
00229           (*data)(2,i*2) = timeStamp;
00230           (*data)(0,i*2+1) = (*currentData)(i);
00231           (*data)(1,i*2+1) = (*currentData)(i);
00232           (*data)(2,i*2+1) = fabs((*currentData)(i));
00233           first = false;
00234           writeIt = true;
00235         } 
00236       } else {
00237         for (int i=0; i<sizeData; i++) {
00238           double value = (*currentData)(i);
00239           if ((*data)(0,2*i+1) > value) {
00240             (*data)(0,i*2) = timeStamp;
00241             (*data)(0,i*2+1) = value;
00242             double absValue = fabs(value);
00243             if ((*data)(2,i*2+1) < absValue) {
00244               (*data)(2,i*2+1) = absValue;
00245               (*data)(2,i*2) = timeStamp;
00246             }
00247             writeIt = true;
00248           } else if ((*data)(1,i*2+1) < value) {
00249             (*data)(1,i*2) = timeStamp;
00250             (*data)(1,i*2+1) = value;
00251             double absValue = fabs(value);
00252             if ((*data)(2,i*2+1) < absValue) { 
00253               (*data)(2,i*2) = timeStamp;
00254               (*data)(2,i*2+1) = absValue;
00255             }
00256             writeIt = true;
00257           }
00258         }
00259       }
00260     }
00261   }    
00262   // succesfull completion - return 0
00263   return result;
00264 }
00265 
00266 int
00267 EnvelopeElementRecorder::restart(void)
00268 {
00269   data->Zero();
00270   first = true;
00271   return 0;
00272 }
00273 
00274 int 
00275 EnvelopeElementRecorder::setDomain(Domain &theDom)
00276 {
00277   theDomain = &theDom;
00278   return 0;
00279 }
00280 
00281 int
00282 EnvelopeElementRecorder::sendSelf(int commitTag, Channel &theChannel)
00283 {
00284   if (theChannel.isDatastore() == 1) {
00285     opserr << "EnvelopeElementRecorder::sendSelf() - does not send data to a datastore\n";
00286     return -1;
00287   }
00288 
00289   //
00290   // into an ID, place & send eleID size, numArgs and length of all responseArgs
00291   //
00292 
00293   static ID idData(4);
00294   idData(0) = eleID.Size();
00295   idData(1) = numArgs;
00296 
00297   int msgLength = 0;
00298   for (int i=0; i<numArgs; i++) 
00299     msgLength += strlen(responseArgs[i])+1;
00300   idData(2) = msgLength;
00301 
00302   if (theHandler != 0) {
00303     idData(3) = theHandler->getClassTag();
00304   } else 
00305     idData(3) = 0;
00306 
00307   if (theChannel.sendID(0, commitTag, idData) < 0) {
00308     opserr << "EnvelopeElementRecorder::sendSelf() - failed to send idData\n";
00309     return -1;
00310   }
00311 
00312   //
00313   // send the eleID
00314   //
00315 
00316   if (eleID.Size() == 0 || theChannel.sendID(0, commitTag, eleID) < 0) {
00317     opserr << "EnvelopeElementRecorder::sendSelf() - failed to send idData\n";
00318     return -1;
00319   }
00320 
00321   //
00322   // create a single char array holding all strings
00323   //    will use string terminating character to differentiate strings on other side
00324   //
00325 
00326   if (msgLength ==  0) {
00327     opserr << "EnvelopeElementRecorder::sendSelf() - no data to send!!\n";
00328     return -1;
00329   }
00330 
00331   char *allResponseArgs = new char[msgLength];
00332   if (allResponseArgs == 0) {
00333     opserr << "EnvelopeElementRecorder::sendSelf() - out of memory\n";
00334     return -1;
00335   }
00336 
00337   char *currentLoc = allResponseArgs;
00338   for (int j=0; j<numArgs; j++) {
00339     strcpy(currentLoc, responseArgs[j]);
00340     currentLoc += strlen(responseArgs[j]);
00341     currentLoc++;
00342   }
00343 
00344   //
00345   // send this single char array
00346   //
00347 
00348   Message theMessage(allResponseArgs, msgLength);
00349   if (theChannel.sendMsg(0, commitTag, theMessage) < 0) {
00350     opserr << "EnvelopeElementRecorder::sendSelf() - failed to send message\n";
00351     return -1;
00352   }
00353 
00354   //
00355   // invoke sendSelf() on the output handler
00356   //
00357 
00358   if (theHandler == 0 || theHandler->sendSelf(commitTag, theChannel) < 0) {
00359     opserr << "EnvelopeElementRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00360     return -1;
00361   }
00362 
00363   //
00364   // clean up & return success
00365   //
00366 
00367   delete [] allResponseArgs;
00368   return 0;
00369 }
00370 
00371 
00372 int 
00373 EnvelopeElementRecorder::recvSelf(int commitTag, Channel &theChannel, 
00374                  FEM_ObjectBroker &theBroker)
00375 {
00376   if (theChannel.isDatastore() == 1) {
00377     opserr << "EnvelopeElementRecorder::recvSelf() - does not recv data to a datastore\n";
00378     return -1;
00379   }
00380 
00381   //
00382   // into an ID of size 2 recv eleID size and length of all responseArgs
00383   //
00384 
00385   static ID idData(4);
00386   if (theChannel.recvID(0, commitTag, idData) < 0) {
00387     opserr << "EnvelopeElementRecorder::recvSelf() - failed to recv idData\n";
00388     return -1;
00389   }
00390 
00391   int eleSize = idData(0);
00392   int numArgs = idData(1);
00393   int msgLength = idData(2);
00394 
00395   numEle = eleSize;
00396 
00397   //
00398   // resize & recv the eleID
00399   //
00400 
00401   if (eleSize == 0) {
00402     opserr << "EnvelopeElementRecorder::recvSelf() - 0 sized eleID\n";
00403     return -1;
00404   }
00405 
00406   int *eleData = new int [eleSize];
00407   eleID.setData(eleData, eleSize, true);
00408   if (theChannel.recvID(0, commitTag, eleID) < 0) {
00409     opserr << "EnvelopeElementRecorder::recvSelf() - failed to recv idData\n";
00410     return -1;
00411   }
00412 
00413   //
00414   // recv the single char array of element response args
00415   //
00416 
00417   if (msgLength == 0) {
00418     opserr << "EnvelopeElementRecorder::recvSelf() - 0 sized string for responses\n";
00419     return -1;
00420   }
00421 
00422   char *allResponseArgs = new char[msgLength];
00423   if (allResponseArgs == 0) {
00424     opserr << "EnvelopeElementRecorder::recvSelf() - out of memory\n";
00425     return -1;
00426   }
00427 
00428   Message theMessage(allResponseArgs, msgLength);
00429   if (theChannel.recvMsg(0, commitTag, theMessage) < 0) {
00430     opserr << "EnvelopeElementRecorder::recvSelf() - failed to recv message\n";
00431     return -1;
00432   }
00433 
00434   //
00435   // now break this single array into many
00436   // 
00437 
00438   responseArgs = new char *[numArgs];
00439   if (responseArgs == 0) {
00440     opserr << "EnvelopeElementRecorder::recvSelf() - out of memory\n";
00441     return -1;
00442   }
00443 
00444   char *currentLoc = allResponseArgs;
00445   for (int j=0; j<numArgs; j++) {
00446     int argLength = strlen(currentLoc)+1;
00447     responseArgs[j] = new char[argLength];
00448     if (responseArgs[j] == 0) {
00449       opserr << "EnvelopeElementRecorder::recvSelf() - out of memory\n";
00450       return -1;
00451     }
00452     opserr << argLength << responseArgs[j] << endln;
00453     strcpy(responseArgs[j], currentLoc);
00454     currentLoc += argLength;
00455   }
00456 
00457   //
00458   // create a new handler object and invoke recvSelf() on it
00459   //
00460 
00461   if (theHandler != 0)
00462     delete theHandler;
00463 
00464   theHandler = theBroker.getPtrNewStream(idData(3));
00465   if (theHandler == 0) {
00466     opserr << "NodeRecorder::sendSelf() - failed to get a data output handler\n";
00467     return -1;
00468   }
00469 
00470   if (theHandler->recvSelf(commitTag, theChannel, theBroker) < 0) {
00471     opserr << "NodeRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00472     return -1;
00473   }
00474 
00475   //
00476   // clean up & return success
00477   //
00478 
00479   delete [] allResponseArgs;
00480   return 0;
00481 
00482 }
00483 
00484 
00485 int 
00486 EnvelopeElementRecorder::initialize(void) 
00487 {
00488   if (numEle == 0 || theDomain == 0)
00489     return 0;
00490 
00491   theHandler->tag("OpenSeesOutput");
00492 
00493   // Set the response objects:
00494   //   1. create an array of pointers for them
00495   //   2. iterate over the elements invoking setResponse() to get the new objects & determine size of data
00496   //
00497 
00498   theResponses = new Response *[numEle];
00499   for (int k=0; k<numEle; k++)
00500     theResponses[k] = 0;
00501 
00502   Information eleInfo(1.0);
00503   int numDbColumns = 0;
00504 
00505   for (int ii=0; ii<numEle; ii++) {
00506     Element *theEle = theDomain->getElement(eleID(ii));
00507     if (theEle == 0) {
00508       theResponses[ii] = 0;
00509     } else {
00510       theResponses[ii] = theEle->setResponse((const char **)responseArgs, numArgs, eleInfo, *theHandler);
00511       if (theResponses[ii] != 0) {
00512         // from the response type determine no of cols for each      
00513         Information &eleInfo = theResponses[ii]->getInformation();
00514         const Vector &eleData = eleInfo.getData();
00515         numDbColumns += eleData.Size();
00516 
00517         if (echoTimeFlag == true) {
00518           for (int i=0; i<eleData.Size(); i++) {
00519             theHandler->tag("TimeOutput");
00520             theHandler->attr("ResponseType", "time");
00521             theHandler->endTag();
00522           }
00523         }
00524       }
00525     }
00526   }
00527 
00528   //
00529   // create the matrix & vector that holds the data
00530   //
00531 
00532   if (echoTimeFlag == true) {
00533     numDbColumns *= 2;
00534   }
00535 
00536   data = new Matrix(3, numDbColumns);
00537   currentData = new Vector(numDbColumns);
00538   if (data == 0 || currentData == 0) {
00539     opserr << "EnvelopeElementRecorder::EnvelopeElementRecorder() - out of memory\n";
00540     exit(-1);
00541   }
00542 
00543   initializationDone = true;  
00544   return 0;
00545 }
00546   

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