00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <math.h>
00031
00032 #include <EnvelopeDriftRecorder.h>
00033 #include <Domain.h>
00034 #include <Node.h>
00035 #include <Vector.h>
00036 #include <ID.h>
00037 #include <Matrix.h>
00038 #include <string.h>
00039 #include <Channel.h>
00040 #include <FEM_ObjectBroker.h>
00041
00042 EnvelopeDriftRecorder::EnvelopeDriftRecorder()
00043 :Recorder(RECORDER_TAGS_EnvelopeDriftRecorder),
00044 ndI(0), ndJ(0), dof(0), perpDirn(0), oneOverL(0), currentData(0),
00045 theDomain(0), theOutputHandler(0),
00046 initializationDone(false), numNodes(0), echoTimeFlag(false)
00047 {
00048
00049 }
00050
00051
00052 EnvelopeDriftRecorder::EnvelopeDriftRecorder(int ni,
00053 int nj,
00054 int df,
00055 int dirn,
00056 Domain &theDom,
00057 OPS_Stream &theCurrentDataOutputHandler,
00058 bool timeFlag)
00059 :Recorder(RECORDER_TAGS_EnvelopeDriftRecorder),
00060 ndI(0), ndJ(0), theNodes(0), dof(df), perpDirn(dirn), oneOverL(0), currentData(0),
00061 theDomain(&theDom), theOutputHandler(&theCurrentDataOutputHandler),
00062 initializationDone(false), numNodes(0), echoTimeFlag(timeFlag)
00063 {
00064 ndI = new ID(1);
00065 ndJ = new ID (1);
00066
00067 if (ndI != 0 && ndJ != 0) {
00068 (*ndI)(0) = ni;
00069 (*ndJ)(0) = nj;
00070 }
00071 }
00072
00073
00074 EnvelopeDriftRecorder::EnvelopeDriftRecorder(const ID &nI,
00075 const ID &nJ,
00076 int df,
00077 int dirn,
00078 Domain &theDom,
00079 OPS_Stream &theDataOutputHandler,
00080 bool timeFlag)
00081 :Recorder(RECORDER_TAGS_EnvelopeDriftRecorder),
00082 ndI(0), ndJ(0), theNodes(0), dof(df), perpDirn(dirn), oneOverL(0), currentData(0),
00083 theDomain(&theDom), theOutputHandler(&theDataOutputHandler),
00084 initializationDone(false), numNodes(0), echoTimeFlag(timeFlag)
00085 {
00086 ndI = new ID(nI);
00087 ndJ = new ID (nJ);
00088 }
00089
00090 EnvelopeDriftRecorder::~EnvelopeDriftRecorder()
00091 {
00092
00093
00094
00095 if (theOutputHandler != 0 && currentData != 0) {
00096
00097 theOutputHandler->tag("Data");
00098 for (int i=0; i<3; i++) {
00099 int size = currentData->Size();
00100 for (int j=0; j<size; j++)
00101 (*currentData)(j) = (*data)(i,j);
00102 theOutputHandler->write(*currentData);
00103 }
00104 theOutputHandler->endTag();
00105 theOutputHandler->endTag();
00106 }
00107
00108
00109
00110 if (ndI != 0)
00111 delete ndI;
00112
00113 if (ndJ != 0)
00114 delete ndJ;
00115
00116 if (oneOverL != 0)
00117 delete oneOverL;
00118
00119 if (currentData != 0)
00120 delete currentData;
00121
00122 if (theNodes != 0)
00123 delete [] theNodes;
00124
00125 if (theOutputHandler != 0)
00126 delete theOutputHandler;
00127 }
00128
00129 int
00130 EnvelopeDriftRecorder::record(int commitTag, double timeStamp)
00131 {
00132
00133 if (theDomain == 0 || ndI == 0 || ndJ == 0) {
00134 return 0;
00135 }
00136
00137 if (theOutputHandler == 0) {
00138 opserr << "EnvelopeDriftRecorder::record() - no DataOutputHandler has been set\n";
00139 return -1;
00140 }
00141
00142 if (initializationDone != true)
00143 if (this->initialize() != 0) {
00144 opserr << "EnvelopeDriftRecorder::record() - failed in initialize()\n";
00145 return -1;
00146 }
00147
00148 if (numNodes == 0 || currentData == 0)
00149 return 0;
00150
00151 for (int i=0; i<numNodes; i++) {
00152 Node *nodeI = theNodes[2*i];
00153 Node *nodeJ = theNodes[2*i+1];
00154
00155 if ((*oneOverL)(i) != 0.0) {
00156 const Vector &dispI = nodeI->getTrialDisp();
00157 const Vector &dispJ = nodeJ->getTrialDisp();
00158
00159 double dx = dispJ(dof)-dispI(dof);
00160
00161 (*currentData)(i) = dx* (*oneOverL)(i);
00162
00163 }
00164 else
00165 (*currentData)(i) = 0.0;
00166 }
00167
00168
00169 int sizeData = currentData->Size();
00170 if (echoTimeFlag == false) {
00171
00172 bool writeIt = false;
00173 if (first == true) {
00174 for (int i=0; i<sizeData; i++) {
00175 (*data)(0,i) = (*currentData)(i);
00176 (*data)(1,i) = (*currentData)(i);
00177 (*data)(2,i) = fabs((*currentData)(i));
00178 first = false;
00179 writeIt = true;
00180 }
00181 } else {
00182 for (int i=0; i<sizeData; i++) {
00183 double value = (*currentData)(i);
00184 if ((*data)(0,i) > value) {
00185 (*data)(0,i) = value;
00186 double absValue = fabs(value);
00187 if ((*data)(2,i) < absValue)
00188 (*data)(2,i) = absValue;
00189 writeIt = true;
00190 } else if ((*data)(1,i) < value) {
00191 (*data)(1,i) = value;
00192 double absValue = fabs(value);
00193 if ((*data)(2,i) < absValue)
00194 (*data)(2,i) = absValue;
00195 writeIt = true;
00196 }
00197 }
00198 }
00199 } else {
00200 sizeData /= 2;
00201 bool writeIt = false;
00202 if (first == true) {
00203 for (int i=0; i<sizeData; i++) {
00204
00205 (*data)(0,i*2) = timeStamp;
00206 (*data)(1,i*2) = timeStamp;
00207 (*data)(2,i*2) = timeStamp;
00208 (*data)(0,i*2+1) = (*currentData)(i);
00209 (*data)(1,i*2+1) = (*currentData)(i);
00210 (*data)(2,i*2+1) = fabs((*currentData)(i));
00211 first = false;
00212 writeIt = true;
00213 }
00214 } else {
00215 for (int i=0; i<sizeData; i++) {
00216 double value = (*currentData)(i);
00217 if ((*data)(0,2*i+1) > value) {
00218 (*data)(0,i*2) = timeStamp;
00219 (*data)(0,i*2+1) = value;
00220 double absValue = fabs(value);
00221 if ((*data)(2,i*2+1) < absValue) {
00222 (*data)(2,i*2+1) = absValue;
00223 (*data)(2,i*2) = timeStamp;
00224 }
00225 writeIt = true;
00226 } else if ((*data)(1,i*2+1) < value) {
00227 (*data)(1,i*2) = timeStamp;
00228 (*data)(1,i*2+1) = value;
00229 double absValue = fabs(value);
00230 if ((*data)(2,i*2+1) < absValue) {
00231 (*data)(2,i*2) = timeStamp;
00232 (*data)(2,i*2+1) = absValue;
00233 }
00234 writeIt = true;
00235 }
00236 }
00237 }
00238 }
00239 return 0;
00240 }
00241
00242 int
00243 EnvelopeDriftRecorder::restart(void)
00244 {
00245 data->Zero();
00246 first = true;
00247 return 0;
00248 }
00249
00250 int
00251 EnvelopeDriftRecorder::setDomain(Domain &theDom)
00252 {
00253 theDomain = &theDom;
00254 initializationDone = false;
00255 return 0;
00256 }
00257
00258 int
00259 EnvelopeDriftRecorder::sendSelf(int commitTag, Channel &theChannel)
00260 {
00261 static ID idData(6);
00262 idData.Zero();
00263 if (ndI != 0 && ndI->Size() != 0)
00264 idData(0) = ndI->Size();
00265 if (ndJ != 0 && ndJ->Size() != 0)
00266 idData(1) = ndJ->Size();
00267 idData(2) = dof;
00268 idData(3) = perpDirn;
00269 if (theOutputHandler != 0) {
00270 idData(4) = theOutputHandler->getClassTag();
00271 }
00272 if (echoTimeFlag == true)
00273 idData(5) = 0;
00274 else
00275 idData(5) = 1;
00276
00277 if (theChannel.sendID(0, commitTag, idData) < 0) {
00278 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to send idData\n";
00279 return -1;
00280 }
00281
00282 if (ndI != 0)
00283 if (theChannel.sendID(0, commitTag, *ndI) < 0) {
00284 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to send dof id's\n";
00285 return -1;
00286 }
00287
00288 if (ndJ != 0)
00289 if (theChannel.sendID(0, commitTag, *ndJ) < 0) {
00290 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to send dof id's\n";
00291 return -1;
00292 }
00293
00294
00295 if (theOutputHandler->sendSelf(commitTag, theChannel) < 0) {
00296 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00297 return -1;
00298 }
00299
00300 return 0;
00301 }
00302
00303 int
00304 EnvelopeDriftRecorder::recvSelf(int commitTag, Channel &theChannel,
00305 FEM_ObjectBroker &theBroker)
00306 {
00307 static ID idData(5);
00308 if (theChannel.recvID(0, commitTag, idData) < 0) {
00309 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to send idData\n";
00310 return -1;
00311 }
00312
00313 if (idData(0) != 0) {
00314 ndI = new ID(idData(0));
00315 if (ndI == 0) {
00316 opserr << "EnvelopeDriftRecorder::sendSelf() - out of memory\n";
00317 return -1;
00318 }
00319 if (theChannel.recvID(0, commitTag, *ndI) < 0) {
00320 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to recv dof id's\n";
00321 return -1;
00322 }
00323 }
00324
00325 if (idData(1) != 0) {
00326
00327 ndJ = new ID(idData(1));
00328 if (ndJ == 0) {
00329 opserr << "EnvelopeDriftRecorder::sendSelf() - out of memory\n";
00330 return -1;
00331 }
00332 if (theChannel.recvID(0, commitTag, *ndJ) < 0) {
00333 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to recv dof id's\n";
00334 return -1;
00335 }
00336 }
00337
00338 dof = idData(2);
00339 perpDirn = idData(3);
00340
00341 if (idData(5) == 0)
00342 echoTimeFlag = true;
00343 else
00344 echoTimeFlag = false;
00345
00346 if (theOutputHandler != 0)
00347 delete theOutputHandler;
00348
00349 theOutputHandler = theBroker.getPtrNewStream(idData(4));
00350 if (theOutputHandler == 0) {
00351 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to get a data output handler\n";
00352 return -1;
00353 }
00354
00355 if (theOutputHandler->recvSelf(commitTag, theChannel, theBroker) < 0) {
00356 opserr << "EnvelopeDriftRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00357 return -1;
00358 }
00359
00360 return 0;
00361 }
00362
00363
00364 int
00365 EnvelopeDriftRecorder::initialize(void)
00366 {
00367 theOutputHandler->tag("OpenSeesOutput");
00368
00369 initializationDone = true;
00370
00371
00372
00373
00374
00375 if (theNodes != 0) {
00376 delete [] theNodes;
00377 theNodes = 0;
00378 }
00379 if (currentData != 0) {
00380 delete currentData;
00381 currentData = 0;
00382 }
00383 if (oneOverL != 0) {
00384 delete oneOverL;
00385 oneOverL = 0;
00386 }
00387
00388
00389
00390
00391
00392 if (ndI == 0 || ndJ == 0) {
00393 opserr << "EnvelopeDriftRecorder::initialize() - no nodal id's set\n";
00394 return -1;
00395 }
00396
00397 int ndIsize = ndI->Size();
00398 int ndJsize = ndJ->Size();
00399
00400 if (ndIsize == 0) {
00401 opserr << "EnvelopeDriftRecorder::initialize() - no nodal id's set\n";
00402 return -1;
00403 }
00404
00405 if (ndIsize != ndJsize) {
00406 opserr << "EnvelopeDriftRecorder::initialize() - error node arrays differ in size\n";
00407 return -2;
00408 }
00409
00410
00411
00412
00413
00414
00415 numNodes = 0;
00416
00417 for (int i=0; i<ndIsize; i++) {
00418 int ni = (*ndI)(i);
00419 int nj = (*ndJ)(i);
00420
00421 Node *nodeI = theDomain->getNode(ni);
00422 Node *nodeJ = theDomain->getNode(nj);
00423
00424 if (nodeI != 0 && nodeJ != 0) {
00425 const Vector &crdI = nodeI->getCrds();
00426 const Vector &crdJ = nodeJ->getCrds();
00427
00428 if (crdI.Size() > perpDirn && crdJ.Size() > perpDirn)
00429 if (crdI(perpDirn) != crdJ(perpDirn))
00430 numNodes++;
00431 }
00432 }
00433
00434 if (numNodes == 0) {
00435 opserr << "EnvelopeDriftRecorder::initialize() - no valid nodes or perpendicular direction\n";
00436 return 0;
00437 }
00438
00439
00440
00441
00442
00443 if (echoTimeFlag == true) {
00444 currentData = new Vector(numNodes*2);
00445 data = new Matrix(3, numNodes*2);
00446 } else {
00447 currentData = new Vector(numNodes);
00448 data = new Matrix(3, numNodes);
00449 }
00450 data->Zero();
00451 theNodes = new Node *[2*numNodes];
00452 oneOverL = new Vector(numNodes);
00453 if (theNodes == 0 || oneOverL == 0 || currentData == 0) {
00454 opserr << "EnvelopeDriftRecorder::initialize() - out of memory\n";
00455 return -3;
00456 }
00457
00458
00459
00460
00461
00462 int counter = 0;
00463 int counterI = 0;
00464 int counterJ = 1;
00465 for (int j=0; j<ndIsize; j++) {
00466 int ni = (*ndI)(j);
00467 int nj = (*ndJ)(j);
00468
00469 Node *nodeI = theDomain->getNode(ni);
00470 Node *nodeJ = theDomain->getNode(nj);
00471
00472 if (nodeI != 0 && nodeJ != 0) {
00473 const Vector &crdI = nodeI->getCrds();
00474 const Vector &crdJ = nodeJ->getCrds();
00475
00476 if (crdI.Size() > perpDirn && crdJ.Size() > perpDirn)
00477 if (crdI(perpDirn) != crdJ(perpDirn)) {
00478
00479 theOutputHandler->tag("DriftOutput");
00480 theOutputHandler->attr("node1", ni);
00481 theOutputHandler->attr("node2", ni);
00482 theOutputHandler->attr("perpDirn", perpDirn);
00483 theOutputHandler->attr("lengthPerpDirn", fabs(crdJ(perpDirn) - crdI(perpDirn)));
00484
00485 if (echoTimeFlag == true) {
00486 theOutputHandler->tag("TimeOutput");
00487 theOutputHandler->tag("ResponseType", "time");
00488 theOutputHandler->endTag();
00489 }
00490
00491 theOutputHandler->tag("ResponseType", "drift");
00492 theOutputHandler->endTag();
00493
00494
00495 (*oneOverL)(counter) = 1.0/fabs(crdJ(perpDirn) - crdI(perpDirn));
00496 theNodes[counterI] = nodeI;
00497 theNodes[counterJ] = nodeJ;
00498 counterI+=2;
00499 counterJ+=2;
00500 counter++;
00501 }
00502 }
00503 }
00504
00505 first = true;
00506
00507
00508
00509
00510
00511 return 0;
00512 }