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 <iomanip.h>
00044
00045 #include <PDeltaCrdTransf3d.h>
00046
00047
00048 PDeltaCrdTransf3d::PDeltaCrdTransf3d(int tag, const Vector &vecInLocXZPlane):
00049 CrdTransf3d(tag, CRDTR_TAG_PDeltaCrdTransf3d),
00050 nodeIPtr(0), nodeJPtr(0),
00051 nodeIOffset(0), nodeJOffset(0),
00052 L(0), ul17(0), ul28(0)
00053 {
00054 R[2][0] = vecInLocXZPlane(0);
00055 R[2][1] = vecInLocXZPlane(1);
00056 R[2][2] = vecInLocXZPlane(2);
00057
00058
00059 }
00060
00061
00062 PDeltaCrdTransf3d::PDeltaCrdTransf3d(int tag, const Vector &vecInLocXZPlane,
00063 const Vector &rigJntOffset1,
00064 const Vector &rigJntOffset2):
00065 CrdTransf3d(tag, CRDTR_TAG_PDeltaCrdTransf3d),
00066 nodeIPtr(0), nodeJPtr(0),
00067 nodeIOffset(0), nodeJOffset(0),
00068 L(0), ul17(0), ul28(0)
00069 {
00070 R[2][0] = vecInLocXZPlane(0);
00071 R[2][1] = vecInLocXZPlane(1);
00072 R[2][2] = vecInLocXZPlane(2);
00073
00074
00075 if (&rigJntOffset1 == 0 || rigJntOffset1.Size() != 3 ) {
00076 cerr << "PDeltaCrdTransf3d::PDeltaCrdTransf3d: Invalid rigid joint offset vector for node I\n";
00077 cerr << "Size must be 3\n";
00078 }
00079 else if (rigJntOffset1.Norm() > 0.0) {
00080 nodeIOffset = new double[3];
00081 nodeIOffset[0] = rigJntOffset1(0);
00082 nodeIOffset[1] = rigJntOffset1(1);
00083 nodeIOffset[2] = rigJntOffset1(2);
00084 }
00085
00086
00087 if (&rigJntOffset2 == 0 || rigJntOffset2.Size() != 3 ) {
00088 cerr << "PDeltaCrdTransf3d::PDeltaCrdTransf3d: Invalid rigid joint offset vector for node J\n";
00089 cerr << "Size must be 3\n";
00090 }
00091 else if (rigJntOffset2.Norm() > 0.0) {
00092 nodeJOffset = new double[3];
00093 nodeJOffset[0] = rigJntOffset2(0);
00094 nodeJOffset[1] = rigJntOffset2(1);
00095 nodeJOffset[2] = rigJntOffset2(2);
00096 }
00097 }
00098
00099
00100
00101
00102
00103
00104 PDeltaCrdTransf3d::PDeltaCrdTransf3d():
00105 CrdTransf3d(0, CRDTR_TAG_PDeltaCrdTransf3d),
00106 nodeIPtr(0), nodeJPtr(0),
00107 nodeIOffset(0), nodeJOffset(0),
00108 L(0), ul17(0), ul28(0)
00109 {
00110
00111 }
00112
00113
00114
00115
00116 PDeltaCrdTransf3d::~PDeltaCrdTransf3d()
00117 {
00118 if (nodeIOffset)
00119 delete [] nodeIOffset;
00120 if (nodeJOffset)
00121 delete [] nodeJOffset;
00122 }
00123
00124
00125 int
00126 PDeltaCrdTransf3d::commitState(void)
00127 {
00128 return 0;
00129 }
00130
00131
00132 int
00133 PDeltaCrdTransf3d::revertToLastCommit(void)
00134 {
00135 return 0;
00136 }
00137
00138
00139 int
00140 PDeltaCrdTransf3d::revertToStart(void)
00141 {
00142 return 0;
00143 }
00144
00145
00146 int
00147 PDeltaCrdTransf3d::initialize(Node *nodeIPointer, Node *nodeJPointer)
00148 {
00149 int error;
00150
00151 nodeIPtr = nodeIPointer;
00152 nodeJPtr = nodeJPointer;
00153
00154 if ((!nodeIPtr) || (!nodeJPtr))
00155 {
00156 cerr << "\nPDeltaCrdTransf3d::initialize";
00157 cerr << "\ninvalid pointers to the element nodes\n";
00158 return -1;
00159 }
00160
00161
00162 if ((error = this->computeElemtLengthAndOrient()))
00163 return error;
00164
00165
00166 if ((error = this->getLocalAxes()))
00167 return error;
00168
00169 return 0;
00170 }
00171
00172
00173 int
00174 PDeltaCrdTransf3d::update(void)
00175 {
00176 const Vector &disp1 = nodeIPtr->getTrialDisp();
00177 const Vector &disp2 = nodeJPtr->getTrialDisp();
00178
00179 static double ug[12];
00180 for (int i = 0; i < 6; i++) {
00181 ug[i] = disp1(i);
00182 ug[i+6] = disp2(i);
00183 }
00184
00185 double ul1, ul7, ul2, ul8;
00186
00187 ul1 = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00188 ul2 = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00189
00190 ul7 = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00191 ul8 = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00192
00193 static double Wu[3];
00194
00195 if (nodeIOffset) {
00196 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00197 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00198 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00199
00200 ul1 += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00201 ul2 += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00202 }
00203
00204 if (nodeJOffset) {
00205 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00206 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00207 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00208
00209 ul7 += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00210 ul8 += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00211 }
00212
00213 ul17 = ul1-ul7;
00214 ul28 = ul2-ul8;
00215
00216 return 0;
00217 }
00218
00219
00220 int
00221 PDeltaCrdTransf3d::computeElemtLengthAndOrient()
00222 {
00223
00224 static Vector dx(3);
00225
00226 const Vector &ndICoords = nodeIPtr->getCrds();
00227 const Vector &ndJCoords = nodeJPtr->getCrds();
00228
00229 if (nodeIOffset == 0) {
00230 dx(0) = ndJCoords(0) - ndICoords(0);
00231 dx(1) = ndJCoords(1) - ndICoords(1);
00232 dx(2) = ndJCoords(2) - ndICoords(2);
00233 }
00234 else {
00235 dx(0) = ndJCoords(0) + nodeJOffset[0] - ndICoords(0) - nodeIOffset[0];
00236 dx(1) = ndJCoords(1) + nodeJOffset[1] - ndICoords(1) - nodeIOffset[1];
00237 dx(2) = ndJCoords(2) + nodeJOffset[2] - ndICoords(2) - nodeIOffset[2];
00238 }
00239
00240
00241 L = dx.Norm();
00242
00243 if (L == 0.0) {
00244 cerr << "\nPDeltaCrdTransf3d::computeElemtLengthAndOrien: 0 length\n";
00245 return -2;
00246 }
00247
00248
00249
00250 R[0][0] = dx(0)/L;
00251 R[0][1] = dx(1)/L;
00252 R[0][2] = dx(2)/L;
00253
00254 return 0;
00255 }
00256
00257
00258 int
00259 PDeltaCrdTransf3d::getLocalAxes(void)
00260 {
00261
00262
00263 static Vector vAxis(3);
00264 vAxis(0) = R[2][0]; vAxis(1) = R[2][1]; vAxis(2) = R[2][2];
00265
00266 static Vector xAxis(3);
00267 xAxis(0) = R[0][0]; xAxis(1) = R[0][1]; xAxis(2) = R[0][2];
00268
00269 static Vector yAxis(3);
00270
00271 yAxis(0) = vAxis(1)*xAxis(2) - vAxis(2)*xAxis(1);
00272 yAxis(1) = vAxis(2)*xAxis(0) - vAxis(0)*xAxis(2);
00273 yAxis(2) = vAxis(0)*xAxis(1) - vAxis(1)*xAxis(0);
00274
00275 double ynorm = yAxis.Norm();
00276
00277 if (ynorm == 0) {
00278 cerr << "\nPDeltaCrdTransf3d::getLocalAxes";
00279 cerr << "\nvector v that defines plane xz is parallel to x axis\n";
00280 return -3;
00281 }
00282
00283 yAxis /= ynorm;
00284
00285
00286 static Vector zAxis(3);
00287
00288 zAxis(0) = xAxis(1)*yAxis(2) - xAxis(2)*yAxis(1);
00289 zAxis(1) = xAxis(2)*yAxis(0) - xAxis(0)*yAxis(2);
00290 zAxis(2) = xAxis(0)*yAxis(1) - xAxis(1)*yAxis(0);
00291
00292
00293 R[1][0] = yAxis(0);
00294 R[1][1] = yAxis(1);
00295 R[1][2] = yAxis(2);
00296
00297 R[2][0] = zAxis(0);
00298 R[2][1] = zAxis(1);
00299 R[2][2] = zAxis(2);
00300
00301 return 0;
00302 }
00303
00304
00305
00306 double
00307 PDeltaCrdTransf3d::getInitialLength(void)
00308 {
00309 return L;
00310 }
00311
00312
00313 double
00314 PDeltaCrdTransf3d::getDeformedLength(void)
00315 {
00316 return L;
00317 }
00318
00319
00320 const Vector &
00321 PDeltaCrdTransf3d::getBasicTrialDisp (void)
00322 {
00323
00324 const Vector &disp1 = nodeIPtr->getTrialDisp();
00325 const Vector &disp2 = nodeJPtr->getTrialDisp();
00326
00327 static double ug[12];
00328 for (int i = 0; i < 6; i++) {
00329 ug[i] = disp1(i);
00330 ug[i+6] = disp2(i);
00331 }
00332
00333 double oneOverL = 1.0/L;
00334
00335 static Vector ub(6);
00336
00337 static double ul[12];
00338
00339 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00340 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00341 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00342
00343 ul[3] = R[0][0]*ug[3] + R[0][1]*ug[4] + R[0][2]*ug[5];
00344 ul[4] = R[1][0]*ug[3] + R[1][1]*ug[4] + R[1][2]*ug[5];
00345 ul[5] = R[2][0]*ug[3] + R[2][1]*ug[4] + R[2][2]*ug[5];
00346
00347 ul[6] = R[0][0]*ug[6] + R[0][1]*ug[7] + R[0][2]*ug[8];
00348 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00349 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00350
00351 ul[9] = R[0][0]*ug[9] + R[0][1]*ug[10] + R[0][2]*ug[11];
00352 ul[10] = R[1][0]*ug[9] + R[1][1]*ug[10] + R[1][2]*ug[11];
00353 ul[11] = R[2][0]*ug[9] + R[2][1]*ug[10] + R[2][2]*ug[11];
00354
00355 static double Wu[3];
00356 if (nodeIOffset) {
00357 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00358 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00359 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00360
00361 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00362 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00363 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00364 }
00365
00366 if (nodeJOffset) {
00367 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00368 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00369 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00370
00371 ul[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00372 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00373 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00374 }
00375
00376 ub(0) = ul[6] - ul[0];
00377 double tmp;
00378 tmp = oneOverL*(ul[1]-ul[7]);
00379 ub(1) = ul[5] + tmp;
00380 ub(2) = ul[11] + tmp;
00381 tmp = oneOverL*(ul[8]-ul[2]);
00382 ub(3) = ul[4] + tmp;
00383 ub(4) = ul[10] + tmp;
00384 ub(5) = ul[9] - ul[3];
00385
00386 return ub;
00387 }
00388
00389
00390 const Vector &
00391 PDeltaCrdTransf3d::getBasicIncrDisp (void)
00392 {
00393
00394 const Vector &disp1 = nodeIPtr->getIncrDisp();
00395 const Vector &disp2 = nodeJPtr->getIncrDisp();
00396
00397 static double ug[12];
00398 for (int i = 0; i < 6; i++) {
00399 ug[i] = disp1(i);
00400 ug[i+6] = disp2(i);
00401 }
00402
00403 double oneOverL = 1.0/L;
00404
00405 static Vector ub(6);
00406
00407 static double ul[12];
00408
00409 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00410 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00411 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00412
00413 ul[3] = R[0][0]*ug[3] + R[0][1]*ug[4] + R[0][2]*ug[5];
00414 ul[4] = R[1][0]*ug[3] + R[1][1]*ug[4] + R[1][2]*ug[5];
00415 ul[5] = R[2][0]*ug[3] + R[2][1]*ug[4] + R[2][2]*ug[5];
00416
00417 ul[6] = R[0][0]*ug[6] + R[0][1]*ug[7] + R[0][2]*ug[8];
00418 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00419 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00420
00421 ul[9] = R[0][0]*ug[9] + R[0][1]*ug[10] + R[0][2]*ug[11];
00422 ul[10] = R[1][0]*ug[9] + R[1][1]*ug[10] + R[1][2]*ug[11];
00423 ul[11] = R[2][0]*ug[9] + R[2][1]*ug[10] + R[2][2]*ug[11];
00424
00425 static double Wu[3];
00426 if (nodeIOffset) {
00427 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00428 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00429 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00430
00431 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00432 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00433 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00434 }
00435
00436 if (nodeJOffset) {
00437 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00438 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00439 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00440
00441 ul[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00442 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00443 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00444 }
00445
00446 ub(0) = ul[6] - ul[0];
00447 double tmp;
00448 tmp = oneOverL*(ul[1]-ul[7]);
00449 ub(1) = ul[5] + tmp;
00450 ub(2) = ul[11] + tmp;
00451 tmp = oneOverL*(ul[8]-ul[2]);
00452 ub(3) = ul[4] + tmp;
00453 ub(4) = ul[10] + tmp;
00454 ub(5) = ul[9] - ul[3];
00455
00456 return ub;
00457 }
00458
00459
00460 const Vector &
00461 PDeltaCrdTransf3d::getBasicIncrDeltaDisp(void)
00462 {
00463
00464 const Vector &disp1 = nodeIPtr->getIncrDeltaDisp();
00465 const Vector &disp2 = nodeJPtr->getIncrDeltaDisp();
00466
00467 static double ug[12];
00468 for (int i = 0; i < 6; i++) {
00469 ug[i] = disp1(i);
00470 ug[i+6] = disp2(i);
00471 }
00472
00473 double oneOverL = 1.0/L;
00474
00475 static Vector ub(6);
00476
00477 static double ul[12];
00478
00479 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00480 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00481 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00482
00483 ul[3] = R[0][0]*ug[3] + R[0][1]*ug[4] + R[0][2]*ug[5];
00484 ul[4] = R[1][0]*ug[3] + R[1][1]*ug[4] + R[1][2]*ug[5];
00485 ul[5] = R[2][0]*ug[3] + R[2][1]*ug[4] + R[2][2]*ug[5];
00486
00487 ul[6] = R[0][0]*ug[6] + R[0][1]*ug[7] + R[0][2]*ug[8];
00488 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00489 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00490
00491 ul[9] = R[0][0]*ug[9] + R[0][1]*ug[10] + R[0][2]*ug[11];
00492 ul[10] = R[1][0]*ug[9] + R[1][1]*ug[10] + R[1][2]*ug[11];
00493 ul[11] = R[2][0]*ug[9] + R[2][1]*ug[10] + R[2][2]*ug[11];
00494
00495 static double Wu[3];
00496 if (nodeIOffset) {
00497 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00498 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00499 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00500
00501 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00502 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00503 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00504 }
00505
00506 if (nodeJOffset) {
00507 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00508 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00509 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00510
00511 ul[6] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00512 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00513 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00514 }
00515
00516 ub(0) = ul[6] - ul[0];
00517 double tmp;
00518 tmp = oneOverL*(ul[1]-ul[7]);
00519 ub(1) = ul[5] + tmp;
00520 ub(2) = ul[11] + tmp;
00521 tmp = oneOverL*(ul[8]-ul[2]);
00522 ub(3) = ul[4] + tmp;
00523 ub(4) = ul[10] + tmp;
00524 ub(5) = ul[9] - ul[3];
00525
00526 return ub;
00527 }
00528
00529
00530 const Vector &
00531 PDeltaCrdTransf3d::getGlobalResistingForce(const Vector &pb, const Vector &unifLoad)
00532 {
00533
00534 static double pl[12];
00535
00536 double q0 = pb(0);
00537 double q1 = pb(1);
00538 double q2 = pb(2);
00539 double q3 = pb(3);
00540 double q4 = pb(4);
00541 double q5 = pb(5);
00542
00543 double oneOverL = 1.0/L;
00544
00545 pl[0] = -q0;
00546 pl[1] = oneOverL*(q1+q2);
00547 pl[2] = -oneOverL*(q3+q4);
00548 pl[3] = -q5;
00549 pl[4] = q3;
00550 pl[5] = q1;
00551 pl[6] = q0;
00552 pl[7] = -pl[1];
00553 pl[8] = -pl[2];
00554 pl[9] = q5;
00555 pl[10] = q4;
00556 pl[11] = q2;
00557
00558
00559
00560 pl[0] -= unifLoad(0)*L;
00561 double V;
00562 V = 0.5*unifLoad(1)*L;
00563 pl[1] -= V;
00564 pl[7] -= V;
00565 V = 0.5*unifLoad(2)*L;
00566 pl[2] -= V;
00567 pl[8] -= V;
00568
00569
00570 double NoverL;
00571 NoverL = ul17*q0*oneOverL;
00572 pl[1] += NoverL;
00573 pl[7] -= NoverL;
00574 NoverL = ul28*q0*oneOverL;
00575 pl[2] += NoverL;
00576 pl[8] -= NoverL;
00577
00578
00579 static Vector pg(12);
00580
00581 pg(0) = R[0][0]*pl[0] + R[1][0]*pl[1] + R[2][0]*pl[2];
00582 pg(1) = R[0][1]*pl[0] + R[1][1]*pl[1] + R[2][1]*pl[2];
00583 pg(2) = R[0][2]*pl[0] + R[1][2]*pl[1] + R[2][2]*pl[2];
00584
00585 pg(3) = R[0][0]*pl[3] + R[1][0]*pl[4] + R[2][0]*pl[5];
00586 pg(4) = R[0][1]*pl[3] + R[1][1]*pl[4] + R[2][1]*pl[5];
00587 pg(5) = R[0][2]*pl[3] + R[1][2]*pl[4] + R[2][2]*pl[5];
00588
00589 pg(6) = R[0][0]*pl[6] + R[1][0]*pl[7] + R[2][0]*pl[8];
00590 pg(7) = R[0][1]*pl[6] + R[1][1]*pl[7] + R[2][1]*pl[8];
00591 pg(8) = R[0][2]*pl[6] + R[1][2]*pl[7] + R[2][2]*pl[8];
00592
00593 pg(9) = R[0][0]*pl[9] + R[1][0]*pl[10] + R[2][0]*pl[11];
00594 pg(10) = R[0][1]*pl[9] + R[1][1]*pl[10] + R[2][1]*pl[11];
00595 pg(11) = R[0][2]*pl[9] + R[1][2]*pl[10] + R[2][2]*pl[11];
00596
00597 if (nodeIOffset) {
00598 pg(3) += -nodeIOffset[2]*pg(1) + nodeIOffset[1]*pg(2);
00599 pg(4) += nodeIOffset[2]*pg(0) - nodeIOffset[0]*pg(2);
00600 pg(5) += -nodeIOffset[1]*pg(0) + nodeIOffset[0]*pg(1);
00601 }
00602
00603 if (nodeJOffset) {
00604 pg(9) += -nodeJOffset[2]*pg(7) + nodeJOffset[1]*pg(8);
00605 pg(10) += nodeJOffset[2]*pg(6) - nodeJOffset[0]*pg(8);
00606 pg(11) += -nodeJOffset[1]*pg(6) + nodeJOffset[0]*pg(7);
00607 }
00608
00609 return pg;
00610 }
00611
00612 const Matrix &
00613 PDeltaCrdTransf3d::getGlobalStiffMatrix (const Matrix &KB, const Vector &pb)
00614 {
00615 static Matrix kg(12,12);
00616 static double kb[6][6];
00617 static double kl[12][12];
00618 static double tmp[12][12];
00619
00620 double oneOverL = 1.0/L;
00621
00622 int i,j;
00623 for (i = 0; i < 6; i++)
00624 for (j = 0; j < 6; j++)
00625 kb[i][j] = KB(i,j);
00626
00627
00628
00629 for (i = 0; i < 6; i++) {
00630 tmp[i][0] = -kb[i][0];
00631 tmp[i][1] = oneOverL*(kb[i][1]+kb[i][2]);
00632 tmp[i][2] = -oneOverL*(kb[i][3]+kb[i][4]);
00633 tmp[i][3] = -kb[i][5];
00634 tmp[i][4] = kb[i][3];
00635 tmp[i][5] = kb[i][1];
00636 tmp[i][6] = kb[i][0];
00637 tmp[i][7] = -tmp[i][1];
00638 tmp[i][8] = -tmp[i][2];
00639 tmp[i][9] = kb[i][5];
00640 tmp[i][10] = kb[i][4];
00641 tmp[i][11] = kb[i][2];
00642 }
00643
00644
00645 for (i = 0; i < 12; i++) {
00646 kl[0][i] = -tmp[0][i];
00647 kl[1][i] = oneOverL*(tmp[1][i]+tmp[2][i]);
00648 kl[2][i] = -oneOverL*(tmp[3][i]+tmp[4][i]);
00649 kl[3][i] = -tmp[5][i];
00650 kl[4][i] = tmp[3][i];
00651 kl[5][i] = tmp[1][i];
00652 kl[6][i] = tmp[0][i];
00653 kl[7][i] = -kl[1][i];
00654 kl[8][i] = -kl[2][i];
00655 kl[9][i] = tmp[5][i];
00656 kl[10][i] = tmp[4][i];
00657 kl[11][i] = tmp[2][i];
00658 }
00659
00660
00661 double NoverL = pb(0)*oneOverL;
00662 kl[1][1] += NoverL;
00663 kl[2][2] += NoverL;
00664 kl[7][7] += NoverL;
00665 kl[8][8] += NoverL;
00666 kl[1][7] -= NoverL;
00667 kl[7][1] -= NoverL;
00668 kl[2][8] -= NoverL;
00669 kl[8][2] -= NoverL;
00670
00671 static double RWI[3][3];
00672
00673 if (nodeIOffset) {
00674
00675 RWI[0][0] = -R[0][1]*nodeIOffset[2] + R[0][2]*nodeIOffset[1];
00676 RWI[1][0] = -R[1][1]*nodeIOffset[2] + R[1][2]*nodeIOffset[1];
00677 RWI[2][0] = -R[2][1]*nodeIOffset[2] + R[2][2]*nodeIOffset[1];
00678
00679 RWI[0][1] = R[0][0]*nodeIOffset[2] - R[0][2]*nodeIOffset[0];
00680 RWI[1][1] = R[1][0]*nodeIOffset[2] - R[1][2]*nodeIOffset[0];
00681 RWI[2][1] = R[2][0]*nodeIOffset[2] - R[2][2]*nodeIOffset[0];
00682
00683 RWI[0][2] = -R[0][0]*nodeIOffset[1] + R[0][1]*nodeIOffset[0];
00684 RWI[1][2] = -R[1][0]*nodeIOffset[1] + R[1][1]*nodeIOffset[0];
00685 RWI[2][2] = -R[2][0]*nodeIOffset[1] + R[2][1]*nodeIOffset[0];
00686 }
00687
00688 static double RWJ[3][3];
00689
00690 if (nodeJOffset) {
00691
00692 RWJ[0][0] = -R[0][1]*nodeJOffset[2] + R[0][2]*nodeJOffset[1];
00693 RWJ[1][0] = -R[1][1]*nodeJOffset[2] + R[1][2]*nodeJOffset[1];
00694 RWJ[2][0] = -R[2][1]*nodeJOffset[2] + R[2][2]*nodeJOffset[1];
00695
00696 RWJ[0][1] = R[0][0]*nodeJOffset[2] - R[0][2]*nodeJOffset[0];
00697 RWJ[1][1] = R[1][0]*nodeJOffset[2] - R[1][2]*nodeJOffset[0];
00698 RWJ[2][1] = R[2][0]*nodeJOffset[2] - R[2][2]*nodeJOffset[0];
00699
00700 RWJ[0][2] = -R[0][0]*nodeJOffset[1] + R[0][1]*nodeJOffset[0];
00701 RWJ[1][2] = -R[1][0]*nodeJOffset[1] + R[1][1]*nodeJOffset[0];
00702 RWJ[2][2] = -R[2][0]*nodeJOffset[1] + R[2][1]*nodeJOffset[0];
00703 }
00704
00705
00706
00707 int m;
00708 for (m = 0; m < 12; m++) {
00709 tmp[m][0] = kl[m][0]*R[0][0] + kl[m][1]*R[1][0] + kl[m][2]*R[2][0];
00710 tmp[m][1] = kl[m][0]*R[0][1] + kl[m][1]*R[1][1] + kl[m][2]*R[2][1];
00711 tmp[m][2] = kl[m][0]*R[0][2] + kl[m][1]*R[1][2] + kl[m][2]*R[2][2];
00712
00713 tmp[m][3] = kl[m][3]*R[0][0] + kl[m][4]*R[1][0] + kl[m][5]*R[2][0];
00714 tmp[m][4] = kl[m][3]*R[0][1] + kl[m][4]*R[1][1] + kl[m][5]*R[2][1];
00715 tmp[m][5] = kl[m][3]*R[0][2] + kl[m][4]*R[1][2] + kl[m][5]*R[2][2];
00716
00717 if (nodeIOffset) {
00718 tmp[m][3] += kl[m][0]*RWI[0][0] + kl[m][1]*RWI[1][0] + kl[m][2]*RWI[2][0];
00719 tmp[m][4] += kl[m][0]*RWI[0][1] + kl[m][1]*RWI[1][1] + kl[m][2]*RWI[2][1];
00720 tmp[m][5] += kl[m][0]*RWI[0][2] + kl[m][1]*RWI[1][2] + kl[m][2]*RWI[2][2];
00721 }
00722
00723 tmp[m][6] = kl[m][6]*R[0][0] + kl[m][7]*R[1][0] + kl[m][8]*R[2][0];
00724 tmp[m][7] = kl[m][6]*R[0][1] + kl[m][7]*R[1][1] + kl[m][8]*R[2][1];
00725 tmp[m][8] = kl[m][6]*R[0][2] + kl[m][7]*R[1][2] + kl[m][8]*R[2][2];
00726
00727 tmp[m][9] = kl[m][9]*R[0][0] + kl[m][10]*R[1][0] + kl[m][11]*R[2][0];
00728 tmp[m][10] = kl[m][9]*R[0][1] + kl[m][10]*R[1][1] + kl[m][11]*R[2][1];
00729 tmp[m][11] = kl[m][9]*R[0][2] + kl[m][10]*R[1][2] + kl[m][11]*R[2][2];
00730
00731 if (nodeJOffset) {
00732 tmp[m][9] += kl[m][6]*RWJ[0][0] + kl[m][7]*RWJ[1][0] + kl[m][8]*RWJ[2][0];
00733 tmp[m][10] += kl[m][6]*RWJ[0][1] + kl[m][7]*RWJ[1][1] + kl[m][8]*RWJ[2][1];
00734 tmp[m][11] += kl[m][6]*RWJ[0][2] + kl[m][7]*RWJ[1][2] + kl[m][8]*RWJ[2][2];
00735 }
00736
00737 }
00738
00739
00740 for (m = 0; m < 12; m++) {
00741 kg(0,m) = R[0][0]*tmp[0][m] + R[1][0]*tmp[1][m] + R[2][0]*tmp[2][m];
00742 kg(1,m) = R[0][1]*tmp[0][m] + R[1][1]*tmp[1][m] + R[2][1]*tmp[2][m];
00743 kg(2,m) = R[0][2]*tmp[0][m] + R[1][2]*tmp[1][m] + R[2][2]*tmp[2][m];
00744
00745 kg(3,m) = R[0][0]*tmp[3][m] + R[1][0]*tmp[4][m] + R[2][0]*tmp[5][m];
00746 kg(4,m) = R[0][1]*tmp[3][m] + R[1][1]*tmp[4][m] + R[2][1]*tmp[5][m];
00747 kg(5,m) = R[0][2]*tmp[3][m] + R[1][2]*tmp[4][m] + R[2][2]*tmp[5][m];
00748
00749 if (nodeIOffset) {
00750 kg(3,m) += RWI[0][0]*tmp[0][m] + RWI[1][0]*tmp[1][m] + RWI[2][0]*tmp[2][m];
00751 kg(4,m) += RWI[0][1]*tmp[0][m] + RWI[1][1]*tmp[1][m] + RWI[2][1]*tmp[2][m];
00752 kg(5,m) += RWI[0][2]*tmp[0][m] + RWI[1][2]*tmp[1][m] + RWI[2][2]*tmp[2][m];
00753 }
00754
00755 kg(6,m) = R[0][0]*tmp[6][m] + R[1][0]*tmp[7][m] + R[2][0]*tmp[8][m];
00756 kg(7,m) = R[0][1]*tmp[6][m] + R[1][1]*tmp[7][m] + R[2][1]*tmp[8][m];
00757 kg(8,m) = R[0][2]*tmp[6][m] + R[1][2]*tmp[7][m] + R[2][2]*tmp[8][m];
00758
00759 kg(9,m) = R[0][0]*tmp[9][m] + R[1][0]*tmp[10][m] + R[2][0]*tmp[11][m];
00760 kg(10,m) = R[0][1]*tmp[9][m] + R[1][1]*tmp[10][m] + R[2][1]*tmp[11][m];
00761 kg(11,m) = R[0][2]*tmp[9][m] + R[1][2]*tmp[10][m] + R[2][2]*tmp[11][m];
00762
00763 if (nodeJOffset) {
00764 kg(9,m) += RWJ[0][0]*tmp[6][m] + RWJ[1][0]*tmp[7][m] + RWJ[2][0]*tmp[8][m];
00765 kg(10,m) += RWJ[0][1]*tmp[6][m] + RWJ[1][1]*tmp[7][m] + RWJ[2][1]*tmp[8][m];
00766 kg(11,m) += RWJ[0][2]*tmp[6][m] + RWJ[1][2]*tmp[7][m] + RWJ[2][2]*tmp[8][m];
00767 }
00768 }
00769
00770 return kg;
00771 }
00772
00773
00774
00775
00776 CrdTransf3d *
00777 PDeltaCrdTransf3d::getCopy(void)
00778 {
00779
00780
00781 PDeltaCrdTransf3d *theCopy;
00782
00783 static Vector xz(3);
00784 xz(0) = R[2][0];
00785 xz(1) = R[2][1];
00786 xz(2) = R[2][2];
00787
00788 Vector offsetI(3);
00789 Vector offsetJ(3);
00790
00791 if (nodeIOffset) {
00792 offsetI(0) = nodeIOffset[0];
00793 offsetI(1) = nodeIOffset[1];
00794 offsetI(2) = nodeIOffset[2];
00795 }
00796
00797 if (nodeJOffset) {
00798 offsetJ(0) = nodeJOffset[0];
00799 offsetJ(1) = nodeJOffset[1];
00800 offsetJ(2) = nodeJOffset[2];
00801 }
00802
00803 theCopy = new PDeltaCrdTransf3d(this->getTag(), xz, offsetI, offsetJ);
00804
00805 theCopy->nodeIPtr = nodeIPtr;
00806 theCopy->nodeJPtr = nodeJPtr;
00807 theCopy->L = L;
00808 theCopy->ul17 = ul17;
00809 theCopy->ul28 = ul28;
00810 for (int i = 0; i < 3; i++)
00811 for (int j = 0; j < 3; j++)
00812 theCopy->R[i][j] = R[i][j];
00813
00814
00815 return theCopy;
00816 }
00817
00818
00819 int
00820 PDeltaCrdTransf3d::sendSelf(int cTag, Channel &theChannel)
00821 {
00822 int res = 0;
00823
00824 static Vector data(9);
00825
00826 data(0) = this->getTag();
00827 data(6) = L;
00828
00829 res += theChannel.sendVector(this->getDbTag(), cTag, data);
00830 if (res < 0) {
00831 g3ErrorHandler->warning("%s - failed to send Vector",
00832 "PDeltaCrdTransf3d::sendSelf");
00833 return res;
00834 }
00835
00836 return res;
00837 }
00838
00839
00840
00841 int
00842 PDeltaCrdTransf3d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00843 {
00844 int res = 0;
00845
00846 static Vector data(9);
00847
00848 res += theChannel.recvVector(this->getDbTag(), cTag, data);
00849 if (res < 0) {
00850 g3ErrorHandler->warning("%s - failed to receive Vector",
00851 "PDeltaCrdTransf3d::recvSelf");
00852 return res;
00853 }
00854
00855 this->setTag((int)data(0));
00856 L = data(6);
00857
00858 return res;
00859 }
00860
00861
00862 const Vector &
00863 PDeltaCrdTransf3d::getPointGlobalCoordFromLocal(const Vector &xl)
00864 {
00865 static Vector xg(3);
00866
00867
00868 xg = nodeIPtr->getCrds();
00869
00870 if (nodeIOffset) {
00871 xg(0) += nodeIOffset[0];
00872 xg(1) += nodeIOffset[1];
00873 xg(2) += nodeIOffset[2];
00874 }
00875
00876
00877
00878 xg(0) += R[0][0]*xl(0) + R[0][1]*xl(1) + R[0][2]*xl(2);
00879 xg(1) += R[1][0]*xl(0) + R[1][1]*xl(1) + R[1][2]*xl(2);
00880 xg(2) += R[2][0]*xl(0) + R[2][1]*xl(1) + R[2][2]*xl(2);
00881
00882 return xg;
00883 }
00884
00885
00886 const Vector &
00887 PDeltaCrdTransf3d::getPointGlobalDisplFromBasic (double xi, const Vector &uxb)
00888 {
00889
00890 const Vector &disp1 = nodeIPtr->getTrialDisp();
00891 const Vector &disp2 = nodeJPtr->getTrialDisp();
00892
00893 static double ug[12];
00894 for (int i = 0; i < 6; i++)
00895 {
00896 ug[i] = disp1(i);
00897 ug[i+6] = disp2(i);
00898 }
00899
00900
00901
00902 static double ul[12];
00903
00904 ul[0] = R[0][0]*ug[0] + R[0][1]*ug[1] + R[0][2]*ug[2];
00905 ul[1] = R[1][0]*ug[0] + R[1][1]*ug[1] + R[1][2]*ug[2];
00906 ul[2] = R[2][0]*ug[0] + R[2][1]*ug[1] + R[2][2]*ug[2];
00907
00908 ul[7] = R[1][0]*ug[6] + R[1][1]*ug[7] + R[1][2]*ug[8];
00909 ul[8] = R[2][0]*ug[6] + R[2][1]*ug[7] + R[2][2]*ug[8];
00910
00911 static double Wu[3];
00912 if (nodeIOffset) {
00913 Wu[0] = nodeIOffset[2]*ug[4] - nodeIOffset[1]*ug[5];
00914 Wu[1] = -nodeIOffset[2]*ug[3] + nodeIOffset[0]*ug[5];
00915 Wu[2] = nodeIOffset[1]*ug[3] - nodeIOffset[0]*ug[4];
00916
00917 ul[0] += R[0][0]*Wu[0] + R[0][1]*Wu[1] + R[0][2]*Wu[2];
00918 ul[1] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00919 ul[2] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00920 }
00921
00922 if (nodeJOffset) {
00923 Wu[0] = nodeJOffset[2]*ug[10] - nodeJOffset[1]*ug[11];
00924 Wu[1] = -nodeJOffset[2]*ug[9] + nodeJOffset[0]*ug[11];
00925 Wu[2] = nodeJOffset[1]*ug[9] - nodeJOffset[0]*ug[10];
00926
00927 ul[7] += R[1][0]*Wu[0] + R[1][1]*Wu[1] + R[1][2]*Wu[2];
00928 ul[8] += R[2][0]*Wu[0] + R[2][1]*Wu[1] + R[2][2]*Wu[2];
00929 }
00930
00931
00932 static double uxl[3];
00933 static Vector uxg(3);
00934
00935 uxl[0] = uxb(0) + ul[0];
00936 uxl[1] = uxb(1) + (1-xi)*ul[1] + xi*ul[7];
00937 uxl[2] = uxb(2) + (1-xi)*ul[2] + xi*ul[8];
00938
00939
00940
00941
00942 uxg(0) = R[0][0]*uxl[0] + R[1][0]*uxl[1] + R[2][0]*uxl[2];
00943 uxg(1) = R[0][1]*uxl[0] + R[1][1]*uxl[1] + R[2][1]*uxl[2];
00944 uxg(2) = R[0][2]*uxl[0] + R[1][2]*uxl[1] + R[2][2]*uxl[2];
00945
00946 return uxg;
00947 }
00948
00949
00950
00951 void
00952 PDeltaCrdTransf3d::Print(ostream &s, int flag)
00953 {
00954 s << "\nCrdTransf: " << this->getTag() << " Type: PDeltaCrdTransf3d" << endl;
00955 if (nodeIOffset)
00956 s << "\tNode I offset: " << nodeIOffset[0] << ' ' << nodeIOffset[1] << ' '<< nodeIOffset[2] << endl;
00957 if (nodeJOffset)
00958 s << "\tNode J offset: " << nodeJOffset[0] << ' ' << nodeJOffset[1] << ' '<< nodeJOffset[2] << endl;
00959 }
00960
00961
00962
00963
00964
00965
00966
00967