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

BeamWithHinges2d.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.5 $
00022 // $Date: 2001/01/31 10:40:20 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/element/beamWithHinges/BeamWithHinges2d.cpp,v $
00024                                                                         
00025                                                                         
00027 // File:  ~/Src/element/beamWithHinges/BeamWithHinges2d.cpp
00028 //
00029 // Written by Matthew Peavy
00030 //
00031 // Written:  Feb 13, 2000
00032 // Debugged: Feb 15, 2000
00033 // Revised:        , 200x
00034 //
00035 //
00036 // Purpose:  This cpp file contains the definitions
00037 // for BeamWithHinges.  The element uses hinges (passed as
00038 // object pointers) at the element ends.  The middle section
00039 // is analyzed elastically, while the hinge ends return
00040 // a section flexibility at their middle points.  The element
00041 // calculates a frame (6x6) stiffness matrix from this info.
00042 
00043 #include <BeamWithHinges2d.h>
00044 #include <Element.h>
00045 #include <Domain.h>
00046 #include <Channel.h>
00047 #include <FEM_ObjectBroker.h>
00048 #include <Matrix.h>
00049 #include <Vector.h>      
00050 #include <Node.h>
00051 #include <MatrixUtil.h>      //For 3x3 matrix inversion
00052 #include <math.h>       //For sqrt function
00053 #include <stdlib.h>      
00054 #include <iostream.h>      //Not needed
00055 #include <string.h>
00056 #include <stdio.h>
00057 
00058 #include <SectionForceDeformation.h>
00059 #include <CrdTransf2d.h>
00060 
00061 #include <Information.h>
00062 #include <ElementResponse.h>
00063 #include <Renderer.h>
00064 
00065 BeamWithHinges2d::BeamWithHinges2d(void)
00066  :Element(0, ELE_TAG_BeamWithHinges2d),
00067  E(0), I(0), A(0), L(0),
00068  G(0), alpha(0),
00069  sectionI(0), sectionJ(0),
00070  connectedExternalNodes(2),
00071  node1Ptr(0), node2Ptr(0),
00072  hingeIlen(0), hingeJlen(0),
00073  K(6,6), m(6,6), d(6,6), fElastic(3,3), vElastic(3,2),
00074  UePrev(6), P(6), Pinert(6), kb(3,3), q(3),
00075  load(6), prevDistrLoad(2), 
00076  distrLoadCommit(2), UeCommit(6), 
00077  kbCommit(3,3), qCommit(3), massDens(0),
00078  shearLength(0), shearIkey(-1), shearJkey(-1),
00079  theCoordTransf(0), maxIter(1), tolerance(1.0e-10), initialFlag(false)
00080 {
00081 
00082 }
00083 
00084 BeamWithHinges2d::BeamWithHinges2d(int tag, int nodeI, int nodeJ,
00085       double E_in, double I_in, double A_in,
00086       double G_in, double alpha_in,
00087       SectionForceDeformation &sectionRefI, double I_length,
00088       SectionForceDeformation &sectionRefJ, double J_length,
00089       CrdTransf2d &coordTransf, double shearL,
00090       double massDensityPerUnitLength, int max, double tol)
00091  :Element(tag, ELE_TAG_BeamWithHinges2d),
00092  E(E_in), I(I_in), A(A_in),
00093  G(G_in), alpha(alpha_in),
00094  sectionI(0), sectionJ(0),
00095  connectedExternalNodes(2),
00096  node1Ptr(0), node2Ptr(0),
00097  hingeIlen(I_length), hingeJlen(J_length),
00098  K(6,6), m(6,6), d(6,6), fElastic(3,3), vElastic(3,2),
00099  UePrev(6), P(6), Pinert(6), kb(3,3), q(3),
00100  load(6), prevDistrLoad(2), 
00101  distrLoadCommit(2), UeCommit(6), 
00102  kbCommit(3,3), qCommit(3),
00103  massDens(massDensityPerUnitLength),
00104  shearLength(shearL), shearIkey(-1), shearJkey(-1),
00105  theCoordTransf(0), maxIter(max), tolerance(tol), initialFlag(false)
00106 {
00107  if (E <= 0.0)  {
00108   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Paramater E is zero or negative.";
00109   //exit(-1);
00110  }
00111  
00112  if (I <= 0.0)  {
00113   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter I is zero or negative.";
00114   //exit(-1);
00115  }
00116  
00117  if (A <= 0.0)  {
00118   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter A is zero or negative.";
00119   //exit(-1); 
00120  }
00121 
00122  if (G <= 0.0)  {
00123   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter G is zero or negative.";
00124   //exit(-1); 
00125  }
00126 
00127  if (alpha < 0.0)  {
00128   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter alpha is negative.";
00129   //exit(-1); 
00130  }
00131 
00132  // Get copies of sections
00133  sectionI = sectionRefI.getCopy();
00134  
00135  if (sectionI == 0)
00136   g3ErrorHandler->fatal("%s -- failed to get copy of section I",
00137    "BeamWithHinges2d::BeamWithHinges2d");
00138 
00139  sectionJ = sectionRefJ.getCopy();
00140 
00141  if (sectionJ == 0)
00142   g3ErrorHandler->fatal("%s -- failed to get copy of section J",
00143    "BeamWithHinges2d::BeamWithHinges2d");
00144 
00145  theCoordTransf = coordTransf.getCopy();
00146  
00147  if (theCoordTransf == 0)
00148      g3ErrorHandler->fatal("%s -- failed to get copy of coordinate transformation",
00149    "BeamWithHinges2d::BeamWithHinges2d");
00150  
00151  connectedExternalNodes(0) = nodeI;
00152  connectedExternalNodes(1) = nodeJ;
00153 }
00154 
00155 BeamWithHinges2d::BeamWithHinges2d(int tag, int nodeI, int nodeJ,
00156        double E_in, double I_in, double A_in,
00157        double G_in, double alpha_in,
00158        SectionForceDeformation &sectionRefI, double I_length,
00159        SectionForceDeformation &sectionRefJ, double J_length,
00160        CrdTransf2d &coordTransf, const Vector &distrLoad,
00161        double shearL, double massDensityPerUnitLength,
00162        int max, double tol)
00163  :Element(tag, ELE_TAG_BeamWithHinges2d),
00164  E(E_in), I(I_in), A(A_in),
00165  G(G_in), alpha(alpha_in),
00166  sectionI(0), sectionJ(0),
00167  connectedExternalNodes(2),
00168  node1Ptr(0), node2Ptr(0),
00169  hingeIlen(I_length), hingeJlen(J_length),
00170  K(6,6), m(6,6), d(6,6), fElastic(3,3), vElastic(3,2),
00171  UePrev(6), P(6), Pinert(6), kb(3,3), q(3),
00172  load(6), prevDistrLoad(2), 
00173  distrLoadCommit(2), UeCommit(6), 
00174  kbCommit(3,3), qCommit(3),
00175  massDens(massDensityPerUnitLength),
00176  shearLength(shearL), shearIkey(-1), shearJkey(-1),
00177  theCoordTransf(0), maxIter(max), tolerance(tol), initialFlag(false)
00178 {
00179  if (E <= 0.0)  {
00180   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Paramater E is zero or negative.";
00181   //exit(-1);
00182  }
00183  
00184  if (I <= 0.0)  {
00185   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter I is zero or negative.";
00186   //exit(-1);
00187  }
00188  
00189  if (A <= 0.0)  {
00190   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter A is zero or negative.";
00191   //exit(-1); 
00192  }
00193 
00194  if (G <= 0.0)  {
00195   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter G is zero or negative.";
00196   //exit(-1); 
00197  }
00198 
00199  if (alpha < 0.0)  {
00200   cerr << "FATAL - BeamWithHinges2d::BeamWithHinges2d() - Parameter alpha is negative.";
00201   //exit(-1); 
00202  }
00203 
00204  // Get copies of sections
00205  sectionI = sectionRefI.getCopy();
00206  
00207  if (sectionI == 0)
00208   g3ErrorHandler->fatal("%s -- failed to get copy of section I",
00209    "BeamWithHinges2d::BeamWithHinges2d");
00210 
00211  sectionJ = sectionRefJ.getCopy();
00212 
00213  if (sectionJ == 0)
00214   g3ErrorHandler->fatal("%s -- failed to get copy of section J",
00215    "BeamWithHinges2d::BeamWithHinges2d");
00216 
00217  theCoordTransf = coordTransf.getCopy();
00218  
00219  if (theCoordTransf == 0)
00220      g3ErrorHandler->fatal("%s -- failed to get copy of coordinate transformation",
00221    "BeamWithHinges2d::BeamWithHinges2d");
00222  
00223  connectedExternalNodes(0) = nodeI;     //node tags
00224  connectedExternalNodes(1) = nodeJ;
00225 }
00226 
00227 BeamWithHinges2d::~BeamWithHinges2d(void)
00228 {
00229  //Only hinges must be destroyed
00230  if (sectionI)
00231   delete sectionI;
00232 
00233  if (sectionJ)
00234   delete sectionJ;
00235  
00236  if (theCoordTransf)
00237      delete theCoordTransf;
00238 }
00239 
00240 int 
00241 BeamWithHinges2d::getNumExternalNodes(void) const
00242 {
00243  return 2;
00244 }
00245 
00246 const ID &
00247 BeamWithHinges2d::getExternalNodes(void)
00248 {
00249  return connectedExternalNodes;
00250 }
00251 
00252 int 
00253 BeamWithHinges2d::getNumDOF(void)
00254 {
00255  return 6;
00256 }
00257 
00258 void
00259 BeamWithHinges2d::setDomain (Domain *theDomain)
00260 {
00261  //This function may be called after a beam is constructed, so
00262  //geometry may change.  Therefore calculate all beam geometry here.
00263 
00264  if(theDomain == 0) {
00265   node1Ptr = 0;
00266   node2Ptr = 0;
00267   return;
00268  }
00269  
00270  // set the node pointers and verify them
00271  this->setNodePtrs(theDomain);
00272 
00273  // call the DomainComponent version of the function
00274  this->DomainComponent::setDomain(theDomain);
00275 
00276  if (theCoordTransf->initialize(node1Ptr, node2Ptr) != 0) {
00277      cerr << "BeamWithHinges2d::setDomain(): Error initializing coordinate transformation";  
00278      exit(-1);
00279  }
00280  
00281  // get element length
00282  L = theCoordTransf->getInitialLength();
00283  
00284  if (L == 0.0) {
00285      cerr << "BeamWithHinges2d::setDomain(): Zero element length:" << this->getTag();  
00286      exit(-1);
00287  }
00288  
00289  UePrev.Zero();     //clear the previous nodal displacements
00290  initialFlag = false;   //used in getTangentStiff to force initialization
00291 
00292  // Set up section interpolation and hinge lengths
00293  this->setHinges();
00294 
00295  // Calculate the elastic contribution to the element flexibility
00296  this->setElasticFlex();
00297 
00298  // Set the element lumped mass matrix
00299  this->setMass();
00300 }
00301 
00302 int
00303 BeamWithHinges2d::commitState(void)
00304 {
00305  int err = 0;
00306  
00307  err += sectionI->commitState();
00308  err += sectionJ->commitState();
00309 
00310  err += theCoordTransf->commitState();
00311  
00312  distrLoadCommit = prevDistrLoad;
00313  UeCommit = UePrev;
00314  kbCommit = kb;
00315  qCommit = q;
00316 
00317  initialFlag = false;
00318  
00319  return err;
00320 }
00321 
00322 int
00323 BeamWithHinges2d::revertToLastCommit(void)
00324 {
00325  int err = 0;
00326 
00327  // Revert the sections and then get their last commited
00328  // deformations, stress resultants, and flexibilities
00329  err += sectionI->revertToLastCommit();
00330  e1 = sectionI->getSectionDeformation();
00331  sr1 = sectionI->getStressResultant();
00332  fs1 = sectionI->getSectionFlexibility();
00333 
00334  err += sectionJ->revertToLastCommit();
00335  e3 = sectionJ->getSectionDeformation();
00336  sr3 = sectionJ->getStressResultant();
00337  fs3 = sectionJ->getSectionFlexibility();
00338 
00339  // Commit the coordinate transformation
00340  err += theCoordTransf->revertToLastCommit();
00341 
00342  prevDistrLoad = distrLoadCommit;
00343  UePrev = UeCommit;
00344  kb = kbCommit;
00345  q = qCommit;
00346 
00347  initialFlag = false;
00348 
00349  return err;
00350 }
00351 
00352 int
00353 BeamWithHinges2d::revertToStart(void)
00354 {
00355     int err = 0;
00356     
00357     err += sectionI->revertToStart();
00358     err += sectionJ->revertToStart();    
00359     
00360     err += theCoordTransf->revertToStart();
00361     
00362     fs1.Zero();
00363     fs3.Zero();    
00364     
00365     e1.Zero();
00366     e3.Zero(); 
00367 
00368  sr1.Zero();
00369  sr3.Zero();
00370     
00371     prevDistrLoad.Zero();
00372     UePrev.Zero();
00373     kb.Zero();
00374     q.Zero();
00375 
00376  return err;
00377 }
00378 
00379 const Matrix &
00380 BeamWithHinges2d::getTangentStiff(void)
00381 {
00382  // Update element state
00383  this->setStiffMatrix();
00384  return K;
00385 }
00386 
00387 const Matrix &
00388 BeamWithHinges2d::getSecantStiff(void)
00389 {
00390  return this->getTangentStiff();
00391 }
00392 
00393 const Matrix &
00394 BeamWithHinges2d::getDamp(void)
00395 {
00396  return d;   //zero matrix
00397 }
00398 
00399 const Matrix &
00400 BeamWithHinges2d::getMass(void)
00401 {
00402  // Computed in setDomain()
00403  return m;
00404 }
00405 
00406 void 
00407 BeamWithHinges2d::zeroLoad(void)
00408 {
00409  load.Zero();
00410 }
00411 
00412 int
00413 BeamWithHinges2d::addLoad(const Vector &moreLoad)
00414 {
00415  if(moreLoad.Size() != 6) {
00416   cerr << "BeamWithHinges2d::addLoad - Vector not of correct size.\n";
00417   return -1;
00418  }
00419 
00420  //load += moreLoad;
00421  load.addVector(1.0, moreLoad, 1.0);
00422  
00423  return 0;
00424 }
00425 
00426 int
00427 BeamWithHinges2d::addInertiaLoadToUnbalance(const Vector &accel)
00428 {
00429  if (massDens == 0.0)
00430   return 0;
00431 
00432  static Vector ag(6);
00433 
00434  const Vector &Raccel1 = node1Ptr->getRV(accel);
00435  const Vector &Raccel2 = node2Ptr->getRV(accel);
00436 
00437  int i,j;
00438  for (i = 0, j = 3; i < 2; i++, j++) {
00439   load(i) += m(i,i) * Raccel1(i);
00440   load(j) += m(j,j) * Raccel2(i); // Yes, this should be 'i'
00441  }
00442  
00443  return 0;
00444 }
00445 
00446 const Vector &
00447 BeamWithHinges2d::getResistingForce(void)
00448 {
00449  this->setStiffMatrix();
00450 
00451  P.addVector(1.0, load, -1.0);
00452 
00453  return P;
00454 }
00455 
00456 const Vector &
00457 BeamWithHinges2d::getResistingForceIncInertia(void)
00458 {
00459  if (massDens == 0.0)
00460   return this->getResistingForce();
00461 
00462  static Vector ag(6);
00463 
00464  this->getGlobalAccels(ag);
00465 
00466  Pinert = this->getResistingForce();
00467 
00468  int i,j; 
00469  for (i = 0, j = 3; i < 2; i++, j++) {
00470   Pinert(i) += m(i,i) * ag(i);
00471   Pinert(j) += m(j,j) * ag(j);
00472  }
00473 
00474  return Pinert;
00475 }
00476 
00477 int
00478 BeamWithHinges2d::sendSelf(int commitTag, Channel &theChannel)
00479 {
00480  int res = 0;
00481 
00482  int elemDbTag = this->getDbTag();
00483 
00484  static ID idData(13);
00485  
00486  int orderI = sectionI->getOrder();
00487  int orderJ = sectionJ->getOrder();
00488 
00489  idData(0) = this->getTag();
00490  idData(1) = sectionI->getClassTag();
00491  idData(2) = sectionJ->getClassTag();
00492  idData(5) = theCoordTransf->getClassTag();
00493  idData(7) = orderI;
00494  idData(8) = orderJ;
00495  idData(9) = maxIter;
00496  idData(10) = (initialFlag) ? 1 : 0;
00497  idData(11) = connectedExternalNodes(0);
00498  idData(12) = connectedExternalNodes(1);
00499 
00500  int sectDbTag;
00501 
00502  sectDbTag = sectionI->getDbTag();
00503     if (sectDbTag == 0) {
00504   sectDbTag = theChannel.getDbTag();
00505   sectionI->setDbTag(sectDbTag);
00506     }
00507     idData(3) = sectDbTag;
00508 
00509  sectDbTag = sectionJ->getDbTag();
00510     if (sectDbTag == 0) {
00511   sectDbTag = theChannel.getDbTag();
00512   sectionJ->setDbTag(sectDbTag);
00513     }
00514     idData(4) = sectDbTag;
00515 
00516  sectDbTag = theCoordTransf->getDbTag();
00517     if (sectDbTag == 0) {
00518   sectDbTag = theChannel.getDbTag();
00519   theCoordTransf->setDbTag(sectDbTag);
00520     }
00521     idData(6) = sectDbTag;
00522 
00523  // Send the data ID
00524  res += theChannel.sendID(elemDbTag, commitTag, idData);
00525  if (res < 0) {
00526   g3ErrorHandler->warning("%s -- failed to send data ID",
00527    "BeamWithHinges2d::sendSelf");
00528   return res;
00529  }
00530 
00531  // Ask the sectionI to send itself
00532  res += sectionI->sendSelf(commitTag, theChannel);
00533  if (res < 0) {
00534   g3ErrorHandler->warning("%s -- failed to send section I",
00535    "BeamWithHinges2d::sendSelf");
00536   return res;
00537  }
00538 
00539  // Ask the sectionJ to send itself
00540  res += sectionJ->sendSelf(commitTag, theChannel);
00541  if (res < 0) {
00542   g3ErrorHandler->warning("%s -- failed to send section J",
00543    "BeamWithHinges2d::sendSelf");
00544   return res;
00545  }
00546 
00547  // data, kbcommit, qcommit, Uecommit, distrLoadcommit
00548  static Vector data(11 + 3*3 + 3 + 6 + 2);
00549  
00550  data(0) = L;
00551  data(1) = E;  
00552  data(2) = A;
00553  data(3) = I;  
00554  data(4) = G;
00555  data(5) = alpha;
00556  data(6) = massDens;
00557  data(7) = hingeIlen/L;  // convert back to ratios
00558  data(8) = hingeJlen/L;
00559  data(9) = tolerance;
00560  data(10) = shearLength/L;
00561 
00562  // Jam committed history variables into the data vector
00563  int i,j;
00564  int loc = 11;
00565  for (i = 0; i < 3; i++)
00566   for (j = 0; j < 3; j++)
00567    data(loc++) = kbCommit(i,j);
00568 
00569  for (i = 0; i < 3; i++)
00570   data(loc++) = qCommit(i);
00571 
00572  for (i = 0; i < 6; i++)
00573   data(loc++) = UeCommit(i);
00574 
00575  for (i = 0; i < 2; i++)
00576   data(loc++) = distrLoadCommit(i);
00577 
00578  // Send the data vector
00579  res += theChannel.sendVector(elemDbTag, commitTag, data);
00580  if (res < 0) {
00581   g3ErrorHandler->warning("%s -- failed to send tags ID",
00582    "BeamWithHinges2d::sendSelf");
00583   return res;
00584  }
00585 
00586  // Ask the coordinate transformation to send itself
00587  res += theCoordTransf->sendSelf(commitTag, theChannel);
00588  if (res < 0) {
00589   g3ErrorHandler->warning("%s -- failed to send coordinate transformation",
00590    "BeamWithHinges2d::sendSelf");
00591   return res;
00592  }
00593 
00594  return res;
00595 }
00596 
00597 int 
00598 BeamWithHinges2d::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00599 {
00600  int res = 0;
00601 
00602  int elemDbTag = this->getDbTag();
00603 
00604  static ID idData(13);
00605 
00606  // Receive the ID data
00607  res += theChannel.recvID(elemDbTag, commitTag, idData);
00608  if (res < 0) {
00609   g3ErrorHandler->warning("%s -- failed to received data ID",
00610    "BeamWithHinges2d::recvSelf");
00611   return res;
00612  }
00613 
00614  this->setTag(idData(0));
00615  maxIter = idData(9);
00616  initialFlag = (idData(10) == 1) ? true : false;
00617  connectedExternalNodes(0) = idData(11);
00618  connectedExternalNodes(1) = idData(12);
00619 
00620  int secTag;
00621 
00622  // Receive section I
00623  secTag = idData(1);
00624 
00625  if (sectionI == 0)
00626   sectionI = theBroker.getNewSection(secTag);
00627 
00628  // Check that the section is of the right type; if not, delete
00629  // the current one and get a new one of the right type
00630  else if (sectionI->getClassTag() != secTag) {
00631   delete sectionI;
00632   sectionI = theBroker.getNewSection(secTag);
00633  }
00634 
00635  if (sectionI == 0) {
00636   g3ErrorHandler->warning("%s -- could not get a Section",
00637    "BeamWithHinges2d::recvSelf");
00638   return -1;
00639  }
00640 
00641  // Now, receive the section
00642  sectionI->setDbTag(idData(3));
00643  res += sectionI->recvSelf(commitTag, theChannel, theBroker);
00644  if (res < 0) {
00645   g3ErrorHandler->warning("%s -- could not receive Section I",
00646    "BeamWithHinges2d::recvSelf");
00647   return res;
00648  }
00649 
00650  // Receive section J
00651  secTag = idData(2);
00652 
00653  if (sectionJ == 0)
00654   sectionJ = theBroker.getNewSection(secTag);
00655 
00656  // Check that the section is of the right type; if not, delete
00657  // the current one and get a new one of the right type
00658  else if (sectionJ->getClassTag() != secTag) {
00659   delete sectionJ;
00660   sectionJ = theBroker.getNewSection(secTag);
00661  }
00662 
00663  if (sectionJ == 0) {
00664   g3ErrorHandler->warning("%s -- could not get a Section",
00665    "BeamWithHinges2d::recvSelf");
00666   return -1;
00667  }
00668 
00669  // Now, receive the section
00670  sectionJ->setDbTag(idData(4));
00671  res += sectionJ->recvSelf(commitTag, theChannel, theBroker);
00672  if (res < 0) {
00673   g3ErrorHandler->warning("%s -- could not receive Section J",
00674    "BeamWithHinges2d::recvSelf");
00675   return res;
00676  }
00677 
00678  int orderI = idData(7);
00679  int orderJ = idData(8);
00680 
00681  static Vector data(11 + 3*3 + 3 + 6 + 2);
00682 
00683  res += theChannel.recvVector(elemDbTag, commitTag, data);
00684  if(res < 0) {
00685   g3ErrorHandler->warning("%s -- failed to receive Vector data",
00686    "BeamWithHinges2d::recvSelf");
00687   return res;
00688  }
00689 
00690  L = data(0);
00691  E = data(1);
00692  A = data(2);
00693  I = data(3);
00694  G = data(4);
00695  alpha = data(5);
00696  massDens = data(6);
00697  hingeIlen = data(7);
00698  hingeJlen = data(8);
00699  tolerance = data(9);
00700  shearLength = data(10);
00701 
00702  // Set up the section force interpolation
00703  this->setHinges();
00704 
00705  // Compute the elastic flexibility
00706  this->setElasticFlex();
00707 
00708  // Get committed history variables from the data vector
00709  int i,j;
00710  int loc = 11;
00711  for (i = 0; i < 3; i++)
00712   for (j = 0; j < 3; j++)
00713    kbCommit(i,j) = data(loc++);
00714 
00715  for (i = 0; i < 3; i++)
00716   qCommit(i) = data(loc++);
00717 
00718  for (i = 0; i < 6; i++)
00719   UeCommit(i) = data(loc++);
00720 
00721  for (i = 0; i < 2; i++)
00722   distrLoadCommit(i) = data(loc++);
00723 
00724  // Receive the coordinate transformation
00725  int crdTag = idData(5);
00726 
00727  // Allocate new CoordTransf if null
00728  if (theCoordTransf == 0)
00729   theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00730 
00731  // Check that the CoordTransf is of the right type; if not, delete
00732  // the current one and get a new one of the right type
00733  else if (theCoordTransf->getClassTag() != crdTag) {
00734   delete theCoordTransf;
00735   theCoordTransf = theBroker.getNewCrdTransf2d(crdTag);
00736  }
00737 
00738  // Check if either allocation failed
00739  if (theCoordTransf == 0) {
00740   g3ErrorHandler->warning("%s -- could not get a CrdTransf3d",
00741    "BeamWithHinges2d::recvSelf");
00742   return -1;
00743  }
00744 
00745  // Now, receive the CoordTransf
00746  theCoordTransf->setDbTag(idData(6));
00747  res += theCoordTransf->recvSelf(commitTag, theChannel, theBroker);
00748  if (res < 0) {
00749   g3ErrorHandler->warning("%s -- could not receive CoordTransf",
00750    "BeamWithHinges2d::recvSelf");
00751   return res;
00752  }
00753  
00754  // Revert the element to the last committed state that was just received
00755  // Can't call this->revertToLastCommit() because this->setDomain() may
00756  // not have been called yet
00757  sectionI->revertToLastCommit();
00758  e1 = sectionI->getSectionDeformation();
00759  sectionI->setTrialSectionDeformation(e1);
00760  sr1 = sectionI->getStressResultant();
00761  fs1 = sectionI->getSectionFlexibility();
00762 
00763  sectionJ->revertToLastCommit();
00764  e3 = sectionJ->getSectionDeformation();
00765  sectionJ->setTrialSectionDeformation(e3);
00766  sr3 = sectionJ->getStressResultant();
00767  fs3 = sectionJ->getSectionFlexibility();
00768 
00769  prevDistrLoad = distrLoadCommit;
00770  UePrev = UeCommit;
00771  kb = kbCommit;
00772  q = qCommit;
00773 
00774  initialFlag = false;
00775 
00776  return res;
00777 }
00778 
00779 void 
00780 BeamWithHinges2d::Print(ostream &s, int flag)
00781 {
00782  s << "\nBeamWithHinges2d, tag: " << this->getTag() << endl;
00783  s << "\tConnected Nodes: " << connectedExternalNodes;
00784  s << "\tE: " << E << endl;
00785  s << "\tA: " << A << endl;
00786  s << "\tI: " << I << endl;
00787 
00788  if (sectionI) {
00789   s << "\tHinge I, section tag: " << sectionI->getTag() << 
00790    ", length: " << hingeIlen << endl;
00791   sectionI->Print(s,flag);
00792  }
00793 
00794  if (sectionJ) {
00795   s << "\tHinge J, section tag: " << sectionJ->getTag() << 
00796    ", length: " << hingeJlen << endl;
00797   sectionJ->Print(s,flag);
00798  }
00799 }
00800 
00802 //Private Function Definitions
00803 
00804 void 
00805 BeamWithHinges2d::setNodePtrs(Domain *theDomain)
00806 {
00807  node1Ptr = theDomain->getNode(connectedExternalNodes(0));
00808  node2Ptr = theDomain->getNode(connectedExternalNodes(1));
00809 
00810  if(node1Ptr == 0) {
00811   cerr << "ERROR: BeamWithHinges2d::setNodePtrs() - Node 1: ";
00812   cerr << connectedExternalNodes(0) << " does not exist.\n";
00813   exit(-1);
00814  }
00815  
00816  if(node2Ptr == 0) {
00817   cerr << "ERROR: BeamWithHinges2d::setNodePtrs() - Node 2: ";
00818   cerr << connectedExternalNodes(1) << " does not exist.\n";
00819   exit(-1);
00820  }
00821  
00822  // check for correct # of DOF's
00823  int dofNd1 = node1Ptr->getNumberDOF();
00824  int dofNd2 = node2Ptr->getNumberDOF();
00825  if ((dofNd1 != 3) || (dofNd2 != 3))  {
00826   cerr << "ERROR: BeamWithHinges2d::setNodePtrs() - Number of ";
00827   cerr << "DOF's in nodes is incorrect.\n";
00828   exit(-1);
00829  }
00830 }
00831 
00832 void
00833 BeamWithHinges2d::getGlobalDispls(Vector &dg)    //get nodal displacements
00834 {
00835     const Vector &disp1 = node1Ptr->getTrialDisp();
00836     const Vector &disp2 = node2Ptr->getTrialDisp();
00837 
00838     dg(0) = disp1(0);  //left side
00839     dg(1) = disp1(1);
00840     dg(2) = disp1(2);
00841     dg(3) = disp2(0);  //right side
00842     dg(4) = disp2(1);
00843     dg(5) = disp2(2);
00844 }
00845 
00846 void
00847 BeamWithHinges2d::getGlobalAccels(Vector &ag) //for dynamic analysis
00848 {
00849     const Vector &accel1 = node1Ptr->getTrialAccel();
00850     const Vector &accel2 = node2Ptr->getTrialAccel();
00851 
00852     ag(0) = accel1(0);
00853     ag(1) = accel1(1);
00854     ag(2) = accel1(2);
00855     ag(3) = accel2(0);
00856     ag(4) = accel2(1);
00857     ag(5) = accel2(2);
00858 }
00859 
00860 void
00861 BeamWithHinges2d::setElasticFlex ()
00862 {
00863  //calculates the middle beam flexibility matrix
00864  //this is obtained by integrating (from lp1 to L-lp2) the matrix
00865  //b ^ fs ^ b, where fs is a constant linear section flexibility matrix.
00866  
00867  fElastic.Zero();
00868  vElastic.Zero();
00869 
00870  double a = hingeIlen;
00871  double b = L-hingeJlen;
00872  
00873  // Integrate elastic portion numerically 
00874  // Create elastic section
00875  static Matrix fElas(2,2);
00876  fElas(0,0) = 1.0/(E*A);
00877  fElas(1,1) = 1.0/(E*I);
00878 
00879  // Section code passed to force interpolation
00880  static ID code(2);
00881  code(0) = SECTION_RESPONSE_P;
00882  code(1) = SECTION_RESPONSE_MZ;
00883 
00884  // Section force interpolation matrix
00885  static Matrix bElas(2,3);
00886  
00887  // Mapping from [-1,1] to [a,b]
00888  double alpha = 0.5*(b-a); // Jacobian
00889  double beta = 0.5*(a+b);
00890 
00891  // Integration points ... the weights are 1.0*(0.5*(b-a)) ==> alpha
00892  const double xsi = 1.0/sqrt(3.0);
00893  double x1 = alpha*(-xsi) + beta;
00894  double x2 = alpha*xsi + beta;
00895 
00896  int dum; 
00897  // Get interpolations at sample points and integrate
00898  this->getForceInterpMatrix(bElas, x1, code, dum);
00899  fElastic.addMatrixTripleProduct(1.0, bElas, fElas, alpha);
00900  vElastic.addMatrix(1.0, bElas^ fElas, alpha);
00901 
00902  this->getForceInterpMatrix(bElas, x2, code, dum);
00903  fElastic.addMatrixTripleProduct(1.0, bElas, fElas, alpha);
00904  vElastic.addMatrix(1.0, bElas^ fElas, alpha);
00905 
00906  /*
00907  double shearFlex = 0.0;
00908 
00909  if (alpha > 0.0)
00910   shearFlex = 1/((G*A*alpha)*L*L) * (b-a);
00911 
00912  fElastic(0,0) = 1/(E*A) * ( b-a );
00913  fElastic(1,1) = 1/(E*I) * ( 1/(3*L*L)*(b*b*b-a*a*a) - 1/L*(b*b-a*a) + b-a ) + shearFlex;
00914  fElastic(2,2) = 1/(E*I) * ( 1/(3*L*L)*(b*b*b-a*a*a) ) + shearFlex;
00915  fElastic(1,2) = 1/(E*I) * ( 1/(3*L*L)*(b*b*b-a*a*a) - 1/(2*L)*(b*b-a*a) ) + shearFlex;
00916  fElastic(2,1) = fElastic(1,2);
00917 
00918  vElastic(0,0) = 1/(E*A) * ( b-a - 1/(2*L)*(b*b-a*a) );
00919  vElastic(1,1) = 1/(E*I) * ( 1/(4*L*L*L)*(b*b*b*b-a*a*a*a) - 1/(3*L*L)*(b*b*b-a*a*a) );
00920 
00921  if (alpha > 0.0)
00922   vElastic(2,1) = 1/(G*A*alpha) * ( 1/(2*L*L)*(b*b-a*a) - 1/(2*L)*(b-a) );
00923  */
00924 }
00925 
00926 void
00927 BeamWithHinges2d::setStiffMatrix(void)
00928 {
00929     // Get element global end displacements
00930     static Vector Ue(6);
00931     this->getGlobalDispls(Ue);
00932     
00933     // Compute global end deformation increments
00934     static Vector dUe(6);
00935     //dUe = Ue - UePrev;
00936  dUe = Ue;
00937  dUe.addVector(1.0, UePrev, -1.0);
00938     
00939     // Check if global end displacements have been changed
00940     if (dUe.Norm() != 0.0 || initialFlag == false) {
00941  // Compute distributed loads and increments
00942  static Vector currDistrLoad(2);
00943  static Vector distrLoadIncr(2); 
00944  
00945  currDistrLoad.Zero();       
00946  //distrLoadIncr = currDistrLoad - prevDistrLoad;
00947  distrLoadIncr = currDistrLoad;
00948  distrLoadIncr.addVector(1.0, prevDistrLoad, -1.0);
00949  prevDistrLoad = currDistrLoad;
00950  
00951  // Update the end deformations
00952  UePrev = Ue;
00953  
00954  theCoordTransf->update();
00955  
00956  // Convert to basic system from local coord's (eleminate rb-modes)
00957  static Vector dv(3);
00958  static Vector v(3);    // basic system deformations
00959  
00960  v = theCoordTransf->getBasicTrialDisp();
00961  dv = theCoordTransf->getBasicIncrDeltaDisp();
00962  
00963  // calculate nodal force increments and update nodal forces
00964  static Vector dq(3);
00965  //dq = kb * dv;     // using previous stiff matrix k,i
00966  dq.addMatrixVector(0.0, kb, dv, 1.0);
00967 
00968  // Element properties
00969  static Matrix f(3,3); // Element flexibility
00970  static Vector vr(3); // Residual element deformations
00971  
00972  Vector s1(sectionI->getStressResultant());
00973  Vector ds1(s1);
00974  Vector de1(s1);
00975  
00976  Vector s3(sectionJ->getStressResultant());
00977  Vector ds3(s3); 
00978  Vector de3(s3);
00979  
00980  for (int j = 0; j < maxIter; j++) {
00981      
00982      //q += dq;
00983   q.addVector(1.0, dq, 1.0);
00984      
00985      // Section forces
00986      //s1 = b1*q + bp1*currDistrLoad;
00987   s1.addMatrixVector(0.0, b1, q, 1.0);
00988   s1.addMatrixVector(1.0, bp1, currDistrLoad, 1.0);
00989 
00990      //s3 = b3*q + bp3*currDistrLoad;
00991   s3.addMatrixVector(0.0, b3, q, 1.0);
00992   s3.addMatrixVector(1.0, bp3, currDistrLoad, 1.0);
00993      
00994   // Increment in section forces
00995   // ds1 = s1 - sr1
00996   ds1 = s1;
00997   ds1.addVector(1.0, sr1, -1.0);
00998 
00999   // ds3 = s3 - sr3
01000   ds3 = s3;
01001   ds3.addVector(1.0, sr3, -1.0);
01002 
01003      // compute section deformation increments and update current deformations
01004      //e1 += fs1 * ds1;
01005   //e3 += fs3 * ds3;
01006   de1.addMatrixVector(0.0, fs1, ds1, 1.0);
01007   if (initialFlag != false)
01008    e1.addVector(1.0, de1, 1.0);
01009   
01010      de3.addMatrixVector(0.0, fs3, ds3, 1.0);
01011   if (initialFlag != false)
01012    e3.addVector(1.0, de3, 1.0);
01013      
01014      /*** Dependent on section type ***/
01015      // set section deformations
01016      sectionI->setTrialSectionDeformation(e1);
01017      sectionJ->setTrialSectionDeformation(e3);
01018      
01019      /*** Dependent on section type ***/
01020      // get section resisting forces
01021      sr1 = sectionI->getStressResultant();
01022      sr3 = sectionJ->getStressResultant();
01023      
01024      /*** Dependent on section type ***/
01025      // get section flexibility matrix
01026      fs1 = sectionI->getSectionFlexibility();
01027      fs3 = sectionJ->getSectionFlexibility();
01028      
01029   // ds1 = s1 - sr1;
01030   // ds3 = s3 - sr3;
01031   ds1 = s1;
01032   ds1.addVector(1.0, sr1, -1.0);
01033   ds3 = s3;
01034   ds3.addVector(1.0, sr3, -1.0);
01035 
01036   de1.addMatrixVector(0.0, fs1, ds1, 1.0);
01037   de3.addMatrixVector(0.0, fs3, ds3, 1.0);
01038      
01039      // Use special integration on the diagonal shear flexibility term and
01040      // the residual shear deformation
01041      double shearWeight;
01042 
01043   if (hingeIlen > 0.0) {
01044    int orderI = sectionI->getOrder();
01045    const ID &codeI = sectionI->getType();
01046    shearWeight = shearLength/hingeIlen;
01047    for (int i = 0; i < orderI; i++) {
01048     if (codeI(i) == SECTION_RESPONSE_VY) {
01049      fs1(i,i) *= shearWeight;
01050      e1(i) *= shearWeight;
01051      de1(i) *= shearWeight;
01052     }
01053    }
01054   }
01055 
01056   if (hingeJlen > 0.0) {
01057    int orderJ = sectionJ->getOrder();
01058    const ID &codeJ = sectionJ->getType();
01059    shearWeight = shearLength/hingeJlen;
01060    for (int i = 0; i < orderJ; i++) {
01061     if (codeJ(i) == SECTION_RESPONSE_VY) {
01062      fs3(i,i) *= shearWeight;
01063      e3(i) *= shearWeight;
01064      de3(i) *= shearWeight;
01065     }
01066    }
01067   }
01068 
01069   f = fElastic;
01070 
01071      // integrate section flexibility matrix
01072      // Matrix f1 = (b1^ fs1 * b1) * hingeIlen;
01073   f.addMatrixTripleProduct(1.0, b1, fs1, hingeIlen);
01074 
01075      // Matrix f3 = (b3^ fs3 * b3) * hingeJlen;
01076   f.addMatrixTripleProduct(1.0, b3, fs3, hingeJlen);
01077 
01078   // vr = fElastic * q;
01079   vr.addMatrixVector(0.0, fElastic, q, 1.0);
01080 
01081   // vr = vr + vElastic*currDistrLoad;
01082   vr.addMatrixVector(1.0, vElastic, currDistrLoad, 1.0);
01083 
01084      // vr += vr1, where vr1 = (b1^ (e1+de1)) * hingeIlen;
01085   vr.addMatrixTransposeVector(1.0, b1, e1 + de1, hingeIlen);
01086 
01087      // vr += vr3, where vr3 = (b3^ (e3+de3)) * hingeJlen;
01088      vr.addMatrixTransposeVector(1.0, b3, e3 + de3, hingeJlen);
01089      
01090      // Undo the temporary change for integrating shear terms
01091   if (hingeIlen > 0.0) {
01092    int orderI = sectionI->getOrder();
01093    const ID &codeI = sectionI->getType();
01094    shearWeight = shearLength/hingeIlen;
01095    for (int i = 0; i < orderI; i++) {
01096     if (codeI(i) == SECTION_RESPONSE_VY) {
01097      fs1(i,i) /= shearWeight;
01098      e1(i) /= shearWeight;
01099      de1(i) /= shearWeight;
01100     }
01101    }
01102   }
01103 
01104   if (hingeJlen > 0.0) {
01105    int orderJ = sectionJ->getOrder();
01106    const ID &codeJ = sectionJ->getType();
01107    shearWeight = shearLength/hingeJlen;
01108    for (int i = 0; i < orderJ; i++) {
01109     if (codeJ(i) == SECTION_RESPONSE_VY) {
01110      fs3(i,i) /= shearWeight;
01111      e3(i) /= shearWeight;
01112      de3(i) /= shearWeight;
01113     }
01114    }
01115   }
01116 
01117   // calculate element stiffness matrix
01118      invert3by3Matrix(f, kb);
01119 
01120      //dv = v - vr;
01121   dv = v;
01122   dv.addVector(1.0, vr, -1.0);
01123  
01124      // determine resisting forces
01125      // dq = kb * dv;
01126   dq.addMatrixVector(0.0, kb, dv, 1.0);
01127  
01128      double dW = dv^ dq;
01129 
01130      if (fabs(dW) < tolerance)
01131    break;
01132  } 
01133     
01134  // q += dq;
01135  q.addVector(1.0, dq, 1.0);
01136     
01137  P = theCoordTransf->getGlobalResistingForce (q, currDistrLoad);
01138  K = theCoordTransf->getGlobalStiffMatrix (kb, q);
01139 
01140  initialFlag = true;
01141     }
01142 
01143     return;
01144 }
01145 
01146 void
01147 BeamWithHinges2d::setMass(void)
01148 {
01149     //Note:  Lumped mass matrix only!
01150     //Note:  It is assumed that section's massDens is the same as beam's.
01151     m.Zero();
01152     m(0,0) = m(1,1) = m(3,3) = m(4,4) = massDens * L / 2.0;
01153 }
01154 
01155 void
01156 BeamWithHinges2d::setHinges (void)
01157 {
01158  // Get the number of section response quantities
01159  int orderI = sectionI->getOrder();
01160  int orderJ = sectionJ->getOrder();
01161 
01162  // Set interpolation matrices
01163  b1 = Matrix(orderI,3);
01164  b3 = Matrix(orderJ,3);
01165 
01166  // Set distributed load interpolation matrices
01167  bp1 = Matrix(orderI,2);
01168  bp3 = Matrix(orderJ,2);
01169 
01170  fs1 = Matrix(orderI,orderI);
01171  fs3 = Matrix(orderJ,orderJ);
01172 
01173  e1 = Vector(orderI);
01174  e3 = Vector(orderJ);
01175  
01176  sr1 = Vector(orderI);
01177  sr3 = Vector(orderJ);
01178 
01179  // Turn the hinge length ratios into actual lengths since L is not
01180  // known until setDomain() is called
01181  hingeIlen *= L;
01182  hingeJlen *= L;
01183  shearLength *= L;
01184 
01185  // Interpolation points
01186  double x1 = hingeIlen/2.0;
01187  double x3 = L - hingeJlen/2.0;
01188 
01189  // Get codes which indicate the ordering of section response quantities
01190  const ID &Icode = sectionI->getType();
01191  const ID &Jcode = sectionJ->getType();
01192 
01193  // Get the force interpolation matrix for each section
01194  this->getForceInterpMatrix (b1, x1, Icode, shearIkey);
01195  this->getForceInterpMatrix (b3, x3, Jcode, shearJkey);
01196 
01197  // Get the distributed load interpolation matrix for each section
01198  this->getDistrLoadInterpMatrix (bp1, x1, Icode);
01199  this->getDistrLoadInterpMatrix (bp3, x3, Jcode);
01200 }
01201 
01202 void
01203 BeamWithHinges2d::getForceInterpMatrix (Matrix &b, double x, const ID &code, int &shearKey)
01204 {   
01205     b.Zero();
01206 
01207  shearKey = -1;
01208 
01209     double xsi = x/L;
01210 
01211     for (int i = 0; i < code.Size(); i++) {
01212  switch (code(i)) {
01213    case SECTION_RESPONSE_MZ:  // Moment, Mz, interpolation
01214      b(i,1) = xsi - 1.0;
01215      b(i,2) = xsi;
01216      break;
01217    case SECTION_RESPONSE_P:  // Axial, P, interpolation
01218      b(i,0) = 1.0;
01219      break;
01220    case SECTION_RESPONSE_VY:  // Shear, Vy, interpolation
01221      b(i,1) = 1.0/L;
01222      b(i,2) = 1.0/L;
01223      shearKey = i;
01224      break;
01225    default:
01226      break;
01227  }
01228     }
01229 }
01230 
01231 void
01232 BeamWithHinges2d::getDistrLoadInterpMatrix (Matrix &bp, double x, const ID & code)
01233 {
01234     bp.Zero();
01235 
01236     double xsi = x/L;
01237 
01238     for (int i = 0; i < code.Size(); i++) {
01239  switch (code(i)) {
01240    case SECTION_RESPONSE_MZ:  // Moment, Mz, interpolation
01241      bp(i,1) = 0.5*xsi*(xsi-1);
01242      break;
01243    case SECTION_RESPONSE_P:  // Axial, P, interpolation
01244      bp(i,0) = 1 - xsi;
01245      break;
01246    case SECTION_RESPONSE_VY:  // Shear, Vy, interpolation
01247      bp(i,1) = xsi - 0.5;
01248      break;
01249    default:
01250      break;
01251  }
01252     }
01253 }
01254 
01255 Response*
01256 BeamWithHinges2d::setResponse (char **argv, int argc, Information &info)
01257 {
01258     // hinge rotations
01259     if (strcmp(argv[0],"rotation") == 0)
01260   return new ElementResponse(this, 1, Vector(2));
01261 
01262     // global forces
01263     else if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"forces") == 0 ||
01264   strcmp(argv[0],"globalForce") == 0 || strcmp(argv[0],"globalForces") == 0)
01265   return new ElementResponse(this, 2, P);
01266 
01267     // stiffness
01268     else if (strcmp(argv[0],"stiffness") == 0)
01269   return new ElementResponse(this, 3, K);
01270 
01271  // local forces
01272     else if (strcmp(argv[0],"localForce") == 0 || strcmp(argv[0],"localForces") == 0)
01273   return new ElementResponse(this, 4, P);
01274 
01275  // section response
01276  else if (strcmp(argv[0],"section") == 0) {
01277   int sectionNum = atoi(argv[1]);
01278  
01279   if (sectionNum == 1)
01280    return sectionI->setResponse(&argv[2], argc-2, info);
01281   else if (sectionNum == 2)
01282    return sectionJ->setResponse(&argv[2], argc-2, info);
01283   else
01284    return 0;
01285     }
01286  else
01287   return 0;
01288 }
01289 
01290 int
01291 BeamWithHinges2d::getResponse (int responseID, Information &eleInfo)
01292 {
01293  double V;
01294  static Vector force(6);
01295  static Vector rot(2);
01296 
01297  switch (responseID) {
01298   case 1: { // hinge rotations ... flexibility formulation, so add deformations
01299    int i;
01300    rot.Zero();
01301 
01302    const Vector &defI = sectionI->getSectionDeformation();
01303    int orderI = sectionI->getOrder();
01304    const ID &codeI = sectionI->getType();
01305    for (i = 0; i < orderI; i++)
01306     if (codeI(i) == SECTION_RESPONSE_MZ)
01307      rot(0) += defI(i)*hingeIlen;
01308 
01309    const Vector &defJ = sectionJ->getSectionDeformation();
01310    int orderJ = sectionJ->getOrder();
01311    const ID &codeJ = sectionJ->getType();
01312    for (i = 0; i < orderJ; i++)
01313     if (codeJ(i) == SECTION_RESPONSE_MZ)
01314      rot(1) += defJ(i)*hingeJlen;
01315 
01316    return eleInfo.setVector(rot);
01317       }
01318 
01319       case 2: // global forces
01320     return eleInfo.setVector(P);
01321 
01322       case 3: // stiffness
01323     return eleInfo.setMatrix(K);
01324 
01325    case 4: // local forces
01326   // Axial
01327   force(3) = q(0);
01328   force(0) = -q(0);
01329   // Moment
01330   force(2) = q(1);
01331   force(5) = q(2);
01332   // Shear
01333   V = (q(1)+q(2))/L;
01334   force(1) = V;
01335   force(4) = -V;
01336   return eleInfo.setVector(force);
01337 
01338       default:
01339     return -1;
01340     }
01341 }
01342 
01343 int
01344 BeamWithHinges2d::displaySelf(Renderer &theViewer, int displayMode, float fact)
01345 {
01346     // first determine the end points of the quad based on
01347     // the display factor (a measure of the distorted image)
01348     const Vector &end1Crd = node1Ptr->getCrds();
01349     const Vector &end2Crd = node2Ptr->getCrds(); 
01350 
01351     const Vector &end1Disp = node1Ptr->getDisp();
01352     const Vector &end2Disp = node2Ptr->getDisp();
01353 
01354  static Vector v1(3);
01355  static Vector v2(3);
01356 
01357  for (int i = 0; i < 2; i++) {
01358   v1(i) = end1Crd(i) + end1Disp(i)*fact;
01359   v2(i) = end2Crd(i) + end2Disp(i)*fact;    
01360  }
01361  
01362  return theViewer.drawLine (v1, v2, 1.0, 1.0);
01363 }
01364 
01365 int
01366 BeamWithHinges2d::setParameter (char **argv, int argc, Information &info)
01367 {
01368     // E of the beam interior
01369     if (strcmp(argv[0],"E") == 0) {
01370  info.theType = DoubleType;
01371  return 1;
01372     }
01373     
01374     // G of the beam interior
01375     else if (strcmp(argv[0],"G") == 0) {
01376  info.theType = DoubleType;
01377  return 2;
01378     }
01379     
01380     // A of the beam interior
01381     else if (strcmp(argv[0],"A") == 0) {
01382  info.theType = DoubleType;
01383  return 3;
01384     }
01385     
01386     // I of the beam interior
01387     else if (strcmp(argv[0],"I") == 0) {
01388  info.theType = DoubleType;
01389  return 4;
01390     }
01391     
01392     // alpha of the beam interior
01393     else if (strcmp(argv[0],"a") == 0 || strcmp(argv[0],"alpha") == 0) {
01394  info.theType = DoubleType;
01395  return 5;
01396     }
01397     
01398     // Section parameter
01399     else if (strcmp(argv[0],"section") ==0) {
01400  if (argc <= 2)
01401      return -1;
01402  
01403  int sectionNum = atoi(argv[1]);
01404  
01405  int ok = -1;
01406  
01407  if (sectionNum == 1)
01408      ok = sectionI->setParameter (&argv[2], argc-2, info);
01409  if (sectionNum == 2)
01410      ok = sectionJ->setParameter (&argv[2], argc-2, info);
01411  
01412  if (ok < 0)
01413      return -1;
01414  else if (ok < 100)
01415      return sectionNum*100 + ok;
01416  else 
01417      return -1;
01418     }
01419     
01420     // Unknown parameter
01421     else
01422  return -1;
01423 } 
01424 
01425 int
01426 BeamWithHinges2d::updateParameter (int parameterID, Information &info)
01427 {
01428     switch (parameterID) {
01429       case 1:
01430  this->E = info.theDouble;
01431  return 0;
01432       case 2:
01433  this->G = info.theDouble;
01434  return 0;
01435       case 3:
01436  this->A = info.theDouble;
01437  return 0;
01438       case 4:
01439  this->I = info.theDouble;
01440  return 0;
01441       case 5:
01442  this->alpha = info.theDouble;
01443  return 0;
01444       default:
01445  if (parameterID >= 100) { // section quantity
01446      int sectionNum = parameterID/100; 
01447      if (sectionNum == 1)
01448   return sectionI->updateParameter (parameterID-100, info);
01449      else if (sectionNum == 2)
01450   return sectionJ->updateParameter (parameterID-2*100, info);
01451      else
01452   return -1;
01453  }
01454  else // unknown
01455      return -1;
01456  } 
01457 } 
01458 
01459 
01460 
Copyright Contact Us