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
00031
00032
00033
00034
00035
00036
00037
00038 #include <Vector.h>
00039 #include <Matrix.h>
00040 #include <Node.h>
00041 #include <Channel.h>
00042
00043 #include <PDeltaCrdTransf3d.h>
00044
00045
00046
00047 PDeltaCrdTransf3d::PDeltaCrdTransf3d(int tag, const Vector &vecInLocXZPlane):
00048 CrdTransf3d(tag, CRDTR_TAG_PDeltaCrdTransf3d),
00049 nodeIPtr(0), nodeJPtr(0),
00050 nodeIOffset(0), nodeJOffset(0),
00051 L(0), ul17(0), ul28(0),
00052 nodeIInitialDisp(0), nodeJInitialDisp(0), initialDispChecked(false)
00053 {
00054 for (int i = 0; i < 2; i++)
00055 for (int j = 0; j < 3; j++)
00056 R[i][j] = 0.0;
00057
00058 R[2][0] = vecInLocXZPlane(0);
00059 R[2][1] = vecInLocXZPlane(1);
00060 R[2][2] = vecInLocXZPlane(2);
00061
00062
00063 }
00064
00065
00066
00067 PDeltaCrdTransf3d::PDeltaCrdTransf3d(int tag, const Vector &vecInLocXZPlane,
00068 const Vector &rigJntOffset1,
00069 const Vector &rigJntOffset2):
00070 CrdTransf3d(tag, CRDTR_TAG_PDeltaCrdTransf3d),
00071 nodeIPtr(0), nodeJPtr(0),
00072 nodeIOffset(0), nodeJOffset(0),
00073 L(0), ul17(0), ul28(0),
00074 nodeIInitialDisp(0), nodeJInitialDisp(0), initialDispChecked(false)
00075 {
00076 for (int i = 0; i < 2; i++)
00077 for (int j = 0; j < 3; j++)
00078 R[i][j] = 0.0;
00079
00080 R[2][0] = vecInLocXZPlane(0);
00081 R[2][1] = vecInLocXZPlane(1);
00082 R[2][2] = vecInLocXZPlane(2);
00083
00084
00085 if (&rigJntOffset1 == 0 || rigJntOffset1.Size() != 3 ) {
00086 opserr << "PDeltaCrdTransf3d::PDeltaCrdTransf3d: Invalid rigid joint offset vector for node I\n";
00087 opserr << "Size must be 3\n";
00088 }
00089 else if (rigJntOffset1.Norm() > 0.0) {
00090 nodeIOffset = new double[3];
00091 nodeIOffset[0] = rigJntOffset1(0);
00092 nodeIOffset[1] = rigJntOffset1(1);
00093 nodeIOffset[2] = rigJntOffset1(2);
00094 }
00095
00096
00097 if (&rigJntOffset2 == 0 || rigJntOffset2.Size() != 3 ) {
00098 opserr << "PDeltaCrdTransf3d::PDeltaCrdTransf3d: Invalid rigid joint offset vector for node J\n";
00099 opserr << "Size must be 3\n";
00100 }
00101 else if (rigJntOffset2.Norm() > 0.0) {
00102 nodeJOffset = new double[3];
00103 nodeJOffset[0] = rigJntOffset2(0);
00104 nodeJOffset[1] = rigJntOffset2(1);
00105 nodeJOffset[2] = rigJntOffset2(2);
00106 }
00107 }
00108
00109
00110
00111
00112 PDeltaCrdTransf3d::PDeltaCrdTransf3d():
00113 CrdTransf3d(0, CRDTR_TAG_PDeltaCrdTransf3d),
00114 nodeIPtr(0), nodeJPtr(0),
00115 nodeIOffset(0), nodeJOffset(0),
00116 L(0), ul17(0), ul28(0),
00117 nodeIInitialDisp(0), nodeJInitialDisp(0), initialDispChecked(false)
00118 {
00119 for (int i = 0; i < 3; i++)
00120 for (int j = 0; j < 3; j++)
00121 R[i][j] = 0.0;
00122 }
00123
00124
00125
00126 PDeltaCrdTransf3d::~PDeltaCrdTransf3d()
00127 {
00128 if (nodeIOffset)
00129 delete [] nodeIOffset;
00130 if (nodeJOffset)
00131 delete [] nodeJOffset;
00132 if (nodeIInitialDisp != 0)
00133 delete [] nodeIInitialDisp;
00134 if (nodeJInitialDisp != 0)
00135 delete [] nodeJInitialDisp;
00136 }
00137
00138
00139 int
00140 PDeltaCrdTransf3d::commitState(void)
00141 {
00142 return 0;
00143 }
00144
00145
00146 int
00147 PDeltaCrdTransf3d::revertToLastCommit(void)
00148 {
00149 return 0;
00150 }
00151
00152
00153 int
00154 PDeltaCrdTransf3d::revertToStart(void)
00155 {
00156 return 0;
00157 }
00158
00159
00160 int
00161 PDeltaCrdTransf3d::initialize(Node *nodeIPointer, Node *nodeJPointer)
00162 {
00163 int error;
00164
00165 nodeIPtr = nodeIPointer;
00166 nodeJPtr = nodeJPointer;
00167
00168 if ((!nodeIPtr) || (!nodeJPtr))
00169 {
00170 opserr << "\nPDeltaCrdTransf3d::initialize";
00171 opserr << "\ninvalid pointers to the element nodes\n";
00172 return -1;
00173 }
00174
00175
00176 if (initialDispChecked == false) {
00177 const Vector &nodeIDisp = nodeIPtr->getDisp();
00178 const Vector &nodeJDisp = nodeJPtr->getDisp();
00179 for (int i=0; i<6; i++)
00180 if (nodeIDisp(i) != 0.0) {
00181 nodeIInitialDisp = new double [6];
00182 for (int j=0; j<6; j++)
00183 nodeIInitialDisp[j] = nodeIDisp(j);
00184 i = 6;
00185 }
00186
00187 for (int j=0; j<6; j++)
00188 if (nodeJDisp(j) != 0.0) {
00189 nodeJInitialDisp = new double [6];
00190 for (int i=0; i<6; i++)
00191 nodeJInitialDisp[i] = nodeJDisp(i);
00192 j = 6;
00193 }
00194
00195 initialDispChecked = true;
00196 }
00197
00198
00199 if ((error = this->computeElemtLengthAndOrient()))
00200 return error;
00201
00202 static Vector XAxis(3);
00203 static Vector YAxis(3);
00204 static Vector ZAxis(3);
00205
00206
00207 if ((error = this->getLocalAxes(XAxis, YAxis, ZAxis)))
00208 return error;
00209
00210 return 0;
00211 }
00212
00213
00214 int
00215 PDeltaCrdTransf3d::update(void)
00216 {
00217 const Vector &disp1 = nodeIPtr->getTrialDisp();
00218 const Vector &disp2 = nodeJPtr->getTrialDisp();
00219
00220 static double ug[12];
00221 for (int i = 0; i < 6; i++) {
00222 ug[i] = disp1(i);
00223 ug[i+6] = disp2(i);
00224 }
00225
00226 if (nodeIInitialDisp != 0) {
00227 for (int j=0; j<6; j++)
00228 ug[j] -= nodeIInitialDisp[j];
00229 }
00230
00231 if (nodeJInitialDisp != 0) {
00232 for (int j=0; j<6; j++)
00233 ug[j+6] -= nodeJInitialDisp[j];
00234 }
00235
00236 double ul1, ul7, ul2, ul8;
00237
00238 ul1 = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00239 ul2 = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00240
00241 ul7 = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00242 ul8 = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00243
00244 static double Wu[3];
00245
00246 if (nodeIOffset) {
00247 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00248 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00249 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00250
00251 ul1 += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00252 ul2 += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00253 }
00254
00255 if (nodeJOffset) {
00256 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00257 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00258 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00259
00260 ul7 += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00261 ul8 += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00262 }
00263
00264 ul17 = ul1-ul7;
00265 ul28 = ul2-ul8;
00266
00267 return 0;
00268 }
00269
00270
00271 int
00272 PDeltaCrdTransf3d::computeElemtLengthAndOrient()
00273 {
00274
00275 static Vector dx(3);
00276
00277 const Vector &ndICoords = nodeIPtr->getCrds();
00278 const Vector &ndJCoords = nodeJPtr->getCrds();
00279
00280 dx(0) = ndJCoords(0) - ndICoords(0);
00281 dx(1) = ndJCoords(1) - ndICoords(1);
00282 dx(2) = ndJCoords(2) - ndICoords(2);
00283
00284 if (nodeIInitialDisp != 0) {
00285 dx(0) -= nodeIInitialDisp[0];
00286 dx(1) -= nodeIInitialDisp[1];
00287 dx(2) -= nodeIInitialDisp[2];
00288 }
00289
00290 if (nodeJInitialDisp != 0) {
00291 dx(0) += nodeJInitialDisp[0];
00292 dx(1) += nodeJInitialDisp[1];
00293 dx(2) += nodeJInitialDisp[2];
00294 }
00295
00296 if (nodeJOffset != 0) {
00297 dx(0) += nodeJOffset[0];
00298 dx(1) += nodeJOffset[1];
00299 dx(2) += nodeJOffset[2];
00300 }
00301
00302 if (nodeIOffset != 0) {
00303 dx(0) -= nodeIOffset[0];
00304 dx(1) -= nodeIOffset[1];
00305 dx(2) -= nodeIOffset[2];
00306 }
00307
00308
00309 L = dx.Norm();
00310
00311 if (L == 0.0) {
00312 opserr << "\nPDeltaCrdTransf3d::computeElemtLengthAndOrien: 0 length\n";
00313 return -2;
00314 }
00315
00316
00317
00318 R[0][0] = dx(0)/L;
00319 R[0][1] = dx(1)/L;
00320 R[0][2] = dx(2)/L;
00321
00322 return 0;
00323 }
00324
00325
00326 int
00327 PDeltaCrdTransf3d::getLocalAxes(Vector &XAxis, Vector &YAxis, Vector &ZAxis)
00328 {
00329
00330
00331 static Vector vAxis(3);
00332 vAxis(0) = R[2][0]; vAxis(1) = R[2][1]; vAxis(2) = R[2][2];
00333
00334 static Vector xAxis(3);
00335 xAxis(0) = R[0][0]; xAxis(1) = R[0][1]; xAxis(2) = R[0][2];
00336 XAxis(0) = xAxis(0); XAxis(1) = xAxis(1); XAxis(2) = xAxis(2);
00337
00338 static Vector yAxis(3);
00339
00340 yAxis(0) = vAxis(1)*xAxis(2) - vAxis(2)*xAxis(1);
00341 yAxis(1) = vAxis(2)*xAxis(0) - vAxis(0)*xAxis(2);
00342 yAxis(2) = vAxis(0)*xAxis(1) - vAxis(1)*xAxis(0);
00343
00344 double ynorm = yAxis.Norm();
00345
00346 if (ynorm == 0) {
00347 opserr << "\nPDeltaCrdTransf3d::getLocalAxes";
00348 opserr << "\nvector v that defines plane xz is parallel to x axis\n";
00349 return -3;
00350 }
00351
00352 yAxis /= ynorm;
00353
00354 YAxis(0) = yAxis(0); YAxis(1) = yAxis(1); YAxis(2) = yAxis(2);
00355
00356
00357 static Vector zAxis(3);
00358
00359 zAxis(0) = xAxis(1)*yAxis(2) - xAxis(2)*yAxis(1);
00360 zAxis(1) = xAxis(2)*yAxis(0) - xAxis(0)*yAxis(2);
00361 zAxis(2) = xAxis(0)*yAxis(1) - xAxis(1)*yAxis(0);
00362 ZAxis(0) = zAxis(0); ZAxis(1) = zAxis(1); ZAxis(2) = zAxis(2);
00363
00364
00365 R[1][0] = yAxis(0);
00366 R[1][1] = yAxis(1);
00367 R[1][2] = yAxis(2);
00368
00369 R[2][0] = zAxis(0);
00370 R[2][1] = zAxis(1);
00371 R[2][2] = zAxis(2);
00372
00373 return 0;
00374 }
00375
00376
00377 double
00378 PDeltaCrdTransf3d::getInitialLength(void)
00379 {
00380 return L;
00381 }
00382
00383
00384 double
00385 PDeltaCrdTransf3d::getDeformedLength(void)
00386 {
00387 return L;
00388 }
00389
00390
00391 const Vector &
00392 PDeltaCrdTransf3d::getBasicTrialDisp (void)
00393 {
00394
00395 const Vector &disp1 = nodeIPtr->getTrialDisp();
00396 const Vector &disp2 = nodeJPtr->getTrialDisp();
00397
00398 static double ug[12];
00399 for (int i = 0; i < 6; i++) {
00400 ug[i] = disp1(i);
00401 ug[i+6] = disp2(i);
00402 }
00403
00404 if (nodeIInitialDisp != 0) {
00405 for (int j=0; j<6; j++)
00406 ug[j] -= nodeIInitialDisp[j];
00407 }
00408
00409 if (nodeJInitialDisp != 0) {
00410 for (int j=0; j<6; j++)
00411 ug[j+6] -= nodeJInitialDisp[j];
00412 }
00413
00414 double oneOverL = 1.0/L;
00415
00416 static Vector ub(6);
00417
00418 static double ul[12];
00419
00420 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00421 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00422 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00423
00424 ul[3] = R[0][0]*ug[3] + R[0][1]*ug[4] + R[0][2]*ug[5];
00425 ul[4] = R[1][0]*ug[3] + R[1][1]*ug[4] + R[1][2]*ug[5];
00426 ul[5] = R[2][0]*ug[3] + R[2][1]*ug[4] + R[2][2]*ug[5];
00427
00428 ul[6] = R[0][0]*ug[6] + R[0][1]*ug[7] + R[0][2]*ug[8];
00429 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00430 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00431
00432 ul[9] = R[0][0]*ug[9] + R[0][1]*ug[10] + R[0][2]*ug[11];
00433 ul[10] = R[1][0]*ug[9] + R[1][1]*ug[10] + R[1][2]*ug[11];
00434 ul[11] = R[2][0]*ug[9] + R[2][1]*ug[10] + R[2][2]*ug[11];
00435
00436 static double Wu[3];
00437 if (nodeIOffset) {
00438 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00439 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00440 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00441
00442 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00443 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00444 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00445 }
00446
00447 if (nodeJOffset) {
00448 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00449 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00450 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00451
00452 ul[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00453 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00454 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00455 }
00456
00457 ub(0) = ul[6] - ul[0];
00458 double tmp;
00459 tmp = oneOverL*(ul[1]-ul[7]);
00460 ub(1) = ul[5] + tmp;
00461 ub(2) = ul[11] + tmp;
00462 tmp = oneOverL*(ul[8]-ul[2]);
00463 ub(3) = ul[4] + tmp;
00464 ub(4) = ul[10] + tmp;
00465 ub(5) = ul[9] - ul[3];
00466
00467 return ub;
00468 }
00469
00470
00471 const Vector &
00472 PDeltaCrdTransf3d::getBasicIncrDisp (void)
00473 {
00474
00475 const Vector &disp1 = nodeIPtr->getIncrDisp();
00476 const Vector &disp2 = nodeJPtr->getIncrDisp();
00477
00478 static double ug[12];
00479 for (int i = 0; i < 6; i++) {
00480 ug[i] = disp1(i);
00481 ug[i+6] = disp2(i);
00482 }
00483
00484 double oneOverL = 1.0/L;
00485
00486 static Vector ub(6);
00487
00488 static double ul[12];
00489
00490 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00491 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00492 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00493
00494 ul[3] = R[0][0]*ug[3] + R[0][1]*ug[4] + R[0][2]*ug[5];
00495 ul[4] = R[1][0]*ug[3] + R[1][1]*ug[4] + R[1][2]*ug[5];
00496 ul[5] = R[2][0]*ug[3] + R[2][1]*ug[4] + R[2][2]*ug[5];
00497
00498 ul[6] = R[0][0]*ug[6] + R[0][1]*ug[7] + R[0][2]*ug[8];
00499 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00500 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00501
00502 ul[9] = R[0][0]*ug[9] + R[0][1]*ug[10] + R[0][2]*ug[11];
00503 ul[10] = R[1][0]*ug[9] + R[1][1]*ug[10] + R[1][2]*ug[11];
00504 ul[11] = R[2][0]*ug[9] + R[2][1]*ug[10] + R[2][2]*ug[11];
00505
00506 static double Wu[3];
00507 if (nodeIOffset) {
00508 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00509 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00510 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00511
00512 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00513 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00514 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00515 }
00516
00517 if (nodeJOffset) {
00518 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00519 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00520 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00521
00522 ul[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00523 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00524 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00525 }
00526
00527 ub(0) = ul[6] - ul[0];
00528 double tmp;
00529 tmp = oneOverL*(ul[1]-ul[7]);
00530 ub(1) = ul[5] + tmp;
00531 ub(2) = ul[11] + tmp;
00532 tmp = oneOverL*(ul[8]-ul[2]);
00533 ub(3) = ul[4] + tmp;
00534 ub(4) = ul[10] + tmp;
00535 ub(5) = ul[9] - ul[3];
00536
00537 return ub;
00538 }
00539
00540
00541 const Vector &
00542 PDeltaCrdTransf3d::getBasicIncrDeltaDisp(void)
00543 {
00544
00545 const Vector &disp1 = nodeIPtr->getIncrDeltaDisp();
00546 const Vector &disp2 = nodeJPtr->getIncrDeltaDisp();
00547
00548 static double ug[12];
00549 for (int i = 0; i < 6; i++) {
00550 ug[i] = disp1(i);
00551 ug[i+6] = disp2(i);
00552 }
00553
00554 double oneOverL = 1.0/L;
00555
00556 static Vector ub(6);
00557
00558 static double ul[12];
00559
00560 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00561 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00562 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00563
00564 ul[3] = R[0][0]*ug[3] + R[0][1]*ug[4] + R[0][2]*ug[5];
00565 ul[4] = R[1][0]*ug[3] + R[1][1]*ug[4] + R[1][2]*ug[5];
00566 ul[5] = R[2][0]*ug[3] + R[2][1]*ug[4] + R[2][2]*ug[5];
00567
00568 ul[6] = R[0][0]*ug[6] + R[0][1]*ug[7] + R[0][2]*ug[8];
00569 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00570 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00571
00572 ul[9] = R[0][0]*ug[9] + R[0][1]*ug[10] + R[0][2]*ug[11];
00573 ul[10] = R[1][0]*ug[9] + R[1][1]*ug[10] + R[1][2]*ug[11];
00574 ul[11] = R[2][0]*ug[9] + R[2][1]*ug[10] + R[2][2]*ug[11];
00575
00576 static double Wu[3];
00577 if (nodeIOffset) {
00578 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00579 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00580 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00581
00582 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00583 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00584 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00585 }
00586
00587 if (nodeJOffset) {
00588 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00589 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00590 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00591
00592 ul[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00593 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00594 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00595 }
00596
00597 ub(0) = ul[6] - ul[0];
00598 double tmp;
00599 tmp = oneOverL*(ul[1]-ul[7]);
00600 ub(1) = ul[5] + tmp;
00601 ub(2) = ul[11] + tmp;
00602 tmp = oneOverL*(ul[8]-ul[2]);
00603 ub(3) = ul[4] + tmp;
00604 ub(4) = ul[10] + tmp;
00605 ub(5) = ul[9] - ul[3];
00606
00607 return ub;
00608 }
00609
00610
00611 const Vector &
00612 PDeltaCrdTransf3d::getBasicTrialVel(void)
00613 {
00614
00615 const Vector &vel1 = nodeIPtr->getTrialVel();
00616 const Vector &vel2 = nodeJPtr->getTrialVel();
00617
00618 static double vg[12];
00619 for (int i = 0; i < 6; i++) {
00620 vg[i] = vel1(i);
00621 vg[i+6] = vel2(i);
00622 }
00623
00624 double oneOverL = 1.0/L;
00625
00626 static Vector vb(6);
00627
00628 static double vl[12];
00629
00630 vl[0] = R[0][0]*vg[0] + R[0][1]*vg[1] + R[0][2]*vg[2];
00631 vl[1] = R[1][0]*vg[0] + R[1][1]*vg[1] + R[1][2]*vg[2];
00632 vl[2] = R[2][0]*vg[0] + R[2][1]*vg[1] + R[2][2]*vg[2];
00633
00634 vl[3] = R[0][0]*vg[3] + R[0][1]*vg[4] + R[0][2]*vg[5];
00635 vl[4] = R[1][0]*vg[3] + R[1][1]*vg[4] + R[1][2]*vg[5];
00636 vl[5] = R[2][0]*vg[3] + R[2][1]*vg[4] + R[2][2]*vg[5];
00637
00638 vl[6] = R[0][0]*vg[6] + R[0][1]*vg[7] + R[0][2]*vg[8];
00639 vl[7] = R[1][0]*vg[6] + R[1][1]*vg[7] + R[1][2]*vg[8];
00640 vl[8] = R[2][0]*vg[6] + R[2][1]*vg[7] + R[2][2]*vg[8];
00641
00642 vl[9] = R[0][0]*vg[9] + R[0][1]*vg[10] + R[0][2]*vg[11];
00643 vl[10] = R[1][0]*vg[9] + R[1][1]*vg[10] + R[1][2]*vg[11];
00644 vl[11] = R[2][0]*vg[9] + R[2][1]*vg[10] + R[2][2]*vg[11];
00645
00646 static double Wu[3];
00647 if (nodeIOffset) {
00648 Wu[0] = nodeIOffset[2]*vg[4] - nodeIOffset[1]*vg[5];
00649 Wu[1] = -nodeIOffset[2]*vg[3] + nodeIOffset[0]*vg[5];
00650 Wu[2] = nodeIOffset[1]*vg[3] - nodeIOffset[0]*vg[4];
00651
00652 vl[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00653 vl[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00654 vl[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00655 }
00656
00657 if (nodeJOffset) {
00658 Wu[0] = nodeJOffset[2]*vg[10] - nodeJOffset[1]*vg[11];
00659 Wu[1] = -nodeJOffset[2]*vg[9] + nodeJOffset[0]*vg[11];
00660 Wu[2] = nodeJOffset[1]*vg[9] - nodeJOffset[0]*vg[10];
00661
00662 vl[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00663 vl[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00664 vl[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00665 }
00666
00667 vb(0) = vl[6] - vl[0];
00668 double tmp;
00669 tmp = oneOverL*(vl[1]-vl[7]);
00670 vb(1) = vl[5] + tmp;
00671 vb(2) = vl[11] + tmp;
00672 tmp = oneOverL*(vl[8]-vl[2]);
00673 vb(3) = vl[4] + tmp;
00674 vb(4) = vl[10] + tmp;
00675 vb(5) = vl[9] - vl[3];
00676
00677 return vb;
00678 }
00679
00680
00681 const Vector &
00682 PDeltaCrdTransf3d::getBasicTrialAccel(void)
00683 {
00684
00685 const Vector &accel1 = nodeIPtr->getTrialAccel();
00686 const Vector &accel2 = nodeJPtr->getTrialAccel();
00687
00688 static double ag[12];
00689 for (int i = 0; i < 6; i++) {
00690 ag[i] = accel1(i);
00691 ag[i+6] = accel2(i);
00692 }
00693
00694 double oneOverL = 1.0/L;
00695
00696 static Vector ab(6);
00697
00698 static double al[12];
00699
00700 al[0] = R[0][0]*ag[0] + R[0][1]*ag[1] + R[0][2]*ag[2];
00701 al[1] = R[1][0]*ag[0] + R[1][1]*ag[1] + R[1][2]*ag[2];
00702 al[2] = R[2][0]*ag[0] + R[2][1]*ag[1] + R[2][2]*ag[2];
00703
00704 al[3] = R[0][0]*ag[3] + R[0][1]*ag[4] + R[0][2]*ag[5];
00705 al[4] = R[1][0]*ag[3] + R[1][1]*ag[4] + R[1][2]*ag[5];
00706 al[5] = R[2][0]*ag[3] + R[2][1]*ag[4] + R[2][2]*ag[5];
00707
00708 al[6] = R[0][0]*ag[6] + R[0][1]*ag[7] + R[0][2]*ag[8];
00709 al[7] = R[1][0]*ag[6] + R[1][1]*ag[7] + R[1][2]*ag[8];
00710 al[8] = R[2][0]*ag[6] + R[2][1]*ag[7] + R[2][2]*ag[8];
00711
00712 al[9] = R[0][0]*ag[9] + R[0][1]*ag[10] + R[0][2]*ag[11];
00713 al[10] = R[1][0]*ag[9] + R[1][1]*ag[10] + R[1][2]*ag[11];
00714 al[11] = R[2][0]*ag[9] + R[2][1]*ag[10] + R[2][2]*ag[11];
00715
00716 static double Wu[3];
00717 if (nodeIOffset) {
00718 Wu[0] = nodeIOffset[2]*ag[4] - nodeIOffset[1]*ag[5];
00719 Wu[1] = -nodeIOffset[2]*ag[3] + nodeIOffset[0]*ag[5];
00720 Wu[2] = nodeIOffset[1]*ag[3] - nodeIOffset[0]*ag[4];
00721
00722 al[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00723 al[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00724 al[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00725 }
00726
00727 if (nodeJOffset) {
00728 Wu[0] = nodeJOffset[2]*ag[10] - nodeJOffset[1]*ag[11];
00729 Wu[1] = -nodeJOffset[2]*ag[9] + nodeJOffset[0]*ag[11];
00730 Wu[2] = nodeJOffset[1]*ag[9] - nodeJOffset[0]*ag[10];
00731
00732 al[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00733 al[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00734 al[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00735 }
00736
00737 ab(0) = al[6] - al[0];
00738 double tmp;
00739 tmp = oneOverL*(al[1]-al[7]);
00740 ab(1) = al[5] + tmp;
00741 ab(2) = al[11] + tmp;
00742 tmp = oneOverL*(al[8]-al[2]);
00743 ab(3) = al[4] + tmp;
00744 ab(4) = al[10] + tmp;
00745 ab(5) = al[9] - al[3];
00746
00747 return ab;
00748 }
00749
00750
00751 const Vector &
00752 PDeltaCrdTransf3d::getGlobalResistingForce(const Vector &pb, const Vector &p0)
00753 {
00754
00755 static double pl[12];
00756
00757 double q0 = pb(0);
00758 double q1 = pb(1);
00759 double q2 = pb(2);
00760 double q3 = pb(3);
00761 double q4 = pb(4);
00762 double q5 = pb(5);
00763
00764 double oneOverL = 1.0/L;
00765
00766 pl[0] = -q0;
00767 pl[1] = oneOverL*(q1+q2);
00768 pl[2] = -oneOverL*(q3+q4);
00769 pl[3] = -q5;
00770 pl[4] = q3;
00771 pl[5] = q1;
00772 pl[6] = q0;
00773 pl[7] = -pl[1];
00774 pl[8] = -pl[2];
00775 pl[9] = q5;
00776 pl[10] = q4;
00777 pl[11] = q2;
00778
00779 pl[0] += p0(0);
00780 pl[1] += p0(1);
00781 pl[7] += p0(2);
00782 pl[2] += p0(3);
00783 pl[8] += p0(4);
00784
00785
00786 double NoverL;
00787 NoverL = ul17*q0*oneOverL;
00788 pl[1] += NoverL;
00789 pl[7] -= NoverL;
00790 NoverL = ul28*q0*oneOverL;
00791 pl[2] += NoverL;
00792 pl[8] -= NoverL;
00793
00794
00795 static Vector pg(12);
00796
00797 pg(0) = R[0][0]*pl[0] + R[1][0]*pl[1] + R[2][0]*pl[2];
00798 pg(1) = R[0][1]*pl[0] + R[1][1]*pl[1] + R[2][1]*pl[2];
00799 pg(2) = R[0][2]*pl[0] + R[1][2]*pl[1] + R[2][2]*pl[2];
00800
00801 pg(3) = R[0][0]*pl[3] + R[1][0]*pl[4] + R[2][0]*pl[5];
00802 pg(4) = R[0][1]*pl[3] + R[1][1]*pl[4] + R[2][1]*pl[5];
00803 pg(5) = R[0][2]*pl[3] + R[1][2]*pl[4] + R[2][2]*pl[5];
00804
00805 pg(6) = R[0][0]*pl[6] + R[1][0]*pl[7] + R[2][0]*pl[8];
00806 pg(7) = R[0][1]*pl[6] + R[1][1]*pl[7] + R[2][1]*pl[8];
00807 pg(8) = R[0][2]*pl[6] + R[1][2]*pl[7] + R[2][2]*pl[8];
00808
00809 pg(9) = R[0][0]*pl[9] + R[1][0]*pl[10] + R[2][0]*pl[11];
00810 pg(10) = R[0][1]*pl[9] + R[1][1]*pl[10] + R[2][1]*pl[11];
00811 pg(11) = R[0][2]*pl[9] + R[1][2]*pl[10] + R[2][2]*pl[11];
00812
00813 if (nodeIOffset) {
00814 pg(3) += -nodeIOffset[2]*pg(1) + nodeIOffset[1]*pg(2);
00815 pg(4) += nodeIOffset[2]*pg(0) - nodeIOffset[0]*pg(2);
00816 pg(5) += -nodeIOffset[1]*pg(0) + nodeIOffset[0]*pg(1);
00817 }
00818
00819 if (nodeJOffset) {
00820 pg(9) += -nodeJOffset[2]*pg(7) + nodeJOffset[1]*pg(8);
00821 pg(10) += nodeJOffset[2]*pg(6) - nodeJOffset[0]*pg(8);
00822 pg(11) += -nodeJOffset[1]*pg(6) + nodeJOffset[0]*pg(7);
00823 }
00824
00825 return pg;
00826 }
00827
00828
00829 const Matrix &
00830 PDeltaCrdTransf3d::getGlobalStiffMatrix (const Matrix &KB, const Vector &pb)
00831 {
00832 static Matrix kg(12,12);
00833 static double kb[6][6];
00834 static double kl[12][12];
00835 static double tmp[12][12];
00836
00837 double oneOverL = 1.0/L;
00838
00839 int i,j;
00840 for (i = 0; i < 6; i++)
00841 for (j = 0; j < 6; j++)
00842 kb[i][j] = KB(i,j);
00843
00844
00845
00846 for (i = 0; i < 6; i++) {
00847 tmp[i][0] = -kb[i][0];
00848 tmp[i][1] = oneOverL*(kb[i][1]+kb[i][2]);
00849 tmp[i][2] = -oneOverL*(kb[i][3]+kb[i][4]);
00850 tmp[i][3] = -kb[i][5];
00851 tmp[i][4] = kb[i][3];
00852 tmp[i][5] = kb[i][1];
00853 tmp[i][6] = kb[i][0];
00854 tmp[i][7] = -tmp[i][1];
00855 tmp[i][8] = -tmp[i][2];
00856 tmp[i][9] = kb[i][5];
00857 tmp[i][10] = kb[i][4];
00858 tmp[i][11] = kb[i][2];
00859 }
00860
00861
00862 for (i = 0; i < 12; i++) {
00863 kl[0][i] = -tmp[0][i];
00864 kl[1][i] = oneOverL*(tmp[1][i]+tmp[2][i]);
00865 kl[2][i] = -oneOverL*(tmp[3][i]+tmp[4][i]);
00866 kl[3][i] = -tmp[5][i];
00867 kl[4][i] = tmp[3][i];
00868 kl[5][i] = tmp[1][i];
00869 kl[6][i] = tmp[0][i];
00870 kl[7][i] = -kl[1][i];
00871 kl[8][i] = -kl[2][i];
00872 kl[9][i] = tmp[5][i];
00873 kl[10][i] = tmp[4][i];
00874 kl[11][i] = tmp[2][i];
00875 }
00876
00877
00878 double NoverL = pb(0)*oneOverL;
00879 kl[1][1] += NoverL;
00880 kl[2][2] += NoverL;
00881 kl[7][7] += NoverL;
00882 kl[8][8] += NoverL;
00883 kl[1][7] -= NoverL;
00884 kl[7][1] -= NoverL;
00885 kl[2][8] -= NoverL;
00886 kl[8][2] -= NoverL;
00887
00888 static double RWI[3][3];
00889
00890 if (nodeIOffset) {
00891
00892 RWI[0][0] = -R[0][1]*nodeIOffset[2] + R[0][2]*nodeIOffset[1];
00893 RWI[1][0] = -R[1][1]*nodeIOffset[2] + R[1][2]*nodeIOffset[1];
00894 RWI[2][0] = -R[2][1]*nodeIOffset[2] + R[2][2]*nodeIOffset[1];
00895
00896 RWI[0][1] = R[0][0]*nodeIOffset[2] - R[0][2]*nodeIOffset[0];
00897 RWI[1][1] = R[1][0]*nodeIOffset[2] - R[1][2]*nodeIOffset[0];
00898 RWI[2][1] = R[2][0]*nodeIOffset[2] - R[2][2]*nodeIOffset[0];
00899
00900 RWI[0][2] = -R[0][0]*nodeIOffset[1] + R[0][1]*nodeIOffset[0];
00901 RWI[1][2] = -R[1][0]*nodeIOffset[1] + R[1][1]*nodeIOffset[0];
00902 RWI[2][2] = -R[2][0]*nodeIOffset[1] + R[2][1]*nodeIOffset[0];
00903 }
00904
00905 static double RWJ[3][3];
00906
00907 if (nodeJOffset) {
00908
00909 RWJ[0][0] = -R[0][1]*nodeJOffset[2] + R[0][2]*nodeJOffset[1];
00910 RWJ[1][0] = -R[1][1]*nodeJOffset[2] + R[1][2]*nodeJOffset[1];
00911 RWJ[2][0] = -R[2][1]*nodeJOffset[2] + R[2][2]*nodeJOffset[1];
00912
00913 RWJ[0][1] = R[0][0]*nodeJOffset[2] - R[0][2]*nodeJOffset[0];
00914 RWJ[1][1] = R[1][0]*nodeJOffset[2] - R[1][2]*nodeJOffset[0];
00915 RWJ[2][1] = R[2][0]*nodeJOffset[2] - R[2][2]*nodeJOffset[0];
00916
00917 RWJ[0][2] = -R[0][0]*nodeJOffset[1] + R[0][1]*nodeJOffset[0];
00918 RWJ[1][2] = -R[1][0]*nodeJOffset[1] + R[1][1]*nodeJOffset[0];
00919 RWJ[2][2] = -R[2][0]*nodeJOffset[1] + R[2][1]*nodeJOffset[0];
00920 }
00921
00922
00923
00924 int m;
00925 for (m = 0; m < 12; m++) {
00926 tmp[m][0] = kl[m][0]*R[0][0] + kl[m][1]*R[1][0] + kl[m][2]*R[2][0];
00927 tmp[m][1] = kl[m][0]*R[0][1] + kl[m][1]*R[1][1] + kl[m][2]*R[2][1];
00928 tmp[m][2] = kl[m][0]*R[0][2] + kl[m][1]*R[1][2] + kl[m][2]*R[2][2];
00929
00930 tmp[m][3] = kl[m][3]*R[0][0] + kl[m][4]*R[1][0] + kl[m][5]*R[2][0];
00931 tmp[m][4] = kl[m][3]*R[0][1] + kl[m][4]*R[1][1] + kl[m][5]*R[2][1];
00932 tmp[m][5] = kl[m][3]*R[0][2] + kl[m][4]*R[1][2] + kl[m][5]*R[2][2];
00933
00934 if (nodeIOffset) {
00935 tmp[m][3] += kl[m][0]*RWI[0][0] + kl[m][1]*RWI[1][0] + kl[m][2]*RWI[2][0];
00936 tmp[m][4] += kl[m][0]*RWI[0][1] + kl[m][1]*RWI[1][1] + kl[m][2]*RWI[2][1];
00937 tmp[m][5] += kl[m][0]*RWI[0][2] + kl[m][1]*RWI[1][2] + kl[m][2]*RWI[2][2];
00938 }
00939
00940 tmp[m][6] = kl[m][6]*R[0][0] + kl[m][7]*R[1][0] + kl[m][8]*R[2][0];
00941 tmp[m][7] = kl[m][6]*R[0][1] + kl[m][7]*R[1][1] + kl[m][8]*R[2][1];
00942 tmp[m][8] = kl[m][6]*R[0][2] + kl[m][7]*R[1][2] + kl[m][8]*R[2][2];
00943
00944 tmp[m][9] = kl[m][9]*R[0][0] + kl[m][10]*R[1][0] + kl[m][11]*R[2][0];
00945 tmp[m][10] = kl[m][9]*R[0][1] + kl[m][10]*R[1][1] + kl[m][11]*R[2][1];
00946 tmp[m][11] = kl[m][9]*R[0][2] + kl[m][10]*R[1][2] + kl[m][11]*R[2][2];
00947
00948 if (nodeJOffset) {
00949 tmp[m][9] += kl[m][6]*RWJ[0][0] + kl[m][7]*RWJ[1][0] + kl[m][8]*RWJ[2][0];
00950 tmp[m][10] += kl[m][6]*RWJ[0][1] + kl[m][7]*RWJ[1][1] + kl[m][8]*RWJ[2][1];
00951 tmp[m][11] += kl[m][6]*RWJ[0][2] + kl[m][7]*RWJ[1][2] + kl[m][8]*RWJ[2][2];
00952 }
00953
00954 }
00955
00956
00957 for (m = 0; m < 12; m++) {
00958 kg(0,m) = R[0][0]*tmp[0][m] + R[1][0]*tmp[1][m] + R[2][0]*tmp[2][m];
00959 kg(1,m) = R[0][1]*tmp[0][m] + R[1][1]*tmp[1][m] + R[2][1]*tmp[2][m];
00960 kg(2,m) = R[0][2]*tmp[0][m] + R[1][2]*tmp[1][m] + R[2][2]*tmp[2][m];
00961
00962 kg(3,m) = R[0][0]*tmp[3][m] + R[1][0]*tmp[4][m] + R[2][0]*tmp[5][m];
00963 kg(4,m) = R[0][1]*tmp[3][m] + R[1][1]*tmp[4][m] + R[2][1]*tmp[5][m];
00964 kg(5,m) = R[0][2]*tmp[3][m] + R[1][2]*tmp[4][m] + R[2][2]*tmp[5][m];
00965
00966 if (nodeIOffset) {
00967 kg(3,m) += RWI[0][0]*tmp[0][m] + RWI[1][0]*tmp[1][m] + RWI[2][0]*tmp[2][m];
00968 kg(4,m) += RWI[0][1]*tmp[0][m] + RWI[1][1]*tmp[1][m] + RWI[2][1]*tmp[2][m];
00969 kg(5,m) += RWI[0][2]*tmp[0][m] + RWI[1][2]*tmp[1][m] + RWI[2][2]*tmp[2][m];
00970 }
00971
00972 kg(6,m) = R[0][0]*tmp[6][m] + R[1][0]*tmp[7][m] + R[2][0]*tmp[8][m];
00973 kg(7,m) = R[0][1]*tmp[6][m] + R[1][1]*tmp[7][m] + R[2][1]*tmp[8][m];
00974 kg(8,m) = R[0][2]*tmp[6][m] + R[1][2]*tmp[7][m] + R[2][2]*tmp[8][m];
00975
00976 kg(9,m) = R[0][0]*tmp[9][m] + R[1][0]*tmp[10][m] + R[2][0]*tmp[11][m];
00977 kg(10,m) = R[0][1]*tmp[9][m] + R[1][1]*tmp[10][m] + R[2][1]*tmp[11][m];
00978 kg(11,m) = R[0][2]*tmp[9][m] + R[1][2]*tmp[10][m] + R[2][2]*tmp[11][m];
00979
00980 if (nodeJOffset) {
00981 kg(9,m) += RWJ[0][0]*tmp[6][m] + RWJ[1][0]*tmp[7][m] + RWJ[2][0]*tmp[8][m];
00982 kg(10,m) += RWJ[0][1]*tmp[6][m] + RWJ[1][1]*tmp[7][m] + RWJ[2][1]*tmp[8][m];
00983 kg(11,m) += RWJ[0][2]*tmp[6][m] + RWJ[1][2]*tmp[7][m] + RWJ[2][2]*tmp[8][m];
00984 }
00985 }
00986
00987 return kg;
00988 }
00989
00990
00991 const Matrix &
00992 PDeltaCrdTransf3d::getInitialGlobalStiffMatrix (const Matrix &KB)
00993 {
00994 static Matrix kg(12,12);
00995 static double kb[6][6];
00996 static double kl[12][12];
00997 static double tmp[12][12];
00998
00999 double oneOverL = 1.0/L;
01000
01001 int i,j;
01002 for (i = 0; i < 6; i++)
01003 for (j = 0; j < 6; j++)
01004 kb[i][j] = KB(i,j);
01005
01006
01007
01008 for (i = 0; i < 6; i++) {
01009 tmp[i][0] = -kb[i][0];
01010 tmp[i][1] = oneOverL*(kb[i][1]+kb[i][2]);
01011 tmp[i][2] = -oneOverL*(kb[i][3]+kb[i][4]);
01012 tmp[i][3] = -kb[i][5];
01013 tmp[i][4] = kb[i][3];
01014 tmp[i][5] = kb[i][1];
01015 tmp[i][6] = kb[i][0];
01016 tmp[i][7] = -tmp[i][1];
01017 tmp[i][8] = -tmp[i][2];
01018 tmp[i][9] = kb[i][5];
01019 tmp[i][10] = kb[i][4];
01020 tmp[i][11] = kb[i][2];
01021 }
01022
01023
01024 for (i = 0; i < 12; i++) {
01025 kl[0][i] = -tmp[0][i];
01026 kl[1][i] = oneOverL*(tmp[1][i]+tmp[2][i]);
01027 kl[2][i] = -oneOverL*(tmp[3][i]+tmp[4][i]);
01028 kl[3][i] = -tmp[5][i];
01029 kl[4][i] = tmp[3][i];
01030 kl[5][i] = tmp[1][i];
01031 kl[6][i] = tmp[0][i];
01032 kl[7][i] = -kl[1][i];
01033 kl[8][i] = -kl[2][i];
01034 kl[9][i] = tmp[5][i];
01035 kl[10][i] = tmp[4][i];
01036 kl[11][i] = tmp[2][i];
01037 }
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 static double RWI[3][3];
01052
01053 if (nodeIOffset) {
01054
01055 RWI[0][0] = -R[0][1]*nodeIOffset[2] + R[0][2]*nodeIOffset[1];
01056 RWI[1][0] = -R[1][1]*nodeIOffset[2] + R[1][2]*nodeIOffset[1];
01057 RWI[2][0] = -R[2][1]*nodeIOffset[2] + R[2][2]*nodeIOffset[1];
01058
01059 RWI[0][1] = R[0][0]*nodeIOffset[2] - R[0][2]*nodeIOffset[0];
01060 RWI[1][1] = R[1][0]*nodeIOffset[2] - R[1][2]*nodeIOffset[0];
01061 RWI[2][1] = R[2][0]*nodeIOffset[2] - R[2][2]*nodeIOffset[0];
01062
01063 RWI[0][2] = -R[0][0]*nodeIOffset[1] + R[0][1]*nodeIOffset[0];
01064 RWI[1][2] = -R[1][0]*nodeIOffset[1] + R[1][1]*nodeIOffset[0];
01065 RWI[2][2] = -R[2][0]*nodeIOffset[1] + R[2][1]*nodeIOffset[0];
01066 }
01067
01068 static double RWJ[3][3];
01069
01070 if (nodeJOffset) {
01071
01072 RWJ[0][0] = -R[0][1]*nodeJOffset[2] + R[0][2]*nodeJOffset[1];
01073 RWJ[1][0] = -R[1][1]*nodeJOffset[2] + R[1][2]*nodeJOffset[1];
01074 RWJ[2][0] = -R[2][1]*nodeJOffset[2] + R[2][2]*nodeJOffset[1];
01075
01076 RWJ[0][1] = R[0][0]*nodeJOffset[2] - R[0][2]*nodeJOffset[0];
01077 RWJ[1][1] = R[1][0]*nodeJOffset[2] - R[1][2]*nodeJOffset[0];
01078 RWJ[2][1] = R[2][0]*nodeJOffset[2] - R[2][2]*nodeJOffset[0];
01079
01080 RWJ[0][2] = -R[0][0]*nodeJOffset[1] + R[0][1]*nodeJOffset[0];
01081 RWJ[1][2] = -R[1][0]*nodeJOffset[1] + R[1][1]*nodeJOffset[0];
01082 RWJ[2][2] = -R[2][0]*nodeJOffset[1] + R[2][1]*nodeJOffset[0];
01083 }
01084
01085
01086
01087
01088 int m;
01089 for (m = 0; m < 12; m++) {
01090 tmp[m][0] = kl[m][0]*R[0][0] + kl[m][1]*R[1][0] + kl[m][2]*R[2][0];
01091 tmp[m][1] = kl[m][0]*R[0][1] + kl[m][1]*R[1][1] + kl[m][2]*R[2][1];
01092 tmp[m][2] = kl[m][0]*R[0][2] + kl[m][1]*R[1][2] + kl[m][2]*R[2][2];
01093
01094 tmp[m][3] = kl[m][3]*R[0][0] + kl[m][4]*R[1][0] + kl[m][5]*R[2][0];
01095 tmp[m][4] = kl[m][3]*R[0][1] + kl[m][4]*R[1][1] + kl[m][5]*R[2][1];
01096 tmp[m][5] = kl[m][3]*R[0][2] + kl[m][4]*R[1][2] + kl[m][5]*R[2][2];
01097
01098 if (nodeIOffset) {
01099 tmp[m][3] += kl[m][0]*RWI[0][0] + kl[m][1]*RWI[1][0] + kl[m][2]*RWI[2][0];
01100 tmp[m][4] += kl[m][0]*RWI[0][1] + kl[m][1]*RWI[1][1] + kl[m][2]*RWI[2][1];
01101 tmp[m][5] += kl[m][0]*RWI[0][2] + kl[m][1]*RWI[1][2] + kl[m][2]*RWI[2][2];
01102 }
01103
01104 tmp[m][6] = kl[m][6]*R[0][0] + kl[m][7]*R[1][0] + kl[m][8]*R[2][0];
01105 tmp[m][7] = kl[m][6]*R[0][1] + kl[m][7]*R[1][1] + kl[m][8]*R[2][1];
01106 tmp[m][8] = kl[m][6]*R[0][2] + kl[m][7]*R[1][2] + kl[m][8]*R[2][2];
01107
01108 tmp[m][9] = kl[m][9]*R[0][0] + kl[m][10]*R[1][0] + kl[m][11]*R[2][0];
01109 tmp[m][10] = kl[m][9]*R[0][1] + kl[m][10]*R[1][1] + kl[m][11]*R[2][1];
01110 tmp[m][11] = kl[m][9]*R[0][2] + kl[m][10]*R[1][2] + kl[m][11]*R[2][2];
01111
01112 if (nodeJOffset) {
01113 tmp[m][9] += kl[m][6]*RWJ[0][0] + kl[m][7]*RWJ[1][0] + kl[m][8]*RWJ[2][0];
01114 tmp[m][10] += kl[m][6]*RWJ[0][1] + kl[m][7]*RWJ[1][1] + kl[m][8]*RWJ[2][1];
01115 tmp[m][11] += kl[m][6]*RWJ[0][2] + kl[m][7]*RWJ[1][2] + kl[m][8]*RWJ[2][2];
01116 }
01117
01118 }
01119
01120
01121 for (m = 0; m < 12; m++) {
01122 kg(0,m) = R[0][0]*tmp[0][m] + R[1][0]*tmp[1][m] + R[2][0]*tmp[2][m];
01123 kg(1,m) = R[0][1]*tmp[0][m] + R[1][1]*tmp[1][m] + R[2][1]*tmp[2][m];
01124 kg(2,m) = R[0][2]*tmp[0][m] + R[1][2]*tmp[1][m] + R[2][2]*tmp[2][m];
01125
01126 kg(3,m) = R[0][0]*tmp[3][m] + R[1][0]*tmp[4][m] + R[2][0]*tmp[5][m];
01127 kg(4,m) = R[0][1]*tmp[3][m] + R[1][1]*tmp[4][m] + R[2][1]*tmp[5][m];
01128 kg(5,m) = R[0][2]*tmp[3][m] + R[1][2]*tmp[4][m] + R[2][2]*tmp[5][m];
01129
01130 if (nodeIOffset) {
01131 kg(3,m) += RWI[0][0]*tmp[0][m] + RWI[1][0]*tmp[1][m] + RWI[2][0]*tmp[2][m];
01132 kg(4,m) += RWI[0][1]*tmp[0][m] + RWI[1][1]*tmp[1][m] + RWI[2][1]*tmp[2][m];
01133 kg(5,m) += RWI[0][2]*tmp[0][m] + RWI[1][2]*tmp[1][m] + RWI[2][2]*tmp[2][m];
01134 }
01135
01136 kg(6,m) = R[0][0]*tmp[6][m] + R[1][0]*tmp[7][m] + R[2][0]*tmp[8][m];
01137 kg(7,m) = R[0][1]*tmp[6][m] + R[1][1]*tmp[7][m] + R[2][1]*tmp[8][m];
01138 kg(8,m) = R[0][2]*tmp[6][m] + R[1][2]*tmp[7][m] + R[2][2]*tmp[8][m];
01139
01140 kg(9,m) = R[0][0]*tmp[9][m] + R[1][0]*tmp[10][m] + R[2][0]*tmp[11][m];
01141 kg(10,m) = R[0][1]*tmp[9][m] + R[1][1]*tmp[10][m] + R[2][1]*tmp[11][m];
01142 kg(11,m) = R[0][2]*tmp[9][m] + R[1][2]*tmp[10][m] + R[2][2]*tmp[11][m];
01143
01144 if (nodeJOffset) {
01145 kg(9,m) += RWJ[0][0]*tmp[6][m] + RWJ[1][0]*tmp[7][m] + RWJ[2][0]*tmp[8][m];
01146 kg(10,m) += RWJ[0][1]*tmp[6][m] + RWJ[1][1]*tmp[7][m] + RWJ[2][1]*tmp[8][m];
01147 kg(11,m) += RWJ[0][2]*tmp[6][m] + RWJ[1][2]*tmp[7][m] + RWJ[2][2]*tmp[8][m];
01148 }
01149 }
01150
01151 return kg;
01152 }
01153
01154
01155 CrdTransf3d *
01156 PDeltaCrdTransf3d::getCopy(void)
01157 {
01158
01159
01160 PDeltaCrdTransf3d *theCopy;
01161
01162 static Vector xz(3);
01163 xz(0) = R[2][0];
01164 xz(1) = R[2][1];
01165 xz(2) = R[2][2];
01166
01167 Vector offsetI(3);
01168 Vector offsetJ(3);
01169
01170 if (nodeIOffset) {
01171 offsetI(0) = nodeIOffset[0];
01172 offsetI(1) = nodeIOffset[1];
01173 offsetI(2) = nodeIOffset[2];
01174 }
01175
01176 if (nodeJOffset) {
01177 offsetJ(0) = nodeJOffset[0];
01178 offsetJ(1) = nodeJOffset[1];
01179 offsetJ(2) = nodeJOffset[2];
01180 }
01181
01182 theCopy = new PDeltaCrdTransf3d(this->getTag(), xz, offsetI, offsetJ);
01183
01184 theCopy->nodeIPtr = nodeIPtr;
01185 theCopy->nodeJPtr = nodeJPtr;
01186 theCopy->L = L;
01187 theCopy->ul17 = ul17;
01188 theCopy->ul28 = ul28;
01189 for (int i = 0; i < 3; i++)
01190 for (int j = 0; j < 3; j++)
01191 theCopy->R[i][j] = R[i][j];
01192
01193
01194 return theCopy;
01195 }
01196
01197
01198 int
01199 PDeltaCrdTransf3d::sendSelf(int cTag, Channel &theChannel)
01200 {
01201 int res = 0;
01202
01203 static Vector data(23);
01204 data(0) = this->getTag();
01205 data(1) = L;
01206
01207 if (nodeIOffset != 0) {
01208 data(2) = nodeIOffset[0];
01209 data(3) = nodeIOffset[1];
01210 data(4) = nodeIOffset[2];
01211 } else {
01212 data(2) = 0.0;
01213 data(3) = 0.0;
01214 data(4) = 0.0;
01215 }
01216
01217 if (nodeJOffset != 0) {
01218 data(5) = nodeJOffset[0];
01219 data(6) = nodeJOffset[1];
01220 data(7) = nodeJOffset[2];
01221 } else {
01222 data(5) = 0.0;
01223 data(6) = 0.0;
01224 data(7) = 0.0;
01225 }
01226
01227 if (nodeIInitialDisp != 0) {
01228 data(8) = nodeIInitialDisp[0];
01229 data(9) = nodeIInitialDisp[1];
01230 data(10) = nodeIInitialDisp[2];
01231 data(11) = nodeIInitialDisp[3];
01232 data(12) = nodeIInitialDisp[4];
01233 data(13) = nodeIInitialDisp[5];
01234 } else {
01235 data(8) = 0.0;
01236 data(9) = 0.0;
01237 data(10) = 0.0;
01238 data(11) = 0.0;
01239 data(12) = 0.0;
01240 data(13) = 0.0;
01241 }
01242
01243 if (nodeJInitialDisp != 0) {
01244 data(14) = nodeJInitialDisp[0];
01245 data(15) = nodeJInitialDisp[1];
01246 data(16) = nodeJInitialDisp[2];
01247 data(17) = nodeJInitialDisp[3];
01248 data(18) = nodeJInitialDisp[4];
01249 data(19) = nodeJInitialDisp[5];
01250 } else {
01251 data(14) = 0.0;
01252 data(15) = 0.0;
01253 data(16) = 0.0;
01254 data(17) = 0.0;
01255 data(18) = 0.0;
01256 data(19) = 0.0;
01257 }
01258
01259 data(20) = R[2][0];
01260 data(21) = R[2][1];
01261 data(22) = R[2][2];
01262
01263 res += theChannel.sendVector(this->getDbTag(), cTag, data);
01264 if (res < 0) {
01265 opserr << "PDeltaCrdTransf3d::sendSelf - failed to send Vector\n";
01266 return res;
01267 }
01268
01269 return res;
01270 }
01271
01272
01273 int
01274 PDeltaCrdTransf3d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
01275 {
01276 int res = 0;
01277
01278 static Vector data(13);
01279
01280 res += theChannel.recvVector(this->getDbTag(), cTag, data);
01281 if (res < 0) {
01282 opserr << "PDeltaCrdTransf3d::recvSelf - failed to receive Vector\n";
01283 return res;
01284 }
01285
01286 this->setTag((int)data(0));
01287 L = data(1);
01288 data(0) = this->getTag();
01289 data(1) = L;
01290
01291 int flag;
01292 int i,j;
01293
01294 flag = 0;
01295 for (i=2; i<=4; i++)
01296 if (data(i) != 0.0)
01297 flag = 1;
01298 if (flag == 1) {
01299 if (nodeIOffset == 0)
01300 nodeIOffset = new double[3];
01301 for (i=2, j=0; i<=4; i++, j++)
01302 nodeIOffset[j] = data(i);
01303 }
01304
01305 flag = 0;
01306 for (i=5; i<=7; i++)
01307 if (data(i) != 0.0)
01308 flag = 1;
01309 if (flag == 1) {
01310 if (nodeJOffset == 0)
01311 nodeJOffset = new double[3];
01312 for (i=5, j=0; i<=7; i++, j++)
01313 nodeJOffset[j] = data(i);
01314 }
01315
01316 flag = 0;
01317 for (i=8; i<=13; i++)
01318 if (data(i) != 0.0)
01319 flag = 1;
01320 if (flag == 1) {
01321 if (nodeIInitialDisp == 0)
01322 nodeIInitialDisp = new double[6];
01323 for (i=8, j=0; i<=13; i++, j++)
01324 nodeIInitialDisp[j] = data(i);
01325 }
01326
01327 flag = 0;
01328 for (i=14; i<=19; i++)
01329 if (data(i) != 0.0)
01330 flag = 1;
01331 if (flag == 1) {
01332 if (nodeJInitialDisp == 0)
01333 nodeJInitialDisp = new double [6];
01334 for (i=14, j=0; i<=19; i++, j++)
01335 nodeJInitialDisp[j] = data(i);
01336 }
01337
01338 R[2][0] = data(20);
01339 R[2][1] = data(21);
01340 R[2][2] = data(22);
01341
01342 initialDispChecked = true;
01343
01344 return res;
01345 }
01346
01347
01348 const Vector &
01349 PDeltaCrdTransf3d::getPointGlobalCoordFromLocal(const Vector &xl)
01350 {
01351 static Vector xg(3);
01352
01353
01354 xg = nodeIPtr->getCrds();
01355
01356 if (nodeIOffset) {
01357 xg(0) += nodeIOffset[0];
01358 xg(1) += nodeIOffset[1];
01359 xg(2) += nodeIOffset[2];
01360 }
01361
01362
01363
01364 xg(0) += R[0][0]*xl(0) + R[1][0]*xl(1) + R[2][0]*xl(2);
01365 xg(1) += R[0][1]*xl(0) + R[1][1]*xl(1) + R[2][1]*xl(2);
01366 xg(2) += R[0][2]*xl(0) + R[1][2]*xl(1) + R[2][2]*xl(2);
01367
01368 return xg;
01369 }
01370
01371
01372 const Vector &
01373 PDeltaCrdTransf3d::getPointGlobalDisplFromBasic (double xi, const Vector &uxb)
01374 {
01375
01376 const Vector &disp1 = nodeIPtr->getTrialDisp();
01377 const Vector &disp2 = nodeJPtr->getTrialDisp();
01378
01379 static double ug[12];
01380 for (int i = 0; i < 6; i++)
01381 {
01382 ug[i] = disp1(i);
01383 ug[i+6] = disp2(i);
01384 }
01385
01386 if (nodeIInitialDisp != 0) {
01387 for (int j=0; j<6; j++)
01388 ug[j] -= nodeIInitialDisp[j];
01389 }
01390
01391 if (nodeJInitialDisp != 0) {
01392 for (int j=0; j<6; j++)
01393 ug[j+6] -= nodeJInitialDisp[j];
01394 }
01395
01396
01397
01398 static double ul[12];
01399
01400 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
01401 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
01402 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
01403
01404 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
01405 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
01406
01407 static double Wu[3];
01408 if (nodeIOffset) {
01409 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
01410 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
01411 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
01412
01413 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
01414 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
01415 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
01416 }
01417
01418 if (nodeJOffset) {
01419 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
01420 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
01421 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
01422
01423 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
01424 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
01425 }
01426
01427
01428 static double uxl[3];
01429 static Vector uxg(3);
01430
01431 uxl[0] = uxb(0) + ul[0];
01432 uxl[1] = uxb(1) + (1-xi)*ul[1] + xi*ul[7];
01433 uxl[2] = uxb(2) + (1-xi)*ul[2] + xi*ul[8];
01434
01435
01436
01437
01438 uxg(0) = R[0][0]*uxl[0] + R[1][0]*uxl[1] + R[2][0]*uxl[2];
01439 uxg(1) = R[0][1]*uxl[0] + R[1][1]*uxl[1] + R[2][1]*uxl[2];
01440 uxg(2) = R[0][2]*uxl[0] + R[1][2]*uxl[1] + R[2][2]*uxl[2];
01441
01442 return uxg;
01443 }
01444
01445
01446 void
01447 PDeltaCrdTransf3d::Print(OPS_Stream &s, int flag)
01448 {
01449 s << "\nCrdTransf: " << this->getTag() << " Type: PDeltaCrdTransf3d" << endln;
01450 if (nodeIOffset)
01451 s << "\tNode I offset: " << nodeIOffset[0] << " " << nodeIOffset[1] << " "<< nodeIOffset[2] << endln;
01452 if (nodeJOffset)
01453 s << "\tNode J offset: " << nodeJOffset[0] << " " << nodeJOffset[1] << " "<< nodeJOffset[2] << endln;
01454 }