Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

PDeltaCrdTransf2d.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.1 $
00022 // $Date: 2001/05/30 07:14:38 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/coordTransformation/PDeltaCrdTransf2d.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/crdTransf/PDeltaCrdTransf2d.C
00027 //
00028 // Written: Remo Magalhaes de Souza (rmsouza@ce.berkeley.edu)
00029 // Created: 04/2000
00030 // Revision: A
00031 // 
00032 // Purpose: This file contains the implementation for the 
00033 // PDeltaCrdTransf2d class. PDeltaCrdTransf2d 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 <iomanip.h>
00044 
00045 #include <PDeltaCrdTransf2d.h>
00046 
00047 // constructor:
00048 PDeltaCrdTransf2d::PDeltaCrdTransf2d(int tag):
00049   CrdTransf2d(tag, CRDTR_TAG_PDeltaCrdTransf2d),
00050   nodeIPtr(0), nodeJPtr(0),
00051   nodeIOffset(0), nodeJOffset(0),
00052   cosTheta(0), sinTheta(0), L(0), ul14(0)
00053 {
00054  // Does nothing
00055 }
00056 
00057 // constructor:
00058 PDeltaCrdTransf2d::PDeltaCrdTransf2d(int tag,
00059              const Vector &rigJntOffset1,
00060              const Vector &rigJntOffset2):
00061   CrdTransf2d(tag, CRDTR_TAG_PDeltaCrdTransf2d),
00062   nodeIPtr(0), nodeJPtr(0),
00063   nodeIOffset(0), nodeJOffset(0),
00064   cosTheta(0), sinTheta(0), L(0), ul14(0)
00065 {
00066  // check rigid joint offset for node I
00067  if (&rigJntOffset1 == 0 || rigJntOffset1.Size() != 2 ) {
00068   cerr << "PDeltaCrdTransf2d::PDeltaCrdTransf2d:  Invalid rigid joint offset vector for node I\n";
00069   cerr << "Size must be 2\n";      
00070  }
00071  else {
00072   nodeIOffset = new double[2];
00073   nodeIOffset[0] = rigJntOffset1(0);
00074   nodeIOffset[1] = rigJntOffset1(1);
00075  }
00076    
00077    // check rigid joint offset for node J
00078  if (&rigJntOffset2 == 0 || rigJntOffset2.Size() != 2 ) {
00079   cerr << "PDeltaCrdTransf2d::PDeltaCrdTransf2d:  Invalid rigid joint offset vector for node J\n";
00080   cerr << "Size must be 2\n";      
00081  }
00082  else {
00083   nodeJOffset = new double[2];
00084   nodeJOffset[0] = rigJntOffset2(0);
00085   nodeJOffset[1] = rigJntOffset2(1);
00086  }
00087 }
00088 
00089 
00090 
00091  
00092 // constructor:
00093 // invoked by a FEM_ObjectBroker, recvSelf() needs to be invoked on this object.
00094 PDeltaCrdTransf2d::PDeltaCrdTransf2d():
00095   CrdTransf2d(0, CRDTR_TAG_PDeltaCrdTransf2d),
00096   nodeIPtr(0), nodeJPtr(0),
00097   nodeIOffset(0), nodeJOffset(0),
00098   cosTheta(0), sinTheta(0), L(0), ul14(0)
00099 {
00100 
00101 }
00102 
00103 
00104 
00105 // destructor:
00106 PDeltaCrdTransf2d::~PDeltaCrdTransf2d() 
00107 {
00108  if (nodeIOffset)
00109   delete [] nodeIOffset;
00110  if (nodeJOffset)
00111   delete [] nodeJOffset;
00112 }
00113 
00114 
00115 int
00116 PDeltaCrdTransf2d::commitState(void)
00117 {
00118    return 0;
00119 }
00120 
00121 
00122 int
00123 PDeltaCrdTransf2d::revertToLastCommit(void)
00124 {
00125    return 0;
00126 }
00127 
00128 
00129 int
00130 PDeltaCrdTransf2d::revertToStart(void)
00131 {
00132    return 0;
00133 }
00134 
00135 
00136 int 
00137 PDeltaCrdTransf2d::initialize(Node *nodeIPointer, Node *nodeJPointer)
00138 {       
00139    int error;
00140 
00141    nodeIPtr = nodeIPointer;
00142    nodeJPtr = nodeJPointer;
00143 
00144    if ((!nodeIPtr) || (!nodeJPtr))
00145    {
00146       cerr << "\nPDeltaCrdTransf2d::initialize";
00147       cerr << "\ninvalid pointers to the element nodes\n";
00148       return -1;
00149    }
00150        
00151    // get element length and orientation
00152    if ((error = this->computeElemtLengthAndOrient()))
00153       return error;
00154       
00155    return 0;
00156 }
00157 
00158 
00159 int
00160 PDeltaCrdTransf2d::update(void)
00161 {
00162  const Vector &nodeIDisp = nodeIPtr->getTrialDisp();
00163  const Vector &nodeJDisp = nodeJPtr->getTrialDisp();
00164 
00165  double ul1;
00166  double ul4;
00167 
00168  if (nodeIOffset == 0) {
00169   ul1 = -sinTheta*nodeIDisp(0) + cosTheta*nodeIDisp(1);
00170   ul4 = -sinTheta*nodeJDisp(0) + cosTheta*nodeJDisp(1);
00171  }
00172  else {
00173   double t12 = sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00174   double t45 = sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00175 
00176   ul1 = -sinTheta*nodeIDisp(0) + cosTheta*nodeIDisp(1) + t12*nodeIDisp(2);
00177   ul4 = -sinTheta*nodeJDisp(0) + cosTheta*nodeJDisp(1) + t45*nodeJDisp(2);
00178  }
00179 
00180  ul14 = ul1-ul4;
00181 
00182  return 0;
00183 }
00184 
00185 
00186 int 
00187 PDeltaCrdTransf2d::computeElemtLengthAndOrient()
00188 {
00189    // element projection
00190    static Vector dx(2);
00191 
00192    const Vector &ndICoords = nodeIPtr->getCrds();
00193    const Vector &ndJCoords = nodeJPtr->getCrds();
00194 
00195    if (nodeIOffset == 0) {
00196     dx(0) = ndJCoords(0) - ndICoords(0);
00197     dx(1) = ndJCoords(1) - ndICoords(1);
00198    }
00199    else {
00200     dx(0) = ndJCoords(0) + nodeJOffset[0] - ndICoords(0) - nodeIOffset[0];
00201     dx(1) = ndJCoords(1) + nodeJOffset[1] - ndICoords(1) - nodeIOffset[1];
00202    }
00203    
00204    // calculate the element length
00205    L = dx.Norm();
00206 
00207    if (L == 0.0) 
00208    {
00209       cerr << "\nPDeltaCrdTransf2d::computeElemtLengthAndOrien: 0 length\n";
00210       return -2;  
00211    }
00212 
00213    // calculate the element local x axis components (direction cossines)
00214    // wrt to the global coordinates 
00215    cosTheta = dx(0)/L;
00216    sinTheta = dx(1)/L;
00217    
00218    return 0;
00219 }
00220 
00221 
00222 
00223 
00224 
00225 double 
00226 PDeltaCrdTransf2d::getInitialLength(void)
00227 {
00228    return L;
00229 }
00230 
00231 
00232 double 
00233 PDeltaCrdTransf2d::getDeformedLength(void)
00234 {
00235    return L;
00236 }
00237 
00238 
00239 const Vector &
00240 PDeltaCrdTransf2d::getBasicTrialDisp (void)
00241 {
00242  // determine global displacements
00243  const Vector &disp1 = nodeIPtr->getTrialDisp();
00244  const Vector &disp2 = nodeJPtr->getTrialDisp();
00245 
00246  static double ug[6];
00247  for (int i = 0; i < 3; i++) {
00248   ug[i]   = disp1(i);
00249   ug[i+3] = disp2(i);
00250  }
00251 
00252  static Vector ub(3);
00253 
00254  double oneOverL = 1.0/L;
00255  double sl = sinTheta*oneOverL;
00256  double cl = cosTheta*oneOverL;
00257 
00258  if (nodeIOffset == 0) {
00259   ub(0) = -cosTheta*ug[0] - sinTheta*ug[1] +
00260    cosTheta*ug[3] + sinTheta*ug[4];
00261 
00262   ub(1) = -sl*ug[0] + cl*ug[1] + ug[2] +
00263    sl*ug[3] - cl*ug[4];
00264 
00265   //ub(2) = -sl*ug[0] + cl*ug[1] +
00266   // sl*ug[3] - cl*ug[4] + ug[5];
00267   ub(2) = ub(1) + ug[5] - ug[2];
00268  }
00269  else {
00270   double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
00271   double t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00272   double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
00273   double t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00274 
00275   ub(0) = -cosTheta*ug[0] - sinTheta*ug[1] - t02*ug[2] +
00276    cosTheta*ug[3] + sinTheta*ug[4] + t35*ug[5];
00277 
00278   ub(1) = -sl*ug[0] + cl*ug[1] + (1.0+oneOverL*t12)*ug[2] +
00279    sl*ug[3] - cl*ug[4] - oneOverL*t45*ug[5];
00280 
00281   //ub(2) = -sl*ug[0] + cl*ug[1] + oneOverL*t12*ug[2] +
00282   // sl*ug[3] - cl*ug[4] + (1.0-oneOverL*t45)*ug[5];
00283   ub(2) = ub(1) + ug[5] - ug[2];
00284  }
00285 
00286  return ub;
00287 }
00288 
00289 
00290 const Vector &
00291 PDeltaCrdTransf2d::getBasicIncrDisp (void)
00292 {
00293  // determine global displacements
00294  const Vector &disp1 = nodeIPtr->getIncrDisp();
00295  const Vector &disp2 = nodeJPtr->getIncrDisp();
00296 
00297  static double dug[6];
00298  for (int i = 0; i < 3; i++) {
00299   dug[i]   = disp1(i);
00300   dug[i+3] = disp2(i);
00301  }
00302 
00303  static Vector dub(3);
00304 
00305  double oneOverL = 1.0/L;
00306  double sl = sinTheta*oneOverL;
00307  double cl = cosTheta*oneOverL;
00308 
00309  if (nodeIOffset == 0) {
00310   dub(0) = -cosTheta*dug[0] - sinTheta*dug[1] +
00311    cosTheta*dug[3] + sinTheta*dug[4];
00312 
00313   dub(1) = -sl*dug[0] + cl*dug[1] + dug[2] +
00314    sl*dug[3] - cl*dug[4];
00315 
00316   //dub(2) = -sl*dug[0] + cl*dug[1] +
00317   // sl*dug[3] - cl*dug[4] + dug[5];
00318   dub(2) = dub(1) + dug[5] - dug[2];
00319  }
00320  else {
00321   double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
00322   double t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00323   double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
00324   double t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00325 
00326   dub(0) = -cosTheta*dug[0] - sinTheta*dug[1] - t02*dug[2] +
00327    cosTheta*dug[3] + sinTheta*dug[4] + t35*dug[5];
00328 
00329   dub(1) = -sl*dug[0] + cl*dug[1] + (1.0+oneOverL*t12)*dug[2] +
00330    sl*dug[3] - cl*dug[4] - oneOverL*t45*dug[5];
00331 
00332   //dub(2) = -sl*dug[0] + cl*dug[1] + oneOverL*t12*dug[2] +
00333   // sl*dug[3] - cl*dug[4] + (1.0-oneOverL*t45)*dug[5];
00334   dub(2) = dub(1) + dug[5] - dug[2];
00335  }
00336 
00337  return dub;
00338 }
00339 
00340 
00341 const Vector &
00342 PDeltaCrdTransf2d::getBasicIncrDeltaDisp(void)
00343 {
00344  // determine global displacements
00345  const Vector &disp1 = nodeIPtr->getIncrDeltaDisp();
00346  const Vector &disp2 = nodeJPtr->getIncrDeltaDisp();
00347 
00348  static double Dug[6];
00349  for (int i = 0; i < 3; i++) {
00350   Dug[i]   = disp1(i);
00351   Dug[i+3] = disp2(i);
00352  }
00353 
00354  static Vector Dub(3);
00355 
00356  double oneOverL = 1.0/L;
00357  double sl = sinTheta*oneOverL;
00358  double cl = cosTheta*oneOverL;
00359 
00360  if (nodeIOffset == 0) {
00361   Dub(0) = -cosTheta*Dug[0] - sinTheta*Dug[1] +
00362    cosTheta*Dug[3] + sinTheta*Dug[4];
00363 
00364   Dub(1) = -sl*Dug[0] + cl*Dug[1] + Dug[2] +
00365    sl*Dug[3] - cl*Dug[4];
00366 
00367   //Dub(2) = -sl*Dug[0] + cl*Dug[1] +
00368   // sl*Dug[3] - cl*Dug[4] + Dug[5];
00369   Dub(2) = Dub(1) + Dug[5] - Dug[2];
00370  }
00371  else {
00372   double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
00373   double t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00374   double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
00375   double t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00376 
00377   Dub(0) = -cosTheta*Dug[0] - sinTheta*Dug[1] - t02*Dug[2] +
00378    cosTheta*Dug[3] + sinTheta*Dug[4] + t35*Dug[5];
00379 
00380   Dub(1) = -sl*Dug[0] + cl*Dug[1] + (1.0+oneOverL*t12)*Dug[2] +
00381    sl*Dug[3] - cl*Dug[4] - oneOverL*t45*Dug[5];
00382 
00383   //Dub(2) = -sl*Dug[0] + cl*Dug[1] + oneOverL*t12*Dug[2] +
00384   // sl*Dug[3] - cl*Dug[4] + (1.0-oneOverL*t45)*Dug[5];
00385   Dub(2) = Dub(1) + Dug[5] - Dug[2];
00386  }
00387 
00388  return Dub;
00389 }
00390 
00391 
00392 const Vector &
00393 PDeltaCrdTransf2d::getGlobalResistingForce(const Vector &pb, const Vector &unifLoad)
00394 {
00395  // transform resisting forces from the basic system to local coordinates
00396  static double pl[6];
00397 
00398  double q0 = pb(0);
00399  double q1 = pb(1);
00400  double q2 = pb(2);
00401 
00402  double oneOverL = 1.0/L;
00403 
00404  pl[0] = -q0;
00405  pl[1] =  oneOverL*(q1+q2);
00406  pl[2] =  q1;
00407  pl[3] =  q0;
00408  //pl[4] = -oneOverL*(q1+q2);
00409  pl[4] = -pl[1];
00410  pl[5] =  q2;
00411 
00412  // add end forces due to uniform distributed
00413  // loads to the system with rigid body modes
00414  pl[0] -= unifLoad(0)*L;
00415  double V = 0.5*unifLoad(1)*L;
00416  pl[1] -= V;
00417  pl[4] -= V;
00418      
00419  // Include leaning column effects (P-Delta)
00420  double NoverL = ul14*q0*oneOverL;             
00421  pl[1] += NoverL;
00422  pl[4] -= NoverL;
00423 
00424  // transform resisting forces  from local to global coordinates
00425  static Vector pg(6);
00426 
00427  pg(0) = cosTheta*pl[0] - sinTheta*pl[1];
00428  pg(1) = sinTheta*pl[0] + cosTheta*pl[1];
00429    
00430  pg(3) = cosTheta*pl[3] - sinTheta*pl[4];
00431  pg(4) = sinTheta*pl[3] + cosTheta*pl[4];
00432  
00433  if (nodeIOffset == 0) {
00434   pg(2) = pl[2];
00435   pg(5) = pl[5];
00436  }
00437  else {
00438   double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
00439   double t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00440   double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
00441   double t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00442 
00443   pg(2) = t02*pl[0] + t12*pl[1] + pl[2];
00444   pg(5) = t35*pl[3] + t45*pl[4] + pl[5];
00445  }
00446 
00447  return pg;
00448 }
00449 
00450 const Matrix &
00451 PDeltaCrdTransf2d::getGlobalStiffMatrix (const Matrix &kb, const Vector &pb)
00452 {
00453  static Matrix kg(6,6);
00454  static double kl[6][6];
00455  static double tmp[6][6];
00456 
00457  double oneOverL = 1.0/L;
00458  double sl = sinTheta*oneOverL;
00459  double cl = cosTheta*oneOverL;
00460 
00461  // Basic stiffness
00462  double kb00, kb01, kb02, kb10, kb11, kb12, kb20, kb21, kb22;
00463  kb00 = kb(0,0);  kb01 = kb(0,1);  kb02 = kb(0,2);
00464  kb10 = kb(1,0);  kb11 = kb(1,1);  kb12 = kb(1,2);
00465  kb20 = kb(2,0);  kb21 = kb(2,1);  kb22 = kb(2,2);
00466 
00467  // Transform basic stiffness to local system
00468  kl[0][0] =  kb00;
00469  kl[1][0] = -oneOverL*(kb10+kb20);
00470  kl[2][0] = -kb10;
00471  kl[3][0] = -kb00;
00472  kl[4][0] = -kl[1][0];
00473  kl[5][0] = -kb20;
00474 
00475  kl[0][1] = -oneOverL*(kb01+kb02);
00476  kl[1][1] =  oneOverL*oneOverL*(kb11+kb12+kb21+kb22);
00477  kl[2][1] =  oneOverL*(kb11+kb12);
00478  kl[3][1] = -kl[0][1];
00479  kl[4][1] = -kl[1][1];
00480  kl[5][1] =  oneOverL*(kb21+kb22);
00481 
00482  kl[0][2] = -kb01;
00483  kl[1][2] =  oneOverL*(kb11+kb21);
00484  kl[2][2] =  kb11;
00485  kl[3][2] =  kb01;
00486  kl[4][2] = -kl[1][2];
00487  kl[5][2] =  kb21;
00488 
00489  kl[0][3] = -kl[0][0];
00490  kl[1][3] = -kl[1][0];
00491  kl[2][3] = -kl[2][0];
00492  kl[3][3] = -kl[3][0];
00493  kl[4][3] = -kl[4][0];
00494  kl[5][3] = -kl[5][0];
00495 
00496  kl[0][4] = -kl[0][1];
00497  kl[1][4] = -kl[1][1];
00498  kl[2][4] = -kl[2][1];
00499  kl[3][4] = -kl[3][1];
00500  kl[4][4] = -kl[4][1];
00501  kl[5][4] = -kl[5][1];
00502 
00503  kl[0][5] = -kb02;
00504  kl[1][5] =  oneOverL*(kb12+kb22);
00505  kl[2][5] =  kb12;
00506  kl[3][5] =  kb02;
00507  kl[4][5] = -kl[1][5];
00508  kl[5][5] =  kb22;
00509 
00510  // Include geometric stiffness effects in local system
00511  double NoverL = pb(0)*oneOverL;
00512  kl[1][1] += NoverL;
00513  kl[4][4] += NoverL;
00514  kl[1][4] -= NoverL;
00515  kl[4][1] -= NoverL;
00516 
00517  double t02 = 0.0;
00518  double t12 = 0.0;
00519  double t35 = 0.0;
00520  double t45 = 0.0;
00521 
00522  if (nodeIOffset) {
00523   t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
00524   t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00525   t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
00526   t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00527  }
00528 
00529  // Now transform from local to global ... compute kl*T
00530  tmp[0][0] = kl[0][0]*cosTheta - kl[0][1]*sinTheta;
00531  tmp[1][0] = kl[1][0]*cosTheta - kl[1][1]*sinTheta;
00532  tmp[2][0] = kl[2][0]*cosTheta - kl[2][1]*sinTheta;
00533  tmp[3][0] = kl[3][0]*cosTheta - kl[3][1]*sinTheta;
00534  tmp[4][0] = kl[4][0]*cosTheta - kl[4][1]*sinTheta;
00535  tmp[5][0] = kl[5][0]*cosTheta - kl[5][1]*sinTheta;
00536 
00537  tmp[0][1] = kl[0][0]*sinTheta + kl[0][1]*cosTheta;
00538  tmp[1][1] = kl[1][0]*sinTheta + kl[1][1]*cosTheta;
00539  tmp[2][1] = kl[2][0]*sinTheta + kl[2][1]*cosTheta;
00540  tmp[3][1] = kl[3][0]*sinTheta + kl[3][1]*cosTheta;
00541  tmp[4][1] = kl[4][0]*sinTheta + kl[4][1]*cosTheta;
00542  tmp[5][1] = kl[5][0]*sinTheta + kl[5][1]*cosTheta;
00543 
00544  if (nodeIOffset) {
00545   tmp[0][2] = kl[0][0]*t02 + kl[0][1]*t12 + kl[0][2];
00546   tmp[1][2] = kl[1][0]*t02 + kl[1][1]*t12 + kl[1][2];
00547   tmp[2][2] = kl[2][0]*t02 + kl[2][1]*t12 + kl[2][2];
00548   tmp[3][2] = kl[3][0]*t02 + kl[3][1]*t12 + kl[3][2];
00549   tmp[4][2] = kl[4][0]*t02 + kl[4][1]*t12 + kl[4][2];
00550   tmp[5][2] = kl[5][0]*t02 + kl[5][1]*t12 + kl[5][2];
00551  }
00552  else {
00553   tmp[0][2] = kl[0][2];
00554   tmp[1][2] = kl[1][2];
00555   tmp[2][2] = kl[2][2];
00556   tmp[3][2] = kl[3][2];
00557   tmp[4][2] = kl[4][2];
00558   tmp[5][2] = kl[5][2];
00559  }
00560  
00561  tmp[0][3] = kl[0][3]*cosTheta - kl[0][4]*sinTheta;
00562  tmp[1][3] = kl[1][3]*cosTheta - kl[1][4]*sinTheta;
00563  tmp[2][3] = kl[2][3]*cosTheta - kl[2][4]*sinTheta;
00564  tmp[3][3] = kl[3][3]*cosTheta - kl[3][4]*sinTheta;
00565  tmp[4][3] = kl[4][3]*cosTheta - kl[4][4]*sinTheta;
00566  tmp[5][3] = kl[5][3]*cosTheta - kl[5][4]*sinTheta;
00567 
00568  tmp[0][4] = kl[0][3]*sinTheta + kl[0][4]*cosTheta;
00569  tmp[1][4] = kl[1][3]*sinTheta + kl[1][4]*cosTheta;
00570  tmp[2][4] = kl[2][3]*sinTheta + kl[2][4]*cosTheta;
00571  tmp[3][4] = kl[3][3]*sinTheta + kl[3][4]*cosTheta;
00572  tmp[4][4] = kl[4][3]*sinTheta + kl[4][4]*cosTheta;
00573  tmp[5][4] = kl[5][3]*sinTheta + kl[5][4]*cosTheta;
00574 
00575  if (nodeJOffset) {
00576   tmp[0][5] = kl[0][3]*t35 + kl[0][4]*t45 + kl[0][5];
00577   tmp[1][5] = kl[1][3]*t35 + kl[1][4]*t45 + kl[1][5];
00578   tmp[2][5] = kl[2][3]*t35 + kl[2][4]*t45 + kl[2][5];
00579   tmp[3][5] = kl[3][3]*t35 + kl[3][4]*t45 + kl[3][5];
00580   tmp[4][5] = kl[4][3]*t35 + kl[4][4]*t45 + kl[4][5];
00581   tmp[5][5] = kl[5][3]*t35 + kl[5][4]*t45 + kl[5][5];
00582  }
00583  else {
00584   tmp[0][5] = kl[0][5];
00585   tmp[1][5] = kl[1][5];
00586   tmp[2][5] = kl[2][5];
00587   tmp[3][5] = kl[3][5];
00588   tmp[4][5] = kl[4][5];
00589   tmp[5][5] = kl[5][5];
00590  }
00591 
00592  // Now compute T'*(kl*T)
00593  kg(0,0) = cosTheta*tmp[0][0] - sinTheta*tmp[1][0];
00594  kg(0,1) = cosTheta*tmp[0][1] - sinTheta*tmp[1][1];
00595  kg(0,2) = cosTheta*tmp[0][2] - sinTheta*tmp[1][2];
00596  kg(0,3) = cosTheta*tmp[0][3] - sinTheta*tmp[1][3];
00597  kg(0,4) = cosTheta*tmp[0][4] - sinTheta*tmp[1][4];
00598  kg(0,5) = cosTheta*tmp[0][5] - sinTheta*tmp[1][5];
00599 
00600  kg(1,0) = sinTheta*tmp[0][0] + cosTheta*tmp[1][0];
00601  kg(1,1) = sinTheta*tmp[0][1] + cosTheta*tmp[1][1];
00602  kg(1,2) = sinTheta*tmp[0][2] + cosTheta*tmp[1][2];
00603  kg(1,3) = sinTheta*tmp[0][3] + cosTheta*tmp[1][3];
00604  kg(1,4) = sinTheta*tmp[0][4] + cosTheta*tmp[1][4];
00605  kg(1,5) = sinTheta*tmp[0][5] + cosTheta*tmp[1][5];
00606 
00607  if (nodeIOffset) {
00608   kg(2,0) = t02*tmp[0][0] + t12*tmp[1][0] + tmp[2][0];
00609   kg(2,1) = t02*tmp[0][1] + t12*tmp[1][1] + tmp[2][1];
00610   kg(2,2) = t02*tmp[0][2] + t12*tmp[1][2] + tmp[2][2];
00611   kg(2,3) = t02*tmp[0][3] + t12*tmp[1][3] + tmp[2][3];
00612   kg(2,4) = t02*tmp[0][4] + t12*tmp[1][4] + tmp[2][4];
00613   kg(2,5) = t02*tmp[0][5] + t12*tmp[1][5] + tmp[2][5];
00614  }
00615  else {
00616   kg(2,0) = tmp[2][0];
00617   kg(2,1) = tmp[2][1];
00618   kg(2,2) = tmp[2][2];
00619   kg(2,3) = tmp[2][3];
00620   kg(2,4) = tmp[2][4];
00621   kg(2,5) = tmp[2][5];
00622  }
00623 
00624  kg(3,0) = cosTheta*tmp[3][0] - sinTheta*tmp[4][0];
00625  kg(3,1) = cosTheta*tmp[3][1] - sinTheta*tmp[4][1];
00626  kg(3,2) = cosTheta*tmp[3][2] - sinTheta*tmp[4][2];
00627  kg(3,3) = cosTheta*tmp[3][3] - sinTheta*tmp[4][3];
00628  kg(3,4) = cosTheta*tmp[3][4] - sinTheta*tmp[4][4];
00629  kg(3,5) = cosTheta*tmp[3][5] - sinTheta*tmp[4][5];
00630 
00631  kg(4,0) = sinTheta*tmp[3][0] + cosTheta*tmp[4][0];
00632  kg(4,1) = sinTheta*tmp[3][1] + cosTheta*tmp[4][1];
00633  kg(4,2) = sinTheta*tmp[3][2] + cosTheta*tmp[4][2];
00634  kg(4,3) = sinTheta*tmp[3][3] + cosTheta*tmp[4][3];
00635  kg(4,4) = sinTheta*tmp[3][4] + cosTheta*tmp[4][4];
00636  kg(4,5) = sinTheta*tmp[3][5] + cosTheta*tmp[4][5];
00637  
00638  if (nodeJOffset) {
00639   kg(5,0) = t35*tmp[3][0] + t45*tmp[4][0] + tmp[5][0];
00640   kg(5,1) = t35*tmp[3][1] + t45*tmp[4][1] + tmp[5][1];
00641   kg(5,2) = t35*tmp[3][2] + t45*tmp[4][2] + tmp[5][2];
00642   kg(5,3) = t35*tmp[3][3] + t45*tmp[4][3] + tmp[5][3];
00643   kg(5,4) = t35*tmp[3][4] + t45*tmp[4][4] + tmp[5][4];
00644   kg(5,5) = t35*tmp[3][5] + t45*tmp[4][5] + tmp[5][5];
00645  }
00646  else {
00647   kg(5,0) = tmp[5][0];
00648   kg(5,1) = tmp[5][1];
00649   kg(5,2) = tmp[5][2];
00650   kg(5,3) = tmp[5][3];
00651   kg(5,4) = tmp[5][4];
00652   kg(5,5) = tmp[5][5];
00653  }
00654 
00655  return kg;
00656 }
00657   
00658 
00659 
00660 
00661 CrdTransf2d *
00662 PDeltaCrdTransf2d::getCopy(void)
00663 {
00664   // create a new instance of PDeltaCrdTransf2d 
00665 
00666   PDeltaCrdTransf2d *theCopy;
00667 
00668   if (nodeIOffset) {
00669    Vector offsetI(nodeIOffset, 2);
00670    Vector offsetJ(nodeJOffset, 2);
00671 
00672    theCopy = new PDeltaCrdTransf2d(this->getTag(), offsetI, offsetJ);
00673   }
00674   else
00675    theCopy = new PDeltaCrdTransf2d(this->getTag());
00676 
00677   theCopy->nodeIPtr = nodeIPtr;
00678   theCopy->nodeJPtr = nodeJPtr;
00679   theCopy->cosTheta = cosTheta;
00680   theCopy->sinTheta = sinTheta;
00681   theCopy->L = L;
00682   theCopy->ul14 = ul14;
00683   
00684   return theCopy;
00685 }
00686 
00687 
00688 int 
00689 PDeltaCrdTransf2d::sendSelf(int cTag, Channel &theChannel)
00690 {
00691  int res = 0;
00692 
00693  static Vector data(9);
00694 
00695  data(0) = this->getTag();
00696  data(6) = L;
00697  data(7) = cosTheta;
00698  data(8) = sinTheta;
00699 
00700  res += theChannel.sendVector(this->getDbTag(), cTag, data);
00701  if (res < 0) {
00702   g3ErrorHandler->warning("%s - failed to send Vector",
00703    "PDeltaCrdTransf2d::sendSelf");
00704   return res;
00705  }
00706 
00707     return res;
00708 }
00709 
00710     
00711 
00712 int 
00713 PDeltaCrdTransf2d::recvSelf(int cTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00714 {
00715  int res = 0;
00716 
00717  static Vector data(9);
00718 
00719  res += theChannel.recvVector(this->getDbTag(), cTag, data);
00720  if (res < 0) {
00721   g3ErrorHandler->warning("%s - failed to receive Vector",
00722    "PDeltaCrdTransf2d::recvSelf");
00723   return res;
00724  }
00725 
00726  this->setTag((int)data(0));
00727  L = data(6);
00728  cosTheta = data(7);
00729  sinTheta = data(8);
00730 
00731     return res;
00732 }
00733   
00734 
00735 const Vector &
00736 PDeltaCrdTransf2d::getPointGlobalCoordFromLocal(const Vector &xl)
00737 {
00738    static Vector xg(2);
00739 
00740    const Vector &nodeICoords = nodeIPtr->getCrds();
00741    xg(0) = nodeICoords(0);
00742    xg(1) = nodeICoords(1);
00743 
00744    if (nodeIOffset) {
00745     xg(0) += nodeIOffset[0];
00746     xg(1) += nodeIOffset[1];
00747    }
00748 
00749    // xg = xg + Rlj'*xl
00750    xg(0) += cosTheta*xl(0) - sinTheta*xl(1);
00751    xg(1) += sinTheta*xl(0) + cosTheta*xl(1);
00752      
00753    return xg;  
00754 }
00755 
00756     
00757 const Vector &
00758 PDeltaCrdTransf2d::getPointGlobalDisplFromBasic (double xi, const Vector &uxb)
00759 {
00760    // determine global displacements
00761    const Vector &disp1 = nodeIPtr->getTrialDisp();
00762    const Vector &disp2 = nodeJPtr->getTrialDisp();
00763 
00764    static Vector ug(6);
00765    for (int i = 0; i < 3; i++)
00766    {
00767       ug(i)   = disp1(i);
00768       ug(i+3) = disp2(i);
00769    }
00770 
00771    // transform global end displacements to local coordinates
00772    static Vector ul(6);      // total displacements
00773 
00774  ul(0) =  cosTheta*ug(0) + sinTheta*ug(1);
00775  ul(1) = -sinTheta*ug(0) + cosTheta*ug(1);
00776  ul(2) =  ug(2);
00777  ul(3) =  cosTheta*ug(3) + sinTheta*ug(4);
00778  ul(4) = -sinTheta*ug(3) + cosTheta*ug(4);
00779  ul(5) =  ug(5);
00780 
00781     if (nodeIOffset != 0) {
00782   double t02 = -cosTheta*nodeIOffset[1] + sinTheta*nodeIOffset[0];
00783   double t12 =  sinTheta*nodeIOffset[1] + cosTheta*nodeIOffset[0];
00784   double t35 = -cosTheta*nodeJOffset[1] + sinTheta*nodeJOffset[0];
00785   double t45 =  sinTheta*nodeJOffset[1] + cosTheta*nodeJOffset[0];
00786 
00787   ul(0) += t02*ug(2);
00788   ul(1) += t12*ug(2);
00789   ul(3) += t35*ug(5);
00790   ul(4) += t45*ug(5);
00791  }
00792    
00793    // compute displacements at point xi, in local coordinates
00794    static Vector uxl(2),  uxg(2);
00795 
00796    uxl(0) = uxb(0) +        ul(0);
00797    uxl(1) = uxb(1) + (1-xi)*ul(1) + xi*ul(4);
00798 
00799    // rotate displacements to global coordinates
00800    // uxg = RljT*uxl
00801    uxg(0) = cosTheta*uxl(0) - sinTheta*uxl(1);
00802    uxg(1) = sinTheta*uxl(0) + cosTheta*uxl(1);
00803      
00804    return uxg;  
00805 }
00806 
00807 
00808 
00809 
00810 void
00811 PDeltaCrdTransf2d::Print(ostream &s, int flag)
00812 {
00813    s << "\nCrdTransf: " << this->getTag() << " Type: PDeltaCrdTransf2d";
00814    s << "\tnodeI Offset: " << nodeIOffset;
00815    s << "\tnodeJ Offset: " << nodeJOffset;
00816 }
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
Copyright Contact Us