Bilinear.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.2 $
00022 // $Date: 2006/09/05 22:47:26 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/material/uniaxial/snap/Bilinear.cpp,v $
00024 //
00025 //
00026 // Bilinear.cpp: implementation of the Bilinear class inspried by Fortran version.
00027 // Originally from SNAP PROGRAM by Luis Ibarra and Prof H.K. Krawinkler
00028 //
00029 // Written: A. Altoontash & Prof. G. Deierlein 05/03
00030 // Revised: 05/05
00031 //
00032 // Purpose: This file contains the implementation for the Bilinear class.
00033 //
00035 
00036 #include <Bilinear.h>
00037 #include <Channel.h>
00038 #include <Parameter.h>
00039 
00040 #include <stdlib.h>
00041 #include <math.h>
00042 #include <string.h>
00043 
00044 #define DEBG 0
00045 
00047 // Construction/Destruction
00049 
00050 Bilinear::Bilinear(int tag, Vector inputParam  ,DamageModel *strength,DamageModel *stiffness,DamageModel *capping)
00051   :UniaxialMaterial(tag,MAT_TAG_SnapBilinear),StrDamage(0),StfDamage(0),CapDamage(0)
00052 {
00053         int ErrorFlag =0;
00054         //*********************************************************************
00055         //      CONSTRUCTING VARIABLES
00056         //
00057         //      elstk           =       Initial elastic stiffness
00058         //      fyieldPos       =       Positive yield strength
00059         //      fyieldNeg       =       Negative yield strength
00060         //      alfa            =       Strain-hardening ratio (fraction of elstk)
00061         //      alfaCap         =       Cap slope ratio (fraction of elstk)
00062         //      capDispPos      =       Cap displacement on positive side
00063         //  capDispNeg  =       Cap displacement on negative side
00064         //      flagCapenv  =   A flag to establish a cut-off limit for the force once the cap is hit
00065         //  Resfac              =       Residual stress ratio (fraction of yield strength)
00066         //      strength        =       A pointer to strength damage model
00067         //      stiffness       =       A pointer to stiffness damage model
00068         //      capping         =       A pointer to capping damage model
00069         //
00070         //  INPUT VARIABLES
00071         //  d                   = Current Displcamenet
00072         //
00073         //
00074         //  OUTPUT VARIABLE
00075         //      f                       = Calculated force response
00076         //      ek                      = Calculated stiffness
00077         //      
00078         //
00079         //*********************************************************************
00080         
00081         if( (inputParam.Size()) < 9) 
00082                 opserr << "Error: Bilinear(): inputParam, size <15\n" << "\a";
00083 
00084         elstk           = inputParam[0];
00085         fyieldPos       = inputParam[1];
00086         fyieldNeg       = inputParam[2];
00087         alfa            = inputParam[3];
00088         alfaCap         = inputParam[4];
00089         capDispPos      = inputParam[5];
00090         capDispNeg      = inputParam[6];
00091         flagCapenv  = (int)inputParam[7];
00092         Resfac          = inputParam[8];
00093 
00094 
00095         // Error check
00096         
00097         if ( fyieldPos <= 0.0 || fyieldNeg >= 0.0 )
00098     {
00099                 opserr << "Error: Bilinear::Bilinear  : Incorrect yield stresse \n" << "\a";
00100                 ErrorFlag =1;
00101     }
00102 
00103         if ( elstk <= 0.0 )
00104     {
00105                 opserr << "Error: Bilinear::Bilinear  : Elastic modulus must be positive\n" << "\a";
00106                 ErrorFlag =1;
00107     }
00108         
00109         if ( alfa < 0.0 || alfa > 0.8 )
00110     {
00111                 opserr << "Error: Bilinear::Bilinear  : alpha is recommended to be in the range of [0.0 , 0.8]\n" << "\a";      
00112     }
00113         
00114         if ( alfaCap >= 0.0 || alfaCap == alfa )
00115     {
00116                 opserr << "Error: Bilinear::Bilinear  : CapSlope must be negative and not equal to alfa\n" << "\a";
00117                 ErrorFlag =1;
00118     }   
00119         
00120         if ( capDispPos < fyieldPos/elstk || capDispNeg > fyieldNeg/elstk )
00121     {
00122                 opserr << "Error: Bilinear::Bilinear  : Capping brach must be located outside the yield criteria\n" << "\a";
00123                 ErrorFlag =1;
00124     }
00125         
00126         if ( Resfac <  0.0  || Resfac > 1.0)
00127     {
00128                 opserr << "Error: Bilinear::Bilinear  : Residual must be positive and less than 1.0\n" << "\a";
00129                 ErrorFlag =1;
00130     }
00131         
00132         if ( DEBG ==1 )
00133     {
00134                 // Open an output file for debugging
00135                 char FileName[20];                                              // debugging
00136                 sprintf(FileName, "Bilinear%d.out", tag);
00137                 OutputFile = fopen ( FileName , "w" );  // debugging
00138                 fprintf( OutputFile , "Constructor called\n" ); // debugging
00139                 fprintf( OutputFile , "elstk = %f\n",inputParam[0]);
00140                 fprintf( OutputFile , "fyieldPos = %f\n",inputParam[1]);
00141                 fprintf( OutputFile , "fyieldNeg = %f\n",inputParam[2]);
00142                 fprintf( OutputFile , "alfa = %f\n",inputParam[3]);
00143                 fprintf( OutputFile , "alfaCap = %f\n",inputParam[4]);
00144                 fprintf( OutputFile , "capDispPos = %f\n",inputParam[5]);
00145                 fprintf( OutputFile , "capDispNeg = %f\n",inputParam[6]);
00146                 fprintf( OutputFile , "flagCapenv = %d\n",(int) inputParam[7]);
00147                 fprintf( OutputFile , "Resfac = %f\n",inputParam[8]);
00148     }
00149         
00150         
00151         if ( DEBG ==2 )
00152     {
00153                 // Open an output file for debugging
00154                 char FileName[20];                                              // debugging
00155                 sprintf(FileName, "Bilinear%d.out", tag);
00156                 OutputFile = fopen ( FileName , "w" );  // debugging
00157     }
00158 
00159         if ( ErrorFlag == 1 )    {
00160                 opserr << "Error: Bilinear::Bilinear  : Error: check the input values\n" << "\a";       
00161                 exit(-1);
00162         }
00163 
00164         
00165         if ( strength != NULL )
00166         {
00167                 StrDamage = strength->getCopy();
00168                 if ( StrDamage == NULL ) {
00169                         opserr << "Error: Bilinear::Bilinear  : Can not make a copy of strength damage model\n" << "\a";        
00170                         exit(-1);
00171                 }
00172         }
00173         
00174         if ( stiffness != NULL )
00175         {
00176                 StfDamage = stiffness->getCopy();
00177                 if ( StfDamage == NULL ) {
00178                         opserr << "Error: Bilinear::Bilinear  : Can not make a copy of stiffness damage model\n" << "\a";       
00179                         exit(-1);
00180                 }
00181         }       
00182 
00183         if ( capping != NULL )
00184         {
00185                 CapDamage = capping->getCopy();
00186                 if ( CapDamage == NULL ) {
00187                         opserr << "Error: Bilinear::Bilinear  : Can not make a copy of capping damage model\n" << "\a"; 
00188                         exit(-1);
00189                 }
00190         }
00191         
00192         // Initialice history data
00193         this->revertToStart();
00194 }
00195 
00196 
00197 Bilinear::Bilinear()
00198   :UniaxialMaterial(0,MAT_TAG_SnapBilinear)
00199 {
00200         if ( DEBG ==1 ) fprintf( OutputFile , "Empty constructor called\n" );   // debugging
00201 }
00202 
00203 
00204 Bilinear::~Bilinear()
00205 {
00206         if ( DEBG == 1 || DEBG == 2 )
00207     {
00208                 fprintf( OutputFile , "Distructor called\n" );          // debugging
00209                 fclose( OutputFile );                                           // debugging
00210     }
00211 
00212         if ( StrDamage != 0 ) delete StrDamage;
00213         if ( StfDamage != 0 ) delete StfDamage;
00214         if ( CapDamage != 0 ) delete CapDamage;
00215 }
00216 
00217 
00218 int Bilinear::revertToStart()
00219 {
00220         if ( DEBG ==1 ) fprintf( OutputFile , "Revert to start\n" );            // debugging
00221 
00222         hsLastCommit[0] =  0.0;                                                                                                 // dP
00223         hsLastCommit[1] =  0.0;                                                                                                 // fP
00224         hsLastCommit[2] =  elstk;                                                                                               // ekP
00225         hsLastCommit[3] =  elstk;                                                                                               // ekexcurs
00226         hsLastCommit[4] =  fyieldPos;                                                                                   // fyPos
00227         hsLastCommit[5] =  fyieldNeg;                                                                                   // fyNeg
00228         hsLastCommit[6] =  alfa*elstk;                                                                                  // ekhard
00229         hsLastCommit[7] =  capDispPos;                                                                                  // cpPos
00230         hsLastCommit[8] =  capDispNeg;                                                                                  // cpNeg
00231         hsLastCommit[9] =  alfaCap*elstk;                                                                               // ekcap
00232         hsLastCommit[10]=  0.0;                                                                                                 // dmax
00233         hsLastCommit[11]=  0.0;                                                                                                 // dmin
00234         hsLastCommit[12]=  fyieldPos+alfa*elstk*(capDispPos-fyieldPos/elstk);   // fuPos
00235         hsLastCommit[13]=  fyieldNeg+alfa*elstk*(capDispNeg-fyieldNeg/elstk);   // fuNeg
00236         hsLastCommit[14]=  0.0;                                                                                                 // Enrgtot
00237         hsLastCommit[15]=  0.0;                                                                                                 // Enrgc
00238         hsLastCommit[16]=  0.0;                                                                                                 // reserved
00239 
00240         for( int i=0 ; i<17 ; i++) {
00241                 hsCommit[i] = hsLastCommit[i];
00242                 hsTrial[i] = hsLastCommit[i];
00243         }
00244         if ( StrDamage != NULL ) StrDamage->revertToStart();
00245         if ( StfDamage != NULL ) StfDamage->revertToStart();
00246         if ( CapDamage != NULL ) CapDamage->revertToStart();
00247         
00248         if ( DEBG == 1 || DEBG == 2 )
00249     {
00250                 if ( StrDamage != NULL ) fprintf( OutputFile , "%d" ,StrDamage->getDamage() );          // debugging
00251                 if ( StfDamage != NULL ) fprintf( OutputFile , "\t%d" , StfDamage->getDamage() );               // debugging
00252                 if ( CapDamage != NULL ) fprintf( OutputFile , "\t%d\n" , CapDamage->getDamage() );             // debugging
00253     }
00254 
00255         return 0;
00256 }
00257 
00258 
00259 void Bilinear::Print(OPS_Stream &s, int flag)
00260 {
00261         if ( DEBG ==1 ) fprintf( OutputFile , "Print\n" );      // debugging
00262         s << "Bilinear Tag: " << this->getTag() << endln;
00263         s << "d : " << hsTrial[0] << endln;
00264         s << "f : " << hsTrial[1] << endln;
00265         s << "ek: " << hsTrial[2] << endln;
00266         s << endln;
00267 }
00268 
00269 
00270 int Bilinear::revertToLastCommit()
00271 {
00272         if ( DEBG ==1 ) fprintf( OutputFile , "Revert to last commit\n" );      // debugging
00273         
00274         for(int i=0; i<17; i++) {
00275                 hsTrial[i] = hsCommit[i];
00276                 hsCommit[i] = hsLastCommit[i];
00277         }
00278         if ( StrDamage != NULL ) StrDamage->revertToLastCommit();
00279         if ( StfDamage != NULL ) StfDamage->revertToLastCommit();
00280         if ( CapDamage != NULL ) CapDamage->revertToLastCommit();
00281         
00282         return 0;
00283 }
00284 
00285 
00286 int Bilinear::commitState()
00287 {
00288         if ( DEBG ==1 ) fprintf( OutputFile , "Commit state\n" );       // debugging
00289         
00290         for(int i=0; i<17; i++) {
00291                 hsLastCommit[i] = hsCommit[i];
00292                 hsCommit[i] = hsTrial[i];
00293         }
00294 
00295                 // Calling the damage object
00296         Vector InforForDamage(3);
00297         InforForDamage(0) = hsCommit[0];
00298         InforForDamage(1) = hsCommit[1];
00299         InforForDamage(2) = hsCommit[3];
00300 
00301         if ( StrDamage != NULL ) {
00302                 StrDamage->setTrial(InforForDamage);
00303                 StrDamage->commitState();
00304         }
00305 
00306         if ( StfDamage != NULL ) {
00307                 StfDamage->setTrial(InforForDamage);
00308                 StfDamage->commitState();
00309         }
00310 
00311         if ( CapDamage != NULL ) {
00312                 CapDamage->setTrial(InforForDamage);
00313                 CapDamage->commitState();
00314         }
00315 
00316         return 0;
00317 }
00318 
00319 
00320 double Bilinear::getTangent()
00321 {
00322         if ( DEBG ==1 ) {
00323                 fprintf( OutputFile , "Get tangent\n" );
00324                 fprintf( OutputFile , "tangent = %f\n",hsTrial[2]);
00325         } // debugging
00326         return hsTrial[2];
00327 }
00328 
00329 double Bilinear::getInitialTangent (void)
00330 {
00331         if ( DEBG ==1 ) fprintf( OutputFile , "Get initial tangent\n" );        // debugging
00332         return elstk;
00333 }
00334 
00335 double Bilinear::getStress()
00336 {
00337         if ( DEBG ==1 ) {
00338                 fprintf( OutputFile , "Get stress\n" );
00339                 fprintf( OutputFile , "Stress = %f\n",hsTrial[1]);
00340         }// debugging
00341         return hsTrial[1];
00342 }
00343 
00344 
00345 double Bilinear::getStrain (void)
00346 {
00347         if ( DEBG ==1 ) {
00348                 fprintf( OutputFile , "Get strain\n" );
00349                 fprintf( OutputFile , "Strain = %f\n",hsTrial[0]);
00350         }       // debugging
00351         return hsTrial[0];
00352 }
00353 
00354 
00355 int Bilinear::recvSelf(int cTag, Channel &theChannel, 
00356                                FEM_ObjectBroker &theBroker)
00357 {
00358         if ( DEBG ==1 ) fprintf( OutputFile , "Receive self\n" );       // debugging
00359         return 0;
00360 }
00361 
00362 
00363 int Bilinear::sendSelf(int cTag, Channel &theChannel)
00364 {
00365         if ( DEBG ==1 ) fprintf( OutputFile , "Send self\n" );  // debugging
00366         return 0;
00367 }
00368 
00369 
00370 UniaxialMaterial *Bilinear::getCopy(void)
00371 {
00372         if ( DEBG ==1 ) fprintf( OutputFile , "Get copy\n" );   // debugging
00373         Vector inp(9);
00374         
00375         inp[0]  = elstk;
00376         inp[1]  = fyieldPos;
00377         inp[2]  = fyieldNeg;
00378         inp[3]  = alfa;
00379         inp[4]  = alfaCap;
00380         inp[5]  = capDispPos;
00381         inp[6]  = capDispNeg;
00382         inp[7]  = flagCapenv;
00383         inp[8]  = Resfac;
00384 
00385         
00386         Bilinear *theCopy = new Bilinear(this->getTag(), inp ,StrDamage,StfDamage,CapDamage);
00387         
00388         for (int i=0; i<17; i++) {
00389                 theCopy->hsTrial[i] = hsTrial[i];
00390                 theCopy->hsCommit[i] = hsCommit[i];
00391                 theCopy->hsLastCommit[i] = hsLastCommit[i];
00392         }
00393 
00394         return theCopy;
00395 }
00396 
00397 
00398 int Bilinear::setTrialStrain( double d, double strainRate)
00399 {
00400         if ( DEBG ==1 ){
00401                 fprintf( OutputFile , "Set trial displacement to %f\n" ,d);
00402 
00403         }
00404         // debugging
00405         
00406         // HYSTERETIC VARIABLES
00407         double dP,fP,ekP,ekexcurs,fyPos,fyNeg,ekhard,cpPos,cpNeg,ekcap,dmax,dmin;
00408         double fuPos,fuNeg,Enrgtot,Enrgc;
00409 
00410         // LOCAL VARIABLES
00411         double deltaD, f, ek, fenvPos, fenvNeg, ekenvPos, ekenvNeg;
00412 
00413         // Relationship between basic variables and hsTrial array --------------
00414         dP                                      = hsCommit[0];
00415         fP                                      = hsCommit[1];
00416         ekP                                     = hsCommit[2];
00417         ekexcurs                        = hsCommit[3];
00418         fyPos                           = hsCommit[4];
00419         fyNeg                           = hsCommit[5];
00420         ekhard                          = hsCommit[6];
00421         cpPos                           = hsCommit[7];
00422         cpNeg                           = hsCommit[8];
00423         ekcap                           = hsCommit[9];
00424         dmax                            = hsCommit[10];
00425         dmin                            = hsCommit[11];
00426         fuPos                           = hsCommit[12];
00427         fuNeg                           = hsCommit[13];
00428         Enrgtot                         = hsCommit[14];
00429         Enrgc                           = hsCommit[15];
00430 
00431         // Initialization of variables (each time the subroutine is called) 
00432         deltaD = d-dP;
00433 
00434         // Calculate the displacement envelope for maximum and minimum strain
00435         if ( d > dmax ) dmax = d;
00436         if ( d < dmin ) dmin = d;
00437 
00438         // Check for a new excursion to degrade the parameters
00439         if ( (fP + ekexcurs * deltaD) * fP <= 0.0 )
00440         {               
00441                 // degrade the model paraeters based on the damage
00442                 // degrade the strength ( yield stress )
00443                 if ( StrDamage != NULL )
00444                 {
00445                         double StrengthResidual = ( 1.0 - StrDamage->getDamage() );
00446                         if ( StrengthResidual < 0.0 ) StrengthResidual = 0.0;
00447                         
00448                         fyPos = StrengthResidual * ( fyieldPos - Resfac*fyieldPos) + Resfac*fyieldPos;
00449                         fyNeg = StrengthResidual * ( fyieldNeg - Resfac*fyieldNeg) + Resfac*fyieldNeg;
00450                 }
00451 
00452                 // degrade the stiffness
00453                 if ( StfDamage != NULL )
00454                 {
00455                         double StiffnessResidual = ( 1.0 - StfDamage->getDamage() );
00456                         if ( StiffnessResidual < 0.0 ) StiffnessResidual = 0.0;
00457 
00458                         ekexcurs = StiffnessResidual * ( elstk - alfa*elstk ) + alfa*elstk;
00459                 }
00460                 
00461                 // degrade the cap
00462                 if ( CapDamage != NULL )
00463                 {
00464                         double CapRefPos = ( fyieldPos + (capDispPos - fyieldPos/elstk) * alfa*elstk - Resfac * fyieldPos ) / (alfaCap*elstk);
00465                         double CapRefNeg = ( fyieldNeg + (capDispNeg - fyieldNeg/elstk) * alfa*elstk - Resfac * fyieldNeg ) / (alfaCap*elstk);
00466 
00467                                 
00468                         double CapPosResidual = ( 1.0 - CapDamage->getPosDamage() );
00469                         if ( CapPosResidual < 0.0 ) CapPosResidual = 0.0;
00470                         double CapNegResidual = ( 1.0 - CapDamage->getNegDamage() );
00471                         if ( CapNegResidual < 0.0 ) CapNegResidual = 0.0;
00472 
00473                         cpPos = CapPosResidual * ( capDispPos - CapRefPos ) + CapRefPos;
00474                         cpPos = ( cpPos > CapRefPos ) ? cpPos : CapRefPos;
00475 
00476                         cpNeg = CapNegResidual * ( capDispNeg - CapRefNeg ) + CapRefNeg;
00477                         cpNeg = ( cpNeg < CapRefNeg ) ? cpNeg : CapRefNeg;
00478                 }
00479         }
00480 
00481         // predict the f based on excurs stiffness
00482         f = fP + ekexcurs * deltaD;
00483         ek = ekenvPos = ekenvNeg = ekexcurs;
00484 
00485         // Calculate the envelopes
00486         if ( f >= 0 )
00487         {
00488                 this->envelPosCap( ekexcurs, fyPos, ekhard, cpPos, ekcap, Resfac*fyieldPos, &fuPos, d, &fenvPos, &ekenvPos );
00489                 fenvNeg = 0.0; 
00490         } else
00491         {
00492                 this->envelNegCap( ekexcurs, fyNeg, ekhard, cpNeg, ekcap, Resfac*fyieldNeg, &fuNeg, d, &fenvNeg, &ekenvNeg );
00493                 fenvPos = 0.0; 
00494         }
00495 
00496         if ( DEBG == 2 ) fprintf( OutputFile , "%f  %f  %f\n" , d , cpPos, fuPos );     // debugging
00497 
00498         // Compare the predictor force with the envelope and correct the 
00499         if ( f > fenvPos )
00500         {
00501                 f = fenvPos;
00502         } 
00503         else if ( f < fenvNeg )
00504         {
00505                 f = fenvNeg;
00506         }
00507 
00508 
00509         if ( flagCapenv == 1 )
00510         {
00511                 if ( f > fuPos )
00512                 {
00513                         f = fuPos;
00514                 } 
00515                 else if ( f < fuNeg )
00516                 {
00517                         f = fuNeg;
00518                 }
00519         }
00520 
00521         if ( deltaD != 0.0 ) ek = ( f - fP ) / deltaD;
00522 
00523         // Relationship between basic variables and hsTrial array       for next cycle
00524         hsTrial[0] = d;
00525         hsTrial[1] = f;
00526         hsTrial[2] = ek;
00527         hsTrial[3] = ekexcurs;
00528         hsTrial[4] = fyPos;
00529         hsTrial[5] = fyNeg;
00530         hsTrial[6] = ekhard;
00531         hsTrial[7] = cpPos;
00532         hsTrial[8] = cpNeg;
00533         hsTrial[9] = ekcap;
00534         hsTrial[10] = dmax;
00535         hsTrial[11] = dmin;
00536         hsTrial[12] = fuPos;
00537         hsTrial[13] = fuNeg;
00538         hsTrial[14] = Enrgtot;
00539         hsTrial[15] = Enrgc;
00540         hsTrial[16] = 0.0;
00541 
00542         return 0;
00543 }
00544 
00545 
00546 Response* Bilinear::setResponse(const char **argv, int argc, Information &matInfo)
00547 {
00548         if ( argv == NULL || argc == 0 ) {
00549                 opserr << "Error: Bilinear::setResponse  : No argument specified\n" << "\a";
00550                 exit (-1);
00551         }
00552 ;
00553 
00554         if (strcmp(argv[0],"force") == 0 || strcmp(argv[0],"stress") == 0 )
00555                 return new MaterialResponse(this, 1, 0.0);
00556 
00557         else if (strcmp(argv[0],"defo") == 0 || strcmp(argv[0],"deformation") == 0 ||
00558                 strcmp(argv[0],"strain") == 0)
00559                 return new MaterialResponse(this, 2, 0.0);
00560 
00561         else if (strcmp(argv[0],"plastic") == 0 || strcmp(argv[0],"plasticdefo") == 0 ||
00562                 strcmp(argv[0],"plasticdeformation") == 0 || strcmp(argv[0],"plasticstrain") == 0)
00563                 return new MaterialResponse(this, 3, 0.0);
00564 
00565         else if ( (strcmp(argv[0],"stiff") == 0) || (strcmp(argv[0],"stiffness") == 0) )
00566                 return new MaterialResponse(this, 4, 0.0);
00567         
00568         else if ( (strcmp(argv[0],"unloading") == 0) || (strcmp(argv[0],"unloadingstiffness") == 0)
00569                 || (strcmp(argv[0],"unloadingstiff") == 0 ) )
00570                 return new MaterialResponse(this, 5, 0.0);
00571 
00572         else if ( (strcmp(argv[0],"damage") == 0) || (strcmp(argv[0],"damages") == 0)
00573                 || (strcmp(argv[0],"Damage") == 0 ) || (strcmp(argv[0],"Damages") == 0 ) )
00574                 return new MaterialResponse(this, 6, Vector(3));
00575 
00576         else
00577                 return 0;
00578 }
00579 
00580 int Bilinear::getResponse(int responseID, Information &matInfo)
00581 {
00582   switch (responseID) {
00583     case 1:
00584                 return matInfo.setDouble( hsTrial[1] );
00585                         
00586     case 2:
00587                 return matInfo.setDouble( hsTrial[0] );
00588                 
00589     case 3:
00590                 return matInfo.setDouble( hsTrial[0]  - hsTrial[1] / hsTrial[3]);
00591                 
00592         case 4:
00593                 return matInfo.setDouble( hsTrial[2] );
00594                 
00595         case 5:
00596                 return matInfo.setDouble( hsTrial[3] );
00597 
00598         case 6:
00599                 (*(matInfo.theVector))(0) = 0.0;
00600                 (*(matInfo.theVector))(1) = 0.0;
00601                 (*(matInfo.theVector))(2) = 0.0;
00602                 if ( StrDamage != NULL ) (*(matInfo.theVector))(0) = StrDamage->getDamage();
00603                 if ( StfDamage != NULL ) (*(matInfo.theVector))(1) = StfDamage->getDamage();
00604                 if ( CapDamage != NULL ) (*(matInfo.theVector))(2) = CapDamage->getDamage();
00605         return 0;
00606                         
00607     default:
00608                 return 0;
00609   }
00610 }
00611 
00612 
00613 void Bilinear::recordInfo(int cond )
00614 {
00615 
00616 }
00617 
00618 
00619 void Bilinear::envelPosCap( double ekelstk, double fy, double ekhard, double dcap,
00620                                                    double ekcap, double fRes, double *fuPos, double d, double *f, double *ek )
00621 {
00622         double dy, fucap, dRes, dmin;
00623         
00624         dy = fy / ekelstk;
00625         dmin = dy - ( (fy-fRes) / ekhard);
00626 //      dcap = ( dcap > dy ) ? dcap : dy;
00627         fucap = fRes + (dcap - dmin) * ekhard;
00628         dRes = dcap + ( fRes - fucap ) / ekcap;
00629 
00630         
00631         if ( DEBG ==1 )
00632     {           
00633                 fprintf( OutputFile , "Positive envelope called\n" );   // debugging
00634                 fprintf( OutputFile , "dmin = %f\n",dmin);
00635                 fprintf( OutputFile , "dy = %f\n",dy);
00636                 fprintf( OutputFile , "fy = %f\n",fy);
00637                 fprintf( OutputFile , "dcap = %f\n",dcap);
00638                 fprintf( OutputFile , "fucap = %f\n",fucap);
00639                 fprintf( OutputFile , "dRes = %f\n",dRes);
00640                 fprintf( OutputFile , "fRes = %f\n",fRes);
00641     }
00642 
00643 
00644         if ( d < dmin ){
00645                 *f = fRes;
00646                 *ek = 0.0;
00647         }
00648         else if ( d < dcap ){
00649                 *f = ekhard * ( d - dmin ) + fRes;
00650                 *ek = ekhard;
00651         }
00652         else if ( d < dRes ){
00653                 *f = fucap + ekcap * (d - dcap);
00654                 *ek = ekcap;
00655                 if ( *f < *fuPos ) *fuPos = *f;
00656         }
00657         else{
00658                 *f = fRes;
00659                 *ek = 0.0;
00660                 *fuPos = fRes;
00661         }
00662         return;
00663 }
00664 
00665 
00666 void Bilinear::envelNegCap( double ekelstk, double fy, double ekhard, double dcap,
00667                                                    double ekcap, double fRes, double *fuNeg,double d, double *f, double *ek )
00668 {
00669         if ( fy > 0.0 || fRes > 0.0 ) {
00670                 opserr <<" Error : Bilinear::envelNegCap wrong parameters in function call";
00671                 exit(-1);
00672         } 
00673 
00674         double dy, fucap, dRes, dmax;
00675         
00676         dy = fy / ekelstk;
00677         dmax = dy - ( (fy-fRes) / ekhard);
00678 //      dcap = ( dcap < dy ) ? dcap : dy;
00679         fucap = fRes + (dcap - dmax)*ekhard;
00680         dRes = dcap + ( fRes - fucap ) / ekcap;
00681         
00682         if ( DEBG ==1 )
00683     {           
00684                 fprintf( OutputFile , "Negative envelope called\n" );   // debugging
00685                 fprintf( OutputFile , "dRes = %f\n",dRes);
00686                 fprintf( OutputFile , "fRes = %f\n",fRes);
00687                 fprintf( OutputFile , "dcap = %f\n",dcap);
00688                 fprintf( OutputFile , "fucap = %f\n",fucap);
00689                 fprintf( OutputFile , "dy = %f\n",dy);
00690                 fprintf( OutputFile , "fy = %f\n",fy);
00691                 fprintf( OutputFile , "dmax = %f\n",dmax);
00692     }
00693                 
00694         if ( d > dmax ){
00695                 *f = fRes;
00696                 *ek = 0.0;
00697         }
00698         else if ( d > dcap ){
00699                 *f = ekhard * ( d - dmax ) + fRes;
00700                 *ek = ekhard;
00701         }
00702         else if ( d > dRes ){
00703                 *f = fucap + ekcap * (d - dcap);
00704                 *ek = ekcap;
00705                 if ( *f > *fuNeg ) *fuNeg = *f;
00706         }
00707         else{
00708                 *f = fRes;
00709                 *ek = 0.0;
00710                 *fuNeg = fRes;
00711         }
00712         return;
00713 }
00714 
00715 
00716 int
00717 Bilinear::setParameter(const char **argv, int argc, Parameter &param)
00718 {
00719   if (argc < 1)
00720     return 0;
00721   
00722   if (strcmp(argv[0],"elstk") == 0) 
00723     return param.addObject(1, this);
00724   
00725   if (strcmp(argv[0],"fyieldPos") == 0) 
00726     return param.addObject(2, this);
00727   
00728   if (strcmp(argv[0],"fyieldNeg") == 0) 
00729     return param.addObject(3, this);
00730   
00731   if (strcmp(argv[0],"alfa") == 0) 
00732     return param.addObject(4, this);
00733   
00734   if (strcmp(argv[0],"alfaCap") == 0) 
00735     return param.addObject(5, this);
00736   
00737   if (strcmp(argv[0],"capDispPos") == 0) 
00738     return param.addObject(6, this);
00739   
00740   if (strcmp(argv[0],"capDispNeg") == 0) 
00741     return param.addObject(7, this);
00742   
00743   if (strcmp(argv[0],"Resfac") == 0) 
00744     return param.addObject(8, this);
00745   
00746   if (strcmp(argv[0],"flagCapenv") == 0) 
00747     return param.addObject(9, this);
00748   
00749   else
00750     opserr << "WARNING: Could not set parameter in BoucWenMaterial. " << endln;
00751   
00752   return 0;
00753 }
00754 
00755 
00756 int
00757 Bilinear::updateParameter(int parameterID, Information &info)
00758 {
00759 
00760         switch (parameterID) {
00761         case -1:
00762                 return -1;
00763         case 1:
00764                 this->elstk = info.theDouble;
00765                 break;
00766         case 2:
00767                 this->fyieldPos = info.theDouble;
00768                 break;
00769         case 3:
00770                 this->fyieldNeg = info.theDouble;
00771                 break;
00772         case 4:
00773                 this->alfa = info.theDouble;
00774                 break;
00775         case 5:
00776                 this->alfaCap = info.theDouble;
00777                 break;
00778         case 6:
00779                 this->capDispPos = info.theDouble;
00780                 break;
00781         case 7:
00782                 this->capDispNeg = info.theDouble;
00783                 break;
00784         case 8:
00785                 this->Resfac = info.theDouble;
00786                 break;
00787         case 9:
00788                 this->flagCapenv = info.theInt;
00789                 break;
00790         default:
00791                 return -1;
00792         }
00793 
00794         return 0;
00795 }
00796 
00797 
00798 
00799 int
00800 Bilinear::activateParameter(int passedParameterID)
00801 {
00802         parameterID = passedParameterID;
00803 
00804         return 0;
00805 }
00806 
00807 
00808 
00809 /*
00810 double
00811 Bilinear::getStressSensitivity(int gradNumber, bool conditional)
00812 {
00813 
00814         // Declare output variable
00815         double sensitivity = 0.0;
00816 
00817 
00818         // Issue warning if response is zero (then an error will occur)
00819         if (hsTrial[0] == 0.0)  {
00820                 opserr << "ERROR: Bilinear::getStressSensitivity() is called " << endln
00821                         << " with zero hysteretic deformation d." << endln;
00822         }
00823 
00824         // First set values depending on what is random
00825         double Delstk;
00826         double DfyieldPos;
00827         double DfyieldNeg;
00828         double Dalfa;
00829         double DalfaCap;
00830         double DcapDispPos;
00831         double DcapDispNeg;
00832         double DResfac;
00833 
00834 
00835         if (parameterID == 0) { }
00836         else if (parameterID == 1) {Delstk=1.0;}
00837         else if (parameterID == 2) {DfyieldPos=1.0;}
00838         else if (parameterID == 3) {DfyieldNeg=1.0;}
00839         else if (parameterID == 4) {Dalfa=1.0;}
00840         else if (parameterID == 5) {DalfaCap=1.0;}
00841         else if (parameterID == 6) {DcapDispPos=1.0;}
00842         else if (parameterID == 7) {DcapDispNeg=1.0;}
00843         else if (parameterID == 8) {DResfac=1.0;}
00844 
00845 
00846 
00847         // Pick up sensitivity history variables for this gradient number
00848         double DCz = 0.0;
00849         double DCe = 0.0;
00850         double DCstrain = 0.0;
00851         if (SHVs != 0) {
00852                 DCz              = (*SHVs)(0,(gradNumber-1));
00853                 DCe              = (*SHVs)(1,(gradNumber-1));
00854                 DCstrain = (*SHVs)(2,(gradNumber-1));
00855         }
00856 
00857         
00858         // Compute sensitivity of z_{i+1} 
00859         // (use same equations as for the unconditional 
00860         // sensitivities, just set DTstrain=0.0)
00861         double c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11;
00862         double DTstrain = 0.0; 
00863         double dStrain = Tstrain-Cstrain;
00864         double TA, Tnu, Teta, DTz, Psi, Phi, DPsi;
00865 
00866         c1  = DCe 
00867                 - Dalpha*ko*dStrain*Tz
00868                 + (1-alpha)*Dko*dStrain*Tz
00869                 + (1-alpha)*ko*(DTstrain-DCstrain)*Tz;
00870         c2  = (1-alpha)*ko*dStrain;
00871         c3  = DAo - DdeltaA*Te - deltaA*c1;
00872         c4  = -deltaA*c2;
00873         c5  = DdeltaNu*Te + deltaNu*c1;
00874         c6  = deltaNu*c2;
00875         c7  = DdeltaEta*Te + deltaEta*c1;
00876         c8  = deltaEta*c2;
00877         TA = Ao - deltaA*Te;
00878         Tnu = 1.0 + deltaNu*Te;
00879         Teta = 1.0 + deltaEta*Te;
00880         Psi = gamma + beta*signum(dStrain*Tz);
00881         DPsi= Dgamma + Dbeta*signum(dStrain*Tz);
00882         Phi = TA - pow(fabs(Tz),n)*Psi*Tnu;
00883         c9  = dStrain/Teta;
00884         c10 = DCz + c9*c3 - c9*pow(fabs(Tz),n)*Dn*log(fabs(Tz))*Psi*Tnu
00885                 - c9*pow(fabs(Tz),n)*DPsi*Tnu - c9*pow(fabs(Tz),n)*Psi*c5
00886                 - Phi/(Teta*Teta)*c7*dStrain + Phi/Teta*(DTstrain-DCstrain);
00887         c11 = 1.0 - c9*c4 + c9*pow(fabs(Tz),n)*Psi*c6
00888                 + c9*pow(fabs(Tz),n)*n/fabs(Tz)*signum(Tz)*Psi*Tnu
00889                 + Phi/(Teta*Teta)*c8*dStrain;
00890 
00891         DTz = c10/c11;
00892 
00893         sensitivity = Dalpha*ko*Tstrain
00894                         + alpha*Dko*Tstrain
00895                                 - Dalpha*ko*Tz
00896                                 + (1-alpha)*Dko*Tz
00897                                 + (1-alpha)*ko*DTz;
00898 
00899         return sensitivity;
00900 }
00901 
00902 
00903 
00904 double
00905 BoucWenMaterial::getTangentSensitivity(int gradNumber)
00906 {
00907         return 0.0;
00908 }
00909 
00910 double
00911 BoucWenMaterial::getDampTangentSensitivity(int gradNumber)
00912 {
00913         return 0.0;
00914 }
00915 
00916 double
00917 BoucWenMaterial::getStrainSensitivity(int gradNumber)
00918 {
00919         return 0.0;
00920 }
00921 
00922 double
00923 BoucWenMaterial::getRhoSensitivity(int gradNumber)
00924 {
00925         return 0.0;
00926 }
00927 
00928 
00929 int
00930 BoucWenMaterial::commitSensitivity(double TstrainSensitivity, int gradNumber, int numGrads)
00931 {
00932         if (SHVs == 0) {
00933                 SHVs = new Matrix(3,numGrads);
00934         }
00935 
00936         // First set values depending on what is random
00937         double Dalpha = 0.0;
00938         double Dko = 0.0;
00939         double Dn = 0.0;
00940         double Dgamma = 0.0;
00941         double Dbeta = 0.0;
00942         double DAo = 0.0;
00943         double DdeltaA = 0.0;
00944         double DdeltaNu = 0.0;
00945         double DdeltaEta = 0.0;
00946 
00947         if (parameterID == 1) {Dalpha=1.0;}
00948         else if (parameterID == 2) {Dko=1.0;}
00949         else if (parameterID == 3) {Dn=1.0;}
00950         else if (parameterID == 4) {Dgamma=1.0;}
00951         else if (parameterID == 5) {Dbeta=1.0;}
00952         else if (parameterID == 6) {DAo=1.0;}
00953         else if (parameterID == 7) {DdeltaA=1.0;}
00954         else if (parameterID == 8) {DdeltaNu=1.0;}
00955         else if (parameterID == 9) {DdeltaEta=1.0;}
00956 
00957 
00958         // Pick up sensitivity history variables for this gradient number
00959         double DCz = 0.0;
00960         double DCe = 0.0;
00961         double DCstrain = 0.0;
00962         if (SHVs != 0) {
00963                 DCz              = (*SHVs)(0,(gradNumber-1));
00964                 DCe              = (*SHVs)(1,(gradNumber-1));
00965                 DCstrain = (*SHVs)(2,(gradNumber-1));
00966         }
00967 
00968         
00969         // Compute sensitivity of z_{i+1} 
00970         // (use same equations as for the unconditional 
00971         // sensitivities, just set DTstrain=0.0)
00972         double c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11;
00973         double DTstrain = TstrainSensitivity; 
00974         double dStrain = Tstrain-Cstrain;
00975         double TA, Tnu, Teta, DTz, Psi, Phi, DPsi, DTe;
00976 
00977         c1  = DCe 
00978                 - Dalpha*ko*dStrain*Tz
00979                 + (1-alpha)*Dko*dStrain*Tz
00980                 + (1-alpha)*ko*(DTstrain-DCstrain)*Tz;
00981         c2  = (1-alpha)*ko*dStrain;
00982         c3  = DAo - DdeltaA*Te - deltaA*c1;
00983         c4  = -deltaA*c2;
00984         c5  = DdeltaNu*Te + deltaNu*c1;
00985         c6  = deltaNu*c2;
00986         c7  = DdeltaEta*Te + deltaEta*c1;
00987         c8  = deltaEta*c2;
00988         TA = Ao - deltaA*Te;
00989         Tnu = 1.0 + deltaNu*Te;
00990         Teta = 1.0 + deltaEta*Te;
00991         Psi = gamma + beta*signum(dStrain*Tz);
00992         DPsi= Dgamma + Dbeta*signum(dStrain*Tz);
00993         Phi = TA - pow(fabs(Tz),n)*Psi*Tnu;
00994         c9  = dStrain/Teta;
00995         c10 = DCz + c9*c3 - c9*pow(fabs(Tz),n)*Dn*log(fabs(Tz))*Psi*Tnu
00996                 - c9*pow(fabs(Tz),n)*DPsi*Tnu - c9*pow(fabs(Tz),n)*Psi*c5
00997                 - Phi/(Teta*Teta)*c7*dStrain + Phi/Teta*(DTstrain-DCstrain);
00998         c11 = 1.0 - c9*c4 + c9*pow(fabs(Tz),n)*Psi*c6
00999                 + c9*pow(fabs(Tz),n)*n/fabs(Tz)*signum(Tz)*Psi*Tnu
01000                 + Phi/(Teta*Teta)*c8*dStrain;
01001 
01002         DTz = c10/c11;
01003 
01004         DTe = DCe - Dalpha*ko*dStrain*Tz
01005                 + (1-alpha)*Dko*dStrain*Tz
01006                 + (1-alpha)*ko*(DTstrain-DCstrain)*Tz
01007                 + (1-alpha)*ko*dStrain*DTz;
01008 
01009 
01010         // Save sensitivity history variables
01011         (*SHVs)(0,(gradNumber-1)) = DTz;
01012         (*SHVs)(1,(gradNumber-1)) = DTe;
01013         (*SHVs)(2,(gradNumber-1)) = DTstrain;
01014 
01015         return 0;
01016 }
01017 
01018 */

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