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 <DriftRecorder.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 DriftRecorder::DriftRecorder()
00043 :Recorder(RECORDER_TAGS_DriftRecorder),
00044 ndI(0), ndJ(0), dof(0), perpDirn(0), oneOverL(0), data(0),
00045 theDomain(0), theOutputHandler(0),
00046 initializationDone(false), numNodes(0), echoTimeFlag(false)
00047 {
00048
00049 }
00050
00051
00052 DriftRecorder::DriftRecorder(int ni,
00053 int nj,
00054 int df,
00055 int dirn,
00056 Domain &theDom,
00057 OPS_Stream &theDataOutputHandler,
00058 bool timeFlag)
00059 :Recorder(RECORDER_TAGS_DriftRecorder),
00060 ndI(0), ndJ(0), theNodes(0), dof(df), perpDirn(dirn), oneOverL(0), data(0),
00061 theDomain(&theDom), theOutputHandler(&theDataOutputHandler),
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 DriftRecorder::DriftRecorder(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_DriftRecorder),
00082 ndI(0), ndJ(0), theNodes(0), dof(df), perpDirn(dirn), oneOverL(0), data(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 DriftRecorder::~DriftRecorder()
00091 {
00092 if (ndI != 0)
00093 delete ndI;
00094
00095 if (ndJ != 0)
00096 delete ndJ;
00097
00098 if (oneOverL != 0)
00099 delete oneOverL;
00100
00101 if (data != 0)
00102 delete data;
00103
00104 if (theNodes != 0)
00105 delete [] theNodes;
00106
00107 theOutputHandler->endTag();
00108 theOutputHandler->endTag();
00109
00110 if (theOutputHandler != 0)
00111 delete theOutputHandler;
00112 }
00113
00114 int
00115 DriftRecorder::record(int commitTag, double timeStamp)
00116 {
00117
00118 if (theDomain == 0 || ndI == 0 || ndJ == 0) {
00119 return 0;
00120 }
00121
00122 if (theOutputHandler == 0) {
00123 opserr << "DriftRecorder::record() - no DataOutputHandler has been set\n";
00124 return -1;
00125 }
00126
00127 if (initializationDone != true)
00128 if (this->initialize() != 0) {
00129 opserr << "DriftRecorder::record() - failed in initialize()\n";
00130 return -1;
00131 }
00132
00133 if (numNodes == 0 || data == 0)
00134 return 0;
00135
00136 int timeOffset = 0;
00137 if (echoTimeFlag == true) {
00138 (*data)(0) = theDomain->getCurrentTime();
00139 timeOffset = 1;
00140 }
00141
00142 for (int i=0; i<numNodes; i++) {
00143 Node *nodeI = theNodes[2*i];
00144 Node *nodeJ = theNodes[2*i+1];
00145
00146 if ((*oneOverL)(i) != 0.0) {
00147 const Vector &dispI = nodeI->getTrialDisp();
00148 const Vector &dispJ = nodeJ->getTrialDisp();
00149
00150 double dx = dispJ(dof)-dispI(dof);
00151
00152 (*data)(i+timeOffset) = dx* (*oneOverL)(i);
00153
00154 }
00155 else
00156 (*data)(i+timeOffset) = 0.0;
00157 }
00158
00159 theOutputHandler->write(*data);
00160 return 0;
00161 }
00162
00163 int
00164 DriftRecorder::restart(void)
00165 {
00166 return 0;
00167 }
00168
00169 int
00170 DriftRecorder::setDomain(Domain &theDom)
00171 {
00172 theDomain = &theDom;
00173 initializationDone = false;
00174 return 0;
00175 }
00176
00177 int
00178 DriftRecorder::sendSelf(int commitTag, Channel &theChannel)
00179 {
00180 static ID idData(6);
00181 idData.Zero();
00182 if (ndI != 0 && ndI->Size() != 0)
00183 idData(0) = ndI->Size();
00184 if (ndJ != 0 && ndJ->Size() != 0)
00185 idData(1) = ndJ->Size();
00186 idData(2) = dof;
00187 idData(3) = perpDirn;
00188 if (theOutputHandler != 0) {
00189 idData(4) = theOutputHandler->getClassTag();
00190 }
00191 if (echoTimeFlag == true)
00192 idData(5) = 0;
00193 else
00194 idData(5) = 1;
00195
00196 if (theChannel.sendID(0, commitTag, idData) < 0) {
00197 opserr << "DriftRecorder::sendSelf() - failed to send idData\n";
00198 return -1;
00199 }
00200
00201 if (ndI != 0)
00202 if (theChannel.sendID(0, commitTag, *ndI) < 0) {
00203 opserr << "DriftRecorder::sendSelf() - failed to send dof id's\n";
00204 return -1;
00205 }
00206
00207 if (ndJ != 0)
00208 if (theChannel.sendID(0, commitTag, *ndJ) < 0) {
00209 opserr << "DriftRecorder::sendSelf() - failed to send dof id's\n";
00210 return -1;
00211 }
00212
00213
00214 if (theOutputHandler->sendSelf(commitTag, theChannel) < 0) {
00215 opserr << "DriftRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00216 return -1;
00217 }
00218
00219 return 0;
00220 }
00221
00222 int
00223 DriftRecorder::recvSelf(int commitTag, Channel &theChannel,
00224 FEM_ObjectBroker &theBroker)
00225 {
00226 static ID idData(5);
00227 if (theChannel.recvID(0, commitTag, idData) < 0) {
00228 opserr << "DriftRecorder::sendSelf() - failed to send idData\n";
00229 return -1;
00230 }
00231
00232 if (idData(0) != 0) {
00233 ndI = new ID(idData(0));
00234 if (ndI == 0) {
00235 opserr << "DriftRecorder::sendSelf() - out of memory\n";
00236 return -1;
00237 }
00238 if (theChannel.recvID(0, commitTag, *ndI) < 0) {
00239 opserr << "DriftRecorder::sendSelf() - failed to recv dof id's\n";
00240 return -1;
00241 }
00242 }
00243
00244 if (idData(1) != 0) {
00245
00246 ndJ = new ID(idData(1));
00247 if (ndJ == 0) {
00248 opserr << "DriftRecorder::sendSelf() - out of memory\n";
00249 return -1;
00250 }
00251 if (theChannel.recvID(0, commitTag, *ndJ) < 0) {
00252 opserr << "DriftRecorder::sendSelf() - failed to recv dof id's\n";
00253 return -1;
00254 }
00255 }
00256
00257 dof = idData(2);
00258 perpDirn = idData(3);
00259
00260 if (idData(5) == 0)
00261 echoTimeFlag = true;
00262 else
00263 echoTimeFlag = false;
00264
00265 if (theOutputHandler != 0)
00266 delete theOutputHandler;
00267
00268 theOutputHandler = theBroker.getPtrNewStream(idData(4));
00269 if (theOutputHandler == 0) {
00270 opserr << "DriftRecorder::sendSelf() - failed to get a data output handler\n";
00271 return -1;
00272 }
00273
00274 if (theOutputHandler->recvSelf(commitTag, theChannel, theBroker) < 0) {
00275 opserr << "DriftRecorder::sendSelf() - failed to send the DataOutputHandler\n";
00276 return -1;
00277 }
00278
00279 return 0;
00280 }
00281
00282
00283 int
00284 DriftRecorder::initialize(void)
00285 {
00286
00287
00288 theOutputHandler->tag("OpenSeesOutput");
00289
00290 if (echoTimeFlag == true) {
00291 theOutputHandler->tag("TimeOutput");
00292 theOutputHandler->tag("ResponseType", "time");
00293 theOutputHandler->endTag();
00294 }
00295
00296 initializationDone = true;
00297
00298
00299
00300
00301
00302 if (theNodes != 0) {
00303 delete [] theNodes;
00304 theNodes = 0;
00305 }
00306 if (data != 0) {
00307 delete data;
00308 data = 0;
00309 }
00310 if (oneOverL != 0) {
00311 delete oneOverL;
00312 oneOverL = 0;
00313 }
00314
00315
00316
00317
00318
00319 if (ndI == 0 || ndJ == 0) {
00320 opserr << "DriftRecorder::initialize() - no nodal id's set\n";
00321 return -1;
00322 }
00323
00324 int ndIsize = ndI->Size();
00325 int ndJsize = ndJ->Size();
00326
00327 if (ndIsize == 0) {
00328 opserr << "DriftRecorder::initialize() - no nodal id's set\n";
00329 return -1;
00330 }
00331
00332 if (ndIsize != ndJsize) {
00333 opserr << "DriftRecorder::initialize() - error node arrays differ in size\n";
00334 return -2;
00335 }
00336
00337
00338
00339
00340
00341
00342 numNodes = 0;
00343
00344 for (int i=0; i<ndIsize; i++) {
00345 int ni = (*ndI)(i);
00346 int nj = (*ndJ)(i);
00347
00348 Node *nodeI = theDomain->getNode(ni);
00349 Node *nodeJ = theDomain->getNode(nj);
00350
00351 if (nodeI != 0 && nodeJ != 0) {
00352 const Vector &crdI = nodeI->getCrds();
00353 const Vector &crdJ = nodeJ->getCrds();
00354
00355 if (crdI.Size() > perpDirn && crdJ.Size() > perpDirn)
00356 if (crdI(perpDirn) != crdJ(perpDirn))
00357 numNodes++;
00358 }
00359 }
00360
00361 if (numNodes == 0) {
00362 opserr << "DriftRecorder::initialize() - no valid nodes or perpendicular direction\n";
00363 return 0;
00364 }
00365
00366
00367
00368
00369
00370 int timeOffset = 0;
00371 if (echoTimeFlag == true)
00372 timeOffset = 1;
00373
00374 theNodes = new Node *[2*numNodes];
00375 oneOverL = new Vector(numNodes);
00376 data = new Vector(numNodes+timeOffset);
00377 if (theNodes == 0 || oneOverL == 0 || data == 0) {
00378 opserr << "DriftRecorder::initialize() - out of memory\n";
00379 return -3;
00380 }
00381
00382
00383
00384
00385
00386 int counter = 0;
00387 int counterI = 0;
00388 int counterJ = 1;
00389 for (int j=0; j<ndIsize; j++) {
00390 int ni = (*ndI)(j);
00391 int nj = (*ndJ)(j);
00392
00393 Node *nodeI = theDomain->getNode(ni);
00394 Node *nodeJ = theDomain->getNode(nj);
00395
00396 if (nodeI != 0 && nodeJ != 0) {
00397 const Vector &crdI = nodeI->getCrds();
00398 const Vector &crdJ = nodeJ->getCrds();
00399
00400 if (crdI.Size() > perpDirn && crdJ.Size() > perpDirn)
00401 if (crdI(perpDirn) != crdJ(perpDirn)) {
00402
00403 theOutputHandler->tag("DriftOutput");
00404 theOutputHandler->attr("node1", ni);
00405 theOutputHandler->attr("node2", ni);
00406 theOutputHandler->attr("perpDirn", perpDirn);
00407 theOutputHandler->attr("lengthPerpDirn", fabs(crdJ(perpDirn) - crdI(perpDirn)));
00408 theOutputHandler->tag("ResponseType", "drift");
00409 theOutputHandler->endTag();
00410 (*oneOverL)(counter) = 1.0/fabs(crdJ(perpDirn) - crdI(perpDirn));
00411 theNodes[counterI] = nodeI;
00412 theNodes[counterJ] = nodeJ;
00413 counterI+=2;
00414 counterJ+=2;
00415 counter++;
00416 }
00417 }
00418 }
00419
00420 theOutputHandler->tag("Data");
00421
00422
00423
00424
00425
00426
00427 return 0;
00428 }