PDeltaCrdTransf3d.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020 
00021 // $Revision: 1.13 $
00022 // $Date: 2005/12/15 00:30:38 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/coordTransformation/PDeltaCrdTransf3d.cpp,v $
00024 
00025 
00026 // Written: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu)
00027 // Created: 04/2000
00028 // Revision: A
00029 //
00030 // Modified: 04/2005 Andreas Schellenberg (getBasicTrialVel, getBasicTrialAccel)
00031 // 
00032 // Purpose: This file contains the implementation for the 
00033 // PDeltaCrdTransf3d class. PDeltaCrdTransf3d is a linear
00034 // transformation for a planar frame between the global 
00035 // and basic coordinate systems
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 // constructor:
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         // Does nothing
00063 }
00064 
00065 
00066 // constructor:
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         // check rigid joint offset for node I
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         // check rigid joint offset for node J
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 // constructor:
00111 // invoked by a FEM_ObjectBroker, recvSelf() needs to be invoked on this object.
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 // destructor:
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     // see if there is some initial displacements at nodes
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     // get element length and orientation
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     // get 3by3 rotation matrix
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     // element projection
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     // calculate the element length
00309     L = dx.Norm();
00310     
00311     if (L == 0.0) {
00312         opserr << "\nPDeltaCrdTransf3d::computeElemtLengthAndOrien: 0 length\n";
00313         return -2;  
00314     }
00315     
00316     // calculate the element local x axis components (direction cossines)
00317     // wrt to the global coordinates
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     // Compute y = v cross x
00330     // Note: v(i) is stored in R[2][i]
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     // Compute z = x cross y
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     // Fill in transformation matrix
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     // determine global displacements
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     // determine global displacements
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     // determine global displacements
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         // determine global velocities
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         // determine global accelerations
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     // transform resisting forces from the basic system to local coordinates
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     // Include leaning column effects (P-Delta)
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     // transform resisting forces  from local to global coordinates
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);    // Global stiffness for return
00833     static double kb[6][6];             // Basic stiffness
00834     static double kl[12][12];   // Local stiffness
00835     static double tmp[12][12];  // Temporary storage
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         // Transform basic stiffness to local system
00845         // First compute kb*T_{bl}
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         // Now compute T'_{bl}*(kb*T_{bl})
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         // Include geometric stiffness effects in local system
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             // Compute RWI
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             // Compute RWJ
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         // Transform local stiffness to global system
00923         // First compute kl*T_{lg}
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         // Now compute T'_{lg}*(kl*T_{lg})
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);    // Global stiffness for return
00995     static double kb[6][6];             // Basic stiffness
00996     static double kl[12][12];   // Local stiffness
00997     static double tmp[12][12];  // Temporary storage
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         // Transform basic stiffness to local system
01007         // First compute kb*T_{bl}
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         // Now compute T'_{bl}*(kb*T_{bl})
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         // Include geometric stiffness effects in local system
01040         //      double NoverL = pb(0)*oneOverL;
01041         //kl[1][1] += NoverL;
01042         //kl[2][2] += NoverL;
01043         //kl[7][7] += NoverL;
01044         //kl[8][8] += NoverL;
01045         //kl[1][7] -= NoverL;
01046         //kl[7][1] -= NoverL;
01047         //kl[2][8] -= NoverL;
01048         //kl[8][2] -= NoverL;
01049         
01050         
01051         static double RWI[3][3];
01052         
01053         if (nodeIOffset) {
01054             // Compute RWI
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             // Compute RWJ
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         // Transform local stiffness to global system
01086         // First compute kl*T_{lg}
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         // Now compute T'_{lg}*(kl*T_{lg})
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     // create a new instance of PDeltaCrdTransf3d 
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     //xg = nodeIPtr->getCrds() + nodeIOffset;
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     // xg = xg + Rlj'*xl
01363     //xg.addMatrixTransposeVector(1.0, Rlj, xl, 1.0);
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     // determine global displacements
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     // transform global end displacements to local coordinates
01397     //ul.addMatrixVector(0.0, Tlg,  ug, 1.0);       //  ul = Tlg *  ug;
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     // compute displacements at point xi, in local coordinates
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     // rotate displacements to global coordinates
01436     // uxg = Rlj'*uxl
01437     //uxg.addMatrixTransposeVector(0.0, Rlj, uxl, 1.0);
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 }

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