AxialCurve.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.3 $
00022 // $Date: 2006/09/05 22:39:58 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/limitState/limitCurve/AxialCurve.cpp,v $
00024                                                                         
00025 // Written: KJE
00026 // Created: Aug 2002
00027 //
00028 
00029 #include <AxialCurve.h>
00030 #include <G3Globals.h>
00031 #include <math.h>
00032 #include <ElementResponse.h>
00033 #include <Element.h>
00034 #include <Node.h>
00035 #include <Domain.h>
00036 #include <Vector.h>
00037 #include <float.h>
00038 #include <tcl.h>
00039 
00040 #include <DummyStream.h>
00041 
00042 #include <fstream>
00043 #include <iomanip>
00044 #include <iostream>
00045 using std::ifstream;
00046 using std::ios;
00047 using std::setw;
00048 using std::setprecision;
00049 using std::setiosflags;
00050 
00051 AxialCurve::AxialCurve(Tcl_Interp *passedTclInterp, int tag, int eTag, Domain *theDom, 
00052                         double Fsw, double Kd, double Fr, //SDK 
00053                         int dType, int fType, 
00054                         int ni, int nj, int df, int dirn, 
00055                         double del, int eleRem):
00056 LimitCurve(tag, TAG_AxialCurve), eleTag(eTag), theDomain(theDom), theElement(0),
00057 Fsw(Fsw), Kdeg(Kd), Fres(Fr), defType(dType), forType(fType), //SDK
00058 ndI(ni), ndJ(nj), dof(df), perpDirn(dirn), eleRemove(eleRem), delta(del)
00059 {
00060         theTclInterp = passedTclInterp;
00061         stateFlag = 0;
00062         theta2 = -1.45 ; //SDK
00063         sigma = 0.40;    //SDK
00064         eps_normal= 0.0;  //SDK
00065         dP_old = 0.0; // SDK
00066         deform_old = 0.0; // SDK
00067         failDrift = 0.0; // SDK
00068         stepCounter = 0; // Terje
00069 }
00070 
00071 
00072 AxialCurve::AxialCurve():
00073 LimitCurve(0, TAG_AxialCurve), eleTag(0), theDomain(0), theElement(0),
00074 Fsw(0), Kdeg(0), Fres(0), defType(0), forType(0), //SDK
00075 ndI(0), ndJ(0), dof(0), perpDirn(0), eleRemove(0), delta(0)
00076 {
00077         stateFlag = 0;
00078         theta2 = -1.45 ; //SDK
00079         sigma = 0.40;    //SDK
00080         eps_normal= 0.0;  //SDK
00081         dP_old = 0.0; // SDK
00082         deform_old = 0.0; // SDK
00083         failDrift = 0.0; // SDK
00084         stepCounter = 0; // Terje
00085 }
00086 
00087 
00088 AxialCurve::~AxialCurve()
00089 {
00090 //VOID//
00091 }
00092 
00093 
00094 LimitCurve*
00095 AxialCurve::getCopy(void)
00096 {
00097         AxialCurve *theCopy = new AxialCurve(theTclInterp,this->getTag(),
00098                 eleTag, theDomain, Fsw, Kdeg, Fres, defType, forType, //SDK
00099                 ndI, ndJ, dof, perpDirn, delta, eleRemove);
00100 
00101         theCopy->stateFlag = stateFlag;
00102         theCopy->theta2 = theta2; //SDK
00103         theCopy->sigma = sigma;   //SDK
00104         theCopy->eps_normal = eps_normal;  //SDK
00105 
00106         theCopy->deform_old = deform_old;  //Terje
00107         theCopy->failDrift = failDrift;  //Terje
00108         theCopy->dP_old = dP_old;  //Terje
00109 
00110         theCopy->stepCounter = stepCounter;  //Terje
00111 
00112         return theCopy;
00113 }
00114 
00115 
00116 // check if limit state surface has been reached
00117 int
00118 AxialCurve::checkElementState(double springForce)
00119 {
00120   static DummyStream dummy;
00121         // Terje
00122         // Count the number of times this method is called 
00123         // (this is equal to the number of loadsteps)
00124         stepCounter++;
00125 
00126         // if element has not been removed (element removal not fully implemented)
00127         if (eleRemove != 2) {
00128 
00129                 // find associated beam-column element on first visit
00130                 if (theElement == 0)
00131                 {
00132                         theElement = theDomain->getElement(eleTag);
00133 
00134                         if (theElement == 0) {
00135 //                              g3ErrorHandler->fatal("WARNING AxialCurve - no element with tag %i exists in Domain",eleTag);
00136                         }
00137                         // find length between nodes if drift is desired
00138                         if (defType == 2)
00139                         {
00140                                 Node *nodeI = theDomain->getNode(ndI);
00141                                 Node *nodeJ = theDomain->getNode(ndJ);
00142 
00143                                 const Vector &crdI = nodeI->getCrds();
00144                                 const Vector &crdJ = nodeJ->getCrds();
00145 
00146                                 if (crdI(perpDirn) == crdJ(perpDirn)) {
00147 //                                      g3ErrorHandler->warning("%s -- Nodal projection has zero component along chosen direction",
00148 //                                                      "AxialCurve::AxialCurve");
00149 
00150                                         oneOverL = 0.0;
00151                                 }
00152                                 else 
00153                                         oneOverL = 1.0/fabs(crdJ(perpDirn) - crdI(perpDirn));
00154                         }
00155                 }
00156 
00157                 dP = 0;                 //zero change in axial load
00158                 double deform;  // value of deformation parameter from element
00159                 double force;   // value of force parameter from element
00160 //              double Ps;              // axial load at shear failure - for now assumed to be current axial load (Commented out by Terje)
00161                 int result;             //junk variable
00162 
00163 
00164                 // Based on "defType" and "forType" calculate 
00165                 // the desired response parameters "deform" and "force"
00166                 if (defType == 1) // maximum chord rotation
00167                 {
00168 
00169                         Response *theRotations =0; // integer element returns in setResponse
00170 
00171                         const char *r[1] = {"basicDeformations"}; // must be implemented in element
00172 
00173                         Information     *rotInfoObject =0;   
00174                         
00175                         Vector *rotVec; //vector of chord rotations at beam-column ends
00176 
00177                         // set type of beam-column element response desired
00178                         theRotations = theElement->setResponse(r, 1, *rotInfoObject, dummy);
00179 
00180                         // put element response in the vector of "myInfo"
00181                         result = theRotations->getResponse();
00182 
00183                         // access the myInfo vector containing the response (new for Version 1.2)
00184                         Information &theInfo = theRotations->getInformation();
00185                         rotVec = (theInfo.theVector);
00186 
00187                         deform = (fabs((*rotVec)(1)) > fabs((*rotVec)(2))) ? 
00188                                 fabs((*rotVec)(1)) : fabs((*rotVec)(2));  //use larger of two end rotations
00189                 }
00190                 else if (defType == 2) // interstory drift
00191                 {
00192                         // find associated nodes 
00193                         Node *nodeI = theDomain->getNode(ndI);
00194                         Node *nodeJ = theDomain->getNode(ndJ);
00195 
00196                         // get displacements
00197                         const Vector &dispI = nodeI->getTrialDisp();
00198                         const Vector &dispJ = nodeJ->getTrialDisp();
00199                         
00200                         // calc drift
00201                         double dx = fabs(dispJ(dof)-dispI(dof));
00202                         deform = dx*oneOverL;
00203                 }
00204                 else {
00205 //                      g3ErrorHandler->fatal("WARNING AxialCurve - deformation type flag %i not implemented",defType);
00206                 }
00207                 
00208                         Response *theForces =0;
00209 
00210                         const char *f[1] = {"localForce"}; // does not include influence of P-delta
00211                                                                                  // for P-delta use forType = 0
00212 
00213                         Information     *forInfoObject =0;
00214 
00215                         Vector *forceVec; //vector of basic forces from beam column
00216 
00217                         // set type of beam-column element response desired
00218                         theForces    = theElement->setResponse(f, 1, *forInfoObject, dummy);
00219 
00220                         // put element response in the vector of "myInfo"
00221                         result += theForces->getResponse();
00222 
00223                         // access the myInfo vector containing the response (new for Version 1.2)
00224                         Information &theInfo = theForces->getInformation();
00225                         forceVec = (theInfo.theVector);
00226 
00227                 // Local forces (assuming no element loads)
00228                 if (forType == 0)
00229                         force = springForce;                    //force in associated hysteretic material
00230                 else if (forType == 1) 
00231                         force = fabs((*forceVec)(1));   // shear 
00232                 else if (forType == 2) 
00233                         force = (*forceVec)(0);                 //axial - positive for compression 
00234                 else {
00235 //                      g3ErrorHandler->fatal("WARNING AxialMaterial - force type flag %i not implemented",forType);
00236                 }
00237 
00238                 // Determine if (deform,force) is outside limit state surface.
00239                 // 
00240                 // Use absolute value of deform
00241                 // Use signed value of force to see if in compression
00242                    double forceSurface = findLimit(deform); // force on surface at deform
00243                 // double deformSurface = findLimit(force); // deform on surface at force SDK
00244                 
00245                 
00246                 
00247                 
00248                 
00249                 
00250                 //cout << "force = " << force << ", forceSurface = " << forceSurface << endln;
00251 
00252                 char tclAssignment[100]="";
00253 
00254                 if (stateFlag == 0) //prior to failure
00255                 {
00256 
00257                         sprintf(tclAssignment , "set fail_%d  0", eleTag);
00258                         Tcl_Eval( theTclInterp, tclAssignment);
00259 
00260 
00261                         if (force >= forceSurface) // on/outside failure surface
00262                         //if (deform >= deformSurface) // on/outside failure surface SDK
00263                         {       
00264                                 // remove element and change eleRemove flag (not fully implemented)
00265                                 if (eleRemove == 1)   
00266                                 {
00267                                         Element *theEle = theDomain->removeElement(eleTag);
00268                                         eleRemove = 2;  // do not check element again
00269                                         stateFlag = 0;
00270 
00271                                         if (theEle != 0) 
00272                                         {
00273                                                 delete theEle;
00274                                         }
00275 
00276                                 } else {
00277 
00278                                         stateFlag = 1;
00279 
00280                                         dP = fabs(force) - fabs(forceSurface); //change in axial load
00281                                         opserr << "AxialCurve - failure detected at deform = " << deform << ", force = " << force << ",element: " << eleTag << endln;//SDK
00282 
00283                                         failDrift = (dP * deform_old - dP_old * deform)/(dP - dP_old);//SDK
00284 
00285                                         // Terje
00286                                         // Failure has occurred for the first time, so we 
00287                                         // print data to be employed by the limit-state function
00288 
00289                                         char myString[100];
00290                                         sprintf(myString, "AxialFailureOfElement%d.txt", eleTag);
00291                                         ofstream outputFile( myString, ios::out );
00292 
00293                                         sprintf(myString, "%d %20.8e  %20.8e  %20.8e", stepCounter, deform_old, failDrift, deform);
00294                         
00295                                         outputFile << myString << endln;
00296 
00297                                         outputFile.close();
00298 
00299                                         sprintf(tclAssignment , "set fail_%d  1", eleTag);
00300                                         Tcl_Eval( theTclInterp, tclAssignment);
00301 
00302 
00303                                 }
00304                         }
00305                         else // inside failure surface
00306                         {
00307                                 stateFlag = 0;
00308                                 
00309                                 dP_old = fabs(force) - fabs(forceSurface); //SDK
00310                                 deform_old = deform; //SDK
00311 
00312 
00313                         }
00314 
00315                 }
00316                 else // after failure
00317                 {
00318                         if (force >= forceSurface) // on/outside failure surface
00319                 //      if (deform >= deformSurface) // on/outside failure surface SDK
00320 
00321 
00322                         {
00323                                 if (forceSurface == Fres)
00324                                         stateFlag = 4; // once at residual capacity, do not check state again
00325                                 else
00326                                         stateFlag = 2;
00327 
00328                                         dP = fabs(force) - fabs(forceSurface); //change in axial load
00329                                 // SDK  opserr << "AxialCurve - on failure surface at deform = " << deform << ", force = " << force << endln;
00330                         }
00331                         else // inside failure surface
00332                         {
00333                                 stateFlag = 3;
00334                         }
00335                 }
00336         }
00337 
00338         return stateFlag;
00339 }
00340 
00341 
00342 double
00343 AxialCurve::getDegSlope(void)
00344 {
00345         return Kdeg;
00346 }
00347 
00348 
00349 double
00350 AxialCurve::getResForce(void)
00351 {
00352         return Fres;  
00353 }
00354 
00355 double
00356 AxialCurve::getUnbalanceForce(void)
00357 {
00358         return dP;
00359 }
00360 
00361 int
00362 AxialCurve::sendSelf(int commitTag, Channel &theChannel)
00363 {
00364         return -1;
00365 }
00366 
00367 
00368 int
00369 AxialCurve::recvSelf(int commitTag, Channel &theChannel, 
00370                         FEM_ObjectBroker &theBroker)
00371 {
00372         return -1;
00373 }
00374     
00375 
00376 void
00377 AxialCurve::Print(OPS_Stream &s, int flag)
00378 {
00379         s << "Axial Limit Curve, tag: " << this->getTag() << endln;
00380         s << "Fsw: " << Fsw << endln; 
00381         s << "eleTag: " << eleTag << endln;
00382         s << "nodeI: " << ndI << endln;
00383         s << "nodeJ: " << ndJ << endln;
00384         s << "deform: " << defType << endln;
00385         s << "force: " << forType << endln;
00386 }
00387 
00388 
00389 //Private Functions
00390 
00391 
00392 // AXIAL FAILURE MODEL FROM ELWOOD (2002)
00393 double
00394 AxialCurve::findLimit(double x)
00395 {
00396         double y = 0.0;
00397 
00398         if (x < 0 || x > 0.08) {
00399 //              g3ErrorHandler->warning("Warning: Outside limits of AxialCurve");
00400         }
00401 
00402         double theta = 65.0*PI/180.0;
00403         double d = x-delta;
00404 
00405         if (d <= 0.0)
00406                 d = 1.0e-9;
00407 
00408         // positive for compression
00409         y = ((1+tan(theta)*tan(theta))/(25*d)-tan(theta))*Fsw*tan(theta);
00410 
00411         //Do not allow axial load to be reduced below residual capacity (may be zero)
00412         //Input as positive
00413         if (y < Fres) {
00414                 y = Fres;
00415         }
00416 
00417         return y;
00418 }
00419 
00420 /*
00421 
00423 double
00424 AxialCurve::findLimit(double DR)
00425 {
00426         double P = 0.0;
00427         double mu = 0.0;
00428         double DRa = DR - delta;
00429         double theta = 65.0*PI/180.0;
00430 
00431   
00432         mu = (log(DRa) - log(-0.15 - 0.23*theta2) - sigma*eps_normal)/theta2;
00433                 
00434                 
00435         P = (Ast * fyt * dc/Hs) * (1+ mu* tan(theta))/(1 - (mu/tan(theta)));
00436         
00437         //for lower limit of probabilistic model
00438         if (P < 0.0) {
00439 
00440                 P = 10.0e99;
00441 
00442         }
00443 
00444 
00445         //Fres residual force
00446         if (P < Fres) {
00447                 
00448                 P = Fres;
00449         }
00450 
00451 
00452         return P;
00453 }
00454 
00455 */
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 // AddingSensitivity:BEGIN ///////////////////////////////////
00464 int
00465 AxialCurve::setParameter(const char **argv, int argc, Parameter &param)
00466 {
00467   if (argc < 1)
00468     return -1;
00469   
00470   else
00471     opserr << "WARNING: Could not set parameter in Axial Curve. " << endln;
00472   
00473   return -1;
00474 }
00475 
00476 
00477 
00478 int
00479 AxialCurve::updateParameter(int parameterID, Information &info)
00480 {
00481         switch (parameterID) {
00482         case -1:
00483                 return -1;
00484 
00485         default:
00486                 return -1;
00487         }
00488 
00489 
00490         return 0;
00491 }
00492 
00493 
00495 
00496 int AxialCurve::revertToStart ()
00497 {
00498         stateFlag = 0;
00499         theta2 = -1.45 ; //SDK
00500         sigma = 0.40;    //SDK
00501         eps_normal= 0.0;  //SDK
00502         dP_old = 0.0; // SDK
00503         deform_old = 0.0; // SDK
00504         failDrift = 0.0; // SDK
00505         stepCounter = 0; // Terje
00506 
00507         return 0;
00508 }

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