EnvelopeNodeRecorder.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 
00022 
00023 // $Revision: 1.13 $
00024 // $Date: 2006/08/17 22:27:28 $
00025 // $Source: /usr/local/cvs/OpenSees/SRC/recorder/EnvelopeNodeRecorder.cpp,v $
00026                                                                         
00027 // Written: fmk 
00028 //
00029 // Description: This file contains the class definition for EnvelopeNodeRecorder.
00030 // A EnvelopeNodeRecorder is used to record the envelop of specified dof responses 
00031 // at a collection of nodes over an analysis. (between commitTag of 0 and
00032 // last commitTag).
00033 //
00034 // What: "@(#) EnvelopeNodeRecorder.C, revA"
00035 
00036 #include <math.h>
00037 
00038 #include <EnvelopeNodeRecorder.h>
00039 #include <Domain.h>
00040 #include <Node.h>
00041 #include <Vector.h>
00042 #include <ID.h>
00043 #include <Matrix.h>
00044 #include <FE_Datastore.h>
00045 #include <FEM_ObjectBroker.h>
00046 
00047 #include <string.h>
00048 
00049 EnvelopeNodeRecorder::EnvelopeNodeRecorder()
00050 :Recorder(RECORDER_TAGS_EnvelopeNodeRecorder),
00051  theDofs(0), theNodalTags(0), theNodes(0),
00052  currentData(0), data(0), 
00053  theDomain(0), theHandler(0),
00054  deltaT(0.0), nextTimeStampToRecord(0.0), 
00055  first(true), initializationDone(false), numValidNodes(0)
00056 {
00057 
00058 }
00059 
00060 EnvelopeNodeRecorder::EnvelopeNodeRecorder(const ID &dofs, 
00061                                            const ID &nodes, 
00062                                            const char *dataToStore,
00063                                            Domain &theDom,
00064                                            OPS_Stream &theOutputHandler,
00065                                            double dT, bool echoTime)
00066 :Recorder(RECORDER_TAGS_EnvelopeNodeRecorder),
00067  theDofs(0), theNodalTags(0), theNodes(0),
00068  currentData(0), data(0), 
00069  theDomain(&theDom), theHandler(&theOutputHandler),
00070  deltaT(dT), nextTimeStampToRecord(0.0), 
00071  first(true), initializationDone(false), numValidNodes(0), echoTimeFlag(echoTime)
00072 {
00073   // verify dof are valid 
00074   int numDOF = dofs.Size();
00075   theDofs = new ID(0, numDOF);
00076 
00077   int count = 0;
00078   int i;
00079   for (i=0; i<numDOF; i++) {
00080     int dof = dofs(i);
00081     if (dof >= 0) {
00082       (*theDofs)[count] = dof;
00083       count++;
00084     } else {
00085       opserr << "EnvelopeNodeRecorder::EnvelopeNodeRecorder - invalid dof  " << dof;
00086       opserr << " will be ignored\n";
00087     }
00088   }
00089 
00090 
00091   // 
00092   // create memory to hold nodal ID's (neeed parallel)
00093   //
00094 
00095   int numNode = nodes.Size();
00096   if (numNode != 0) {
00097     theNodalTags = new ID(nodes);
00098     
00099     if (theNodalTags == 0) {
00100       opserr << "EnvelopeNodeRecorder::EnvelopeNodeRecorder - out of memory\n";
00101     }
00102   }
00103 
00104   //
00105   // set the data flag used as a switch to get the response in a record
00106   //
00107 
00108   if (dataToStore == 0 || (strcmp(dataToStore, "disp") == 0)) {
00109     dataFlag = 0;
00110   } else if ((strcmp(dataToStore, "vel") == 0)) {
00111     dataFlag = 1;
00112   } else if ((strcmp(dataToStore, "accel") == 0)) {
00113     dataFlag = 2;
00114   } else if ((strcmp(dataToStore, "incrDisp") == 0)) {
00115     dataFlag = 3;
00116   } else if ((strcmp(dataToStore, "incrDeltaDisp") == 0)) {
00117     dataFlag = 4;
00118   } else if ((strcmp(dataToStore, "unbalance") == 0)) {
00119     dataFlag = 5;
00120   } else if ((strncmp(dataToStore, "eigen",5) == 0)) {
00121     int mode = atoi(&(dataToStore[5]));
00122     if (mode > 0)
00123       dataFlag = 10 + mode;
00124     else
00125       dataFlag = 6;
00126   } else {
00127     dataFlag = 6;
00128     opserr << "EnvelopeNodeRecorder::EnvelopeNodeRecorder - dataToStore " << dataToStore;
00129     opserr << "not recognized (disp, vel, accel, incrDisp, incrDeltaDisp)\n";
00130   }
00131 }
00132 
00133 
00134 EnvelopeNodeRecorder::~EnvelopeNodeRecorder()
00135 {
00136   //
00137   // write the data
00138   //
00139   if (theHandler != 0 && currentData != 0) {
00140     
00141     theHandler->tag("Data"); // Data
00142 
00143     for (int i=0; i<3; i++) {
00144       int size = currentData->Size();
00145       for (int j=0; j<size; j++)
00146         (*currentData)(j) = (*data)(i,j);
00147       theHandler->write(*currentData);
00148     }
00149     theHandler->endTag(); // Data
00150     theHandler->endTag(); // OpenSeesOutput
00151   }
00152 
00153 
00154   //
00155   // clean up the memory
00156   //
00157 
00158   if (theDofs != 0)
00159     delete theDofs;
00160 
00161   if (theNodalTags != 0)
00162     delete theNodalTags;
00163   
00164   if (theHandler != 0)
00165     delete theHandler;
00166 
00167   if (currentData != 0)
00168     delete currentData;
00169 
00170   if (data != 0)
00171     delete data;
00172 
00173   if (theNodes != 0)
00174     delete [] theNodes;
00175 }
00176 
00177 int 
00178 EnvelopeNodeRecorder::record(int commitTag, double timeStamp)
00179 {
00180   if (theDomain == 0 || theNodalTags == 0 || theDofs == 0) {
00181     return 0;
00182   }
00183 
00184   if (theHandler == 0) {
00185     opserr << "EnvelopeNodeRecorder::record() - no DataOutputHandler has been set\n";
00186     return -1;
00187   }
00188 
00189 
00190   if (initializationDone != true) 
00191     if (this->initialize() != 0) {
00192       opserr << "EnvelopeNodeRecorder::record() - failed in initialize()\n";
00193       return -1;
00194     }
00195 
00196   int numDOF = theDofs->Size();
00197   
00198   if (deltaT == 0.0 || timeStamp >= nextTimeStampToRecord) {
00199     
00200     if (deltaT != 0.0) 
00201       nextTimeStampToRecord = timeStamp + deltaT;
00202     
00203     for (int i=0; i<numValidNodes; i++) {
00204       int cnt = i*numDOF;
00205       Node *theNode = theNodes[i];
00206       if (dataFlag == 0) {
00207         const Vector &response = theNode->getTrialDisp();
00208         for (int j=0; j<numDOF; j++) {
00209           int dof = (*theDofs)(j);
00210           if (response.Size() > dof) {
00211             (*currentData)(cnt) = response(dof);
00212           }else 
00213             (*currentData)(cnt) = 0.0;
00214           
00215           cnt++;
00216         }
00217       } else if (dataFlag == 1) {
00218         const Vector &response = theNode->getTrialVel();
00219         for (int j=0; j<numDOF; j++) {
00220           int dof = (*theDofs)(j);
00221           if (response.Size() > dof) {
00222             (*currentData)(cnt) = response(dof);
00223           } else 
00224             (*currentData)(cnt) = 0.0;
00225           
00226           cnt++;
00227         }
00228       } else if (dataFlag == 2) {
00229         const Vector &response = theNode->getTrialAccel();
00230         for (int j=0; j<numDOF; j++) {
00231           int dof = (*theDofs)(j);
00232           if (response.Size() > dof) {
00233             (*currentData)(cnt) = response(dof);
00234           } else 
00235             (*currentData)(cnt) = 0.0;
00236           
00237           cnt++;
00238         }
00239       } else if (dataFlag == 3) {
00240         const Vector &response = theNode->getIncrDisp();
00241         for (int j=0; j<numDOF; j++) {
00242           int dof = (*theDofs)(j);
00243           if (response.Size() > dof) {
00244             (*currentData)(cnt) = response(dof);
00245           } else 
00246             (*currentData)(cnt) = 0.0;
00247           
00248           cnt++;
00249         }
00250       } else if (dataFlag == 4) {
00251         const Vector &response = theNode->getIncrDeltaDisp();
00252         for (int j=0; j<numDOF; j++) {
00253           int dof = (*theDofs)(j);
00254           if (response.Size() > dof) {
00255             (*currentData)(cnt) = response(dof);
00256           } else 
00257             (*currentData)(cnt) = 0.0;
00258           
00259           cnt++;
00260         }
00261       } else if (dataFlag == 5) {
00262         const Vector &theResponse = theNode->getUnbalancedLoad();
00263         for (int j=0; j<numDOF; j++) {
00264           int dof = (*theDofs)(j);
00265           if (theResponse.Size() > dof) {
00266             (*currentData)(cnt) = theResponse(dof);
00267           } else 
00268             (*currentData)(cnt) = 0.0;
00269           
00270           cnt++;
00271         }
00272       } else if (dataFlag > 10) {
00273         int mode = dataFlag - 10;
00274         int column = mode - 1;
00275         const Matrix &theEigenvectors = theNode->getEigenvectors();
00276         if (theEigenvectors.noCols() > column) {
00277           int noRows = theEigenvectors.noRows();
00278           for (int j=0; j<numDOF; j++) {
00279             int dof = (*theDofs)(j);
00280             if (noRows > dof) {
00281               (*currentData)(cnt) = theEigenvectors(dof,column);
00282             } else 
00283               (*currentData)(cnt) = 0.0;
00284             cnt++;              
00285           }
00286         } else {
00287           for (int j=0; j<numDOF; j++) {
00288             (*currentData)(cnt) = 0.0;
00289             cnt++;              
00290           }
00291         }
00292       }
00293     }
00294   }
00295     
00296   // check if currentData modifies the saved data
00297   int sizeData = currentData->Size();
00298   if (echoTimeFlag == false) {
00299 
00300     bool writeIt = false;
00301     if (first == true) {
00302       for (int i=0; i<sizeData; i++) {
00303         (*data)(0,i) = (*currentData)(i);
00304         (*data)(1,i) = (*currentData)(i);
00305         (*data)(2,i) = fabs((*currentData)(i));
00306         first = false;
00307         writeIt = true;
00308       } 
00309     } else {
00310       for (int i=0; i<sizeData; i++) {
00311         double value = (*currentData)(i);
00312         if ((*data)(0,i) > value) {
00313           (*data)(0,i) = value;
00314           double absValue = fabs(value);
00315           if ((*data)(2,i) < absValue) 
00316             (*data)(2,i) = absValue;
00317           writeIt = true;
00318         } else if ((*data)(1,i) < value) {
00319           (*data)(1,i) = value;
00320           double absValue = fabs(value);
00321           if ((*data)(2,i) < absValue) 
00322             (*data)(2,i) = absValue;
00323           writeIt = true;
00324         }
00325       }
00326     }
00327   } else {
00328     sizeData /= 2;
00329     bool writeIt = false;
00330     if (first == true) {
00331       for (int i=0; i<sizeData; i++) {
00332 
00333         (*data)(0,i*2) = timeStamp;
00334         (*data)(1,i*2) = timeStamp;
00335         (*data)(2,i*2) = timeStamp;
00336         (*data)(0,i*2+1) = (*currentData)(i);
00337         (*data)(1,i*2+1) = (*currentData)(i);
00338         (*data)(2,i*2+1) = fabs((*currentData)(i));
00339         first = false;
00340         writeIt = true;
00341       } 
00342     } else {
00343       for (int i=0; i<sizeData; i++) {
00344         double value = (*currentData)(i);
00345         if ((*data)(0,2*i+1) > value) {
00346           (*data)(0,i*2) = timeStamp;
00347           (*data)(0,i*2+1) = value;
00348           double absValue = fabs(value);
00349           if ((*data)(2,i*2+1) < absValue) {
00350             (*data)(2,i*2+1) = absValue;
00351             (*data)(2,i*2) = timeStamp;
00352           }
00353           writeIt = true;
00354         } else if ((*data)(1,i*2+1) < value) {
00355           (*data)(1,i*2) = timeStamp;
00356           (*data)(1,i*2+1) = value;
00357           double absValue = fabs(value);
00358           if ((*data)(2,i*2+1) < absValue) { 
00359             (*data)(2,i*2) = timeStamp;
00360             (*data)(2,i*2+1) = absValue;
00361           }
00362           writeIt = true;
00363         }
00364       }
00365     }
00366   }
00367   return 0;
00368 }
00369 
00370 
00371 int
00372 EnvelopeNodeRecorder::restart(void)
00373 {
00374   data->Zero();
00375   first = true;
00376   return 0;
00377 }
00378 
00379 
00380 int 
00381 EnvelopeNodeRecorder::setDomain(Domain &theDom)
00382 {
00383   theDomain = &theDom;
00384   initializationDone = false;  
00385   return 0;
00386 }
00387 
00388 
00389 int
00390 EnvelopeNodeRecorder::sendSelf(int commitTag, Channel &theChannel)
00391 {
00392   if (theChannel.isDatastore() == 1) {
00393     opserr << "EnvelopeNodeRecorder::sendSelf() - does not send data to a datastore\n";
00394     return -1;
00395   }
00396 
00397   static ID idData(4); 
00398   idData.Zero();
00399   if (theDofs != 0)
00400     idData(0) = theDofs->Size();
00401   if (theNodalTags != 0)
00402     idData(1) = theNodalTags->Size();
00403   if (theHandler != 0) {
00404     idData(2) = theHandler->getClassTag();
00405   }
00406 
00407   idData(3) = dataFlag;
00408 
00409   if (theChannel.sendID(0, commitTag, idData) < 0) {
00410     opserr << "EnvelopeNodeRecorder::sendSelf() - failed to send idData\n";
00411     return -1;
00412   }
00413 
00414   if (theDofs != 0) 
00415     if (theChannel.sendID(0, commitTag, *theDofs) < 0) {
00416       opserr << "EnvelopeNodeRecorder::sendSelf() - failed to send dof id's\n";
00417       return -1;
00418     }
00419 
00420   if (theNodalTags != 0)
00421     if (theChannel.sendID(0, commitTag, *theNodalTags) < 0) {
00422       opserr << "EnvelopeNodeRecorder::sendSelf() - failed to send nodal tags\n";
00423       return -1;
00424     }
00425 
00426   static Vector data(2);
00427   data(0) = deltaT;
00428   data(1) = nextTimeStampToRecord;
00429   if (theChannel.sendVector(0, commitTag, data) < 0) {
00430     opserr << "EnvelopeNodeRecorder::sendSelf() - failed to send data\n";
00431     return -1;
00432   }
00433 
00434   if (theHandler->sendSelf(commitTag, theChannel) < 0) {
00435     opserr << "EnvelopeNodeRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00436     return -1;
00437   }
00438 
00439   return 0;
00440 }
00441 
00442 int 
00443 EnvelopeNodeRecorder::recvSelf(int commitTag, Channel &theChannel, 
00444                  FEM_ObjectBroker &theBroker)
00445 {
00446   if (theChannel.isDatastore() == 1) {
00447     opserr << "EnvelopeNodeRecorder::sendSelf() - does not send data to a datastore\n";
00448     return -1;
00449   }
00450 
00451   static ID idData(4); 
00452   if (theChannel.recvID(0, commitTag, idData) < 0) {
00453     opserr << "EnvelopeNodeRecorder::recvSelf() - failed to send idData\n";
00454     return -1;
00455   }
00456 
00457   int numDOFs = idData(0);
00458   int numNodes = idData(1);
00459 
00460   dataFlag = idData(3);
00461 
00462   //
00463   // get the DOF ID data
00464   //
00465 
00466   if (theDofs == 0 || theDofs->Size() != numDOFs) {
00467     if (theDofs != 0)
00468       delete theDofs;
00469 
00470     if (numDOFs != 0) {
00471       theDofs = new ID(numDOFs);
00472       if (theDofs == 0 || theDofs->Size() != numDOFs) {
00473         opserr << "EnvelopeNodeRecorder::recvSelf() - out of memory\n";
00474         return -1;
00475       } 
00476     }
00477   }
00478   if (theDofs != 0)
00479     if (theChannel.recvID(0, commitTag, *theDofs) < 0) {
00480       opserr << "EnvelopeNodeRecorder::recvSelf() - failed to recv dof data\n";
00481       return -1;
00482     } 
00483 
00484   //
00485   // get the NODAL tag data
00486   //
00487 
00488   if (theNodalTags == 0 || theNodalTags->Size() != numNodes) {
00489     if (theNodalTags != 0)
00490       delete theNodalTags;
00491 
00492     if (numNodes != 0) {
00493       theNodalTags = new ID(numNodes);
00494       if (theNodalTags == 0 || theNodalTags->Size() != numNodes) {
00495         opserr << "EnvelopeNodeRecorder::recvSelf() - out of memory\n";
00496         return -1;
00497       } 
00498     }
00499   }
00500   if (theNodalTags != 0)
00501     if (theChannel.recvID(0, commitTag, *theNodalTags) < 0) {
00502       opserr << "EnvelopeNodeRecorder::recvSelf() - failed to recv dof data\n";
00503       return -1;
00504     } 
00505 
00506 
00507   static Vector data(2);
00508   data(0) = deltaT;
00509   data(1) = nextTimeStampToRecord;
00510   if (theChannel.recvVector(0, commitTag, data) < 0) {
00511     opserr << "EnvelopeNodeRecorder::sendSelf() - failed to receive data\n";
00512     return -1;
00513   }
00514 
00515   if (theHandler != 0)
00516     delete theHandler;
00517 
00518   theHandler = theBroker.getPtrNewStream(idData(2));
00519   if (theHandler == 0) {
00520     opserr << "EnvelopeNodeRecorder::sendSelf() - failed to get a data output handler\n";
00521     return -1;
00522   }
00523 
00524   if (theHandler->recvSelf(commitTag, theChannel, theBroker) < 0) {
00525     opserr << "EnvelopeNodeRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00526     return -1;
00527   }
00528 
00529   return 0;
00530 }
00531 
00532 
00533 int
00534 EnvelopeNodeRecorder::initialize(void)
00535 {
00536   if (theDofs == 0 || theNodalTags == 0 || theDomain == 0) {
00537     opserr << "EnvelopeNodeRecorder::initialize() - either nodes, dofs or domain has not been set\n";
00538     return -1;
00539   }
00540 
00541   theHandler->tag("OpenSeesOutput");
00542   
00543   //
00544   // create & set nodal array pointer
00545   //
00546 
00547   if (theNodes != 0) 
00548     delete [] theNodes;
00549   
00550   numValidNodes = 0;
00551   int i;
00552   int numNode = theNodalTags->Size();
00553   for (i=0; i<numNode; i++) {
00554     int nodeTag = (*theNodalTags)(i);
00555     Node *theNode = theDomain->getNode(nodeTag);
00556     if (theNode != 0) {
00557       numValidNodes++;
00558     }
00559   }
00560 
00561   theNodes = new Node *[numValidNodes];
00562   if (theNodes == 0) {
00563     opserr << "EnvelopeNodeRecorder::domainChanged - out of memory\n";
00564     return -1;
00565   }
00566 
00567   int count = 0;
00568   for (i=0; i<numNode; i++) {
00569     int nodeTag = (*theNodalTags)(i);
00570     Node *theNode = theDomain->getNode(nodeTag);
00571     if (theNode != 0) {
00572       theNodes[count] = theNode;
00573       count++;
00574     }
00575   }
00576 
00577 
00578   //
00579   // need to create the data description, i.e. what each column of data is
00580   //
00581 
00582   //
00583   // need to create the data description, i.e. what each column of data is
00584   //
00585   
00586   char outputData[32];
00587   char dataType[10];
00588 
00589   if (dataFlag == 0) {
00590     strcpy(dataType,"D");
00591   } else if (dataFlag == 1) {
00592     strcpy(dataType,"V");
00593   } else if (dataFlag == 2) {
00594     strcpy(dataType,"A");
00595   } else if (dataFlag == 3) {
00596     strcpy(dataType,"dD");
00597   } else if (dataFlag == 4) {
00598     strcpy(dataType,"ddD");
00599   } else if (dataFlag == 5) {
00600     strcpy(dataType,"U");
00601   } else if (dataFlag == 6) {
00602     strcpy(dataType,"U");
00603   } else if (dataFlag == 7) {
00604     strcpy(dataType,"R");
00605   } else if (dataFlag == 8) {
00606     strcpy(dataType,"R");
00607   } else if (dataFlag > 10) {
00608     sprintf(dataType,"E%d", dataFlag-10);
00609   } else
00610     strcpy(dataType,"Unknown");
00611 
00612   for (i=0; i<numValidNodes; i++) {
00613     int nodeTag = theNodes[i]->getTag();
00614 
00615     theHandler->tag("NodeOutput");
00616     theHandler->attr("nodeTag", nodeTag);
00617 
00618     for (int j=0; j<theDofs->Size(); j++) {
00619       
00620       if (echoTimeFlag == true) {
00621         theHandler->tag("TimeOutput");
00622         theHandler->tag("ResponseType", "time");
00623         theHandler->endTag();
00624       }
00625 
00626       sprintf(outputData, "%s%d", dataType, j+1);
00627       theHandler->tag("ResponseType",outputData);
00628     }
00629 
00630     theHandler->endTag();
00631   }
00632 
00633   //
00634   // resize the response vector
00635   //
00636   int numValidResponse = numValidNodes*theDofs->Size();
00637 
00638   if (echoTimeFlag == true) {
00639     numValidResponse *= 2;
00640   }
00641 
00642 
00643   currentData = new Vector(numValidResponse);
00644   data = new Matrix(3, numValidResponse);
00645   data->Zero();
00646 
00647   initializationDone = true;
00648 
00649   return 0;
00650 }

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