TzSimple1.cpp

Go to the documentation of this file.
00001 /* *********************************************************************
00002 **    Module:   TzSimple1.cpp 
00003 **
00004 **    Purpose:  Provide a simple t-z spring for OpenSees.
00005 **
00006 **    Developed by Ross W. Boulanger
00007 **    (C) Copyright 2002, All Rights Reserved.
00008 **
00009 ** ****************************************************************** */
00010 
00011 // $Revision: 1.0
00012 // $Date: 2002/1/19
00013 // $Source: /OpenSees/SRC/material/uniaxial/TzSimple1.cpp
00014 
00015 // Written: RWB
00016 // Created: Jan 2002
00017 // Revision: A
00018 // tested and checked: Boris Jeremic (jeremic@ucdavis.edu) Spring 2002
00019 //
00020 // Description: This file contains the class implementation for TzSimple1
00021 
00022 #include <stdlib.h>
00023 
00024 #include "TzSimple1.h"
00025 #include <Vector.h>
00026 #include <Channel.h>
00027 #include <math.h>
00028 
00029 // Controls on internal iteration between spring components
00030 const int TZmaxIterations = 20;
00031 const double TZtolerance = 1.0e-12;
00032 
00034 //      Constructor with data
00035 
00036 TzSimple1::TzSimple1(int tag,int classtag, int tz_type,double t_ult,double z_50,double dash_pot)
00037 :UniaxialMaterial(tag,classtag),
00038  tzType(tz_type), tult(t_ult), z50(z_50), dashpot(dash_pot)
00039 {
00040   // Initialize TzSimple variables and history variables
00041   //
00042   this->revertToStart();
00043   initialTangent = Ttangent;
00044 }
00045 
00047 //      Default constructor
00048 
00049 TzSimple1::TzSimple1()
00050 :UniaxialMaterial(0,0),
00051  tzType(0), tult(0.0), z50(0.0), dashpot(0.0)
00052 {
00053   // Initialize variables .. WILL NOT WORK AS NOTHING SET
00054   // this->revertToStart();
00055 
00056   // need to set iterations and tolerance
00057 
00058   // BTW maxIterations and tolerance should not be private variables, they
00059   // should be static .. all PySimple1 materials share the same values & 
00060   // these values don't change
00061 
00062 }
00063 
00065 //      Default destructor
00066 TzSimple1::~TzSimple1()
00067 {
00068     // Does nothing
00069 }
00070 
00072 void TzSimple1::getFarField(double z)
00073 {
00074         TFar_z   = z;
00075         TFar_tang= TFar_tang;
00076         TFar_t   = TFar_tang * TFar_z;
00077 
00078         return;
00079 }
00080 
00082 void TzSimple1::getNearField(double zlast, double dz, double dz_old)
00083 {
00084         // Limit "dz" step size if it is osillating and not shrinking.
00085         //
00086         if(dz*dz_old < 0.0 && fabs(dz/dz_old) > 0.5) dz = -dz_old/2.0;
00087 
00088         // Establish trial "z" and direction of loading (with dzTotal) for entire step.
00089         //      
00090         TNF_z = zlast + dz;
00091         double dzTotal = TNF_z - CNF_z;
00092 
00093         // Treat as elastic if dzTotal is below TZtolerance
00094         //
00095         if(fabs(dzTotal*TNF_tang/tult) < 10.0*TZtolerance) 
00096         {
00097                 TNF_t = TNF_t + dz*TNF_tang;
00098                 if(fabs(TNF_t) >=(1.0-TZtolerance)*tult) 
00099                         TNF_t =(TNF_t/fabs(TNF_t))*(1.0-TZtolerance)*tult;
00100                 return;
00101         }
00102 
00103         // Reset the history terms to the last Committed values, and let them
00104         // reset if the reversal of loading persists in this step.
00105         //
00106         if(TNF_tin != CNF_tin)
00107         {
00108                 TNF_tin = CNF_tin;
00109                 TNF_zin = CNF_zin;
00110         }
00111 
00112         // Change from positive to negative direction
00113         //
00114         if(CNF_z > CNF_zin && dzTotal < 0.0)
00115         {
00116                 TNF_tin = CNF_t;
00117                 TNF_zin = CNF_z;
00118         }
00119 
00120         // Change from negative to positive direction
00121         //
00122         if(CNF_z < CNF_zin && dzTotal > 0.0)
00123         {
00124                 TNF_tin = CNF_t;
00125                 TNF_zin = CNF_z;
00126         }
00127         
00128         // Positive loading
00129         //
00130         if(dzTotal > 0.0)
00131         {
00132                 TNF_t=tult-(tult-TNF_tin)*pow(zref,np)
00133                                         *pow(zref + TNF_z - TNF_zin,-np);
00134                 TNF_tang=np*(tult-TNF_tin)*pow(zref,np)
00135                                         *pow(zref + TNF_z - TNF_zin,-np-1.0);
00136         }
00137         // Negative loading
00138         //
00139         if(dzTotal < 0.0)
00140         {
00141                 TNF_t=-tult+(tult+TNF_tin)*pow(zref,np)
00142                                         *pow(zref - TNF_z + TNF_zin,-np);
00143                 TNF_tang=np*(tult+TNF_tin)*pow(zref,np)
00144                                         *pow(zref - TNF_z + TNF_zin,-np-1.0);
00145         }
00146 
00147         // Ensure that |t|<tult and tangent not zero or negative.
00148         //
00149         if(fabs(TNF_t) >=tult) {
00150                 TNF_t =(TNF_t/fabs(TNF_t))*(1.0-TZtolerance)*tult;}
00151         if(TNF_tang <=1.0e-4*tult/z50) TNF_tang = 1.0e-4*tult/z50;
00152 
00153         return;
00154 }
00155 
00157 int 
00158 TzSimple1::setTrialStrain (double newz, double zRate)
00159 {
00160         // Set trial values for displacement and load in the material
00161         // based on the last Tangent modulus.
00162         //
00163         double dz = newz - Tz;
00164         double dt = Ttangent * dz;
00165         TzRate    = zRate;
00166 
00167         // Limit the size of step (dz or dt) that can be imposed. Prevents
00168         // oscillation under large load reversal steps
00169         //
00170         int numSteps = 1;
00171         double stepSize = 1.0;
00172         if(fabs(dt/tult) > 0.5)  numSteps = 1 + int(fabs(dt/(0.5*tult)));
00173         if(fabs(dz/z50)  > 1.0 ) numSteps = 1 + int(fabs(dz/(1.0*z50)));
00174         stepSize = 1.0/float(numSteps);
00175         if(numSteps > 100) numSteps = 100;
00176 
00177         dz = stepSize * dz;
00178 
00179         // Main loop over the required number of substeps
00180         //
00181         for(int istep=1; istep <= numSteps; istep++)
00182         {
00183                 Tz = Tz + dz;
00184                 dt = Ttangent * dz;
00185                 
00186                 // May substep in NearField component if not making progress due to oscillation
00187                 // The following history term is initialized here.
00188                 //
00189                 double dz_nf_old = ((Tt+dt) - TNF_t)/TNF_tang;
00190                 
00191         // Iterate to distribute displacement between elastic & plastic components.
00192         // Use the incremental iterative strain & iterate at this strain.
00193         //
00194         for (int j=1; j < TZmaxIterations; j++)
00195         {
00196                 Tt = Tt + dt;
00197                 if(fabs(Tt) >(1.0-TZtolerance)*tult) Tt=(1.0-TZtolerance)*tult*(Tt/fabs(Tt));
00198 
00199                 // Stress & strain update in Near Field element
00200                 double dz_nf = (Tt - TNF_t)/TNF_tang;
00201                 getNearField(TNF_z,dz_nf,dz_nf_old);
00202                 
00203                 // Residuals in Near Field element
00204                 double t_unbalance = Tt - TNF_t;
00205                 double zres_nf = (Tt - TNF_t)/TNF_tang;
00206                 dz_nf_old = dz_nf;
00207 
00208                 // Stress & strain update in Far Field element
00209                 double dz_far = (Tt - TFar_t)/TFar_tang;
00210                 TFar_z = TFar_z + dz_far;
00211                 getFarField(TFar_z);
00212 
00213                 // Residuals in Far Field element
00214                 double t_unbalance2 = Tt - TFar_t;
00215                 double zres_far = (Tt - TFar_t)/TFar_tang;
00216 
00217                 // Update the combined tangent modulus
00218                 Ttangent = pow(1.0/TNF_tang + 1.0/TFar_tang, -1.0);
00219 
00220                 // Residual deformation across combined element
00221                 double dv = Tz - (TNF_z + zres_nf) - (TFar_z + zres_far);
00222 
00223                 // Residual "t" increment 
00224                 dt = Ttangent * dv;
00225 
00226                 // Test for convergence
00227                 double tsum = fabs(t_unbalance) + fabs(t_unbalance2);
00228                 if(tsum/tult < TZtolerance) break;
00229         }
00230         }
00231 
00232         return 0;
00233 }
00235 double 
00236 TzSimple1::getStress(void)
00237 {
00238         // Dashpot force is only due to velocity in the far field.
00239         // If converged, proportion by Tangents.
00240         // If not converged, proportion by ratio of displacements in components.
00241         //
00242         double ratio_disp =(1.0/TFar_tang)/(1.0/TFar_tang + 1.0/TNF_tang);
00243         if(Tz != Cz) {
00244                 ratio_disp = (TFar_z - CFar_z)/(Tz - Cz);
00245                 if(ratio_disp > 1.0) ratio_disp = 1.0;
00246                 if(ratio_disp < 0.0) ratio_disp = 0.0;
00247         }
00248         double dashForce = dashpot * TzRate * ratio_disp;
00249 
00250         // Limit the combined force to tult.
00251         //
00252         if(fabs(Tt + dashForce) >= (1.0-TZtolerance)*tult)
00253                 return (1.0-TZtolerance)*tult*(Tt+dashForce)/fabs(Tt+dashForce);
00254         else return Tt + dashForce;
00255 }
00257 double 
00258 TzSimple1::getTangent(void)
00259 {
00260     return this->Ttangent;
00261 }
00263 double 
00264 TzSimple1::getInitialTangent(void)
00265 {
00266     return this->initialTangent;
00267 }
00269 double 
00270 TzSimple1::getDampTangent(void)
00271 {
00272         // Damping tangent is produced only by the far field component.
00273         // If converged, proportion by Tangents.
00274         // If not converged, proportion by ratio of displacements in components.
00275         //
00276         double ratio_disp =(1.0/TFar_tang)/(1.0/TFar_tang + 1.0/TNF_tang);
00277         if(Tz != Cz) {
00278                 ratio_disp = (TFar_z - CFar_z)/(Tz - Cz);
00279                 if(ratio_disp > 1.0) ratio_disp = 1.0;
00280                 if(ratio_disp < 0.0) ratio_disp = 0.0;
00281         }
00282 
00283         double DampTangent = dashpot * ratio_disp;
00284 
00285         // Minimum damping tangent referenced against Farfield spring
00286         //
00287         if(DampTangent < TFar_tang * 1.0e-12) DampTangent = TFar_tang * 1.0e-12;
00288 
00289         return DampTangent;
00290 }
00292 double 
00293 TzSimple1::getStrain(void)
00294 {
00295     return this->Tz;
00296 }
00298 double 
00299 TzSimple1::getStrainRate(void)
00300 {
00301     return this->TzRate;
00302 }
00304 int
00305 TzSimple1::commitState(void)
00306 {
00307   // Commit trial history variable -- Combined element
00308   Cz       = Tz;
00309   Ct       = Tt;
00310   Ctangent = Ttangent;
00311   
00312   // Commit trial history variables for Near Field component
00313   CNF_tin = TNF_tin;
00314   CNF_zin = TNF_zin;
00315   CNF_t   = TNF_t;
00316   CNF_z   = TNF_z;
00317   CNF_tang= TNF_tang;
00318   
00319   // Commit trial history variables for the Far Field
00320   CFar_z    = TFar_z;
00321   CFar_t    = TFar_t;
00322   CFar_tang = TFar_tang;
00323     
00324   return 0;
00325 }
00326 
00328 int 
00329 TzSimple1::revertToLastCommit(void)
00330 {
00331   // Nothing to do here -- WRONG -- have a look at setTrialStrain() .. everything
00332   // calculated based on trial values & trial values updated in method .. need to 
00333   // reset to committed values
00334   
00335   // for convenience i am just gonna do the reverse of commit
00336   Tz       = Cz;
00337   Tt       = Ct;
00338   Ttangent = Ctangent;
00339   
00340   TNF_tin = CNF_tin;
00341   TNF_zin = CNF_zin;
00342   TNF_t   = CNF_t;
00343   TNF_z   = CNF_z;
00344   TNF_tang= CNF_tang;
00345   
00346   TFar_z    = CFar_z;
00347   TFar_t    = CFar_t;
00348   TFar_tang = CFar_tang;
00349 
00350   return 0;
00351 }
00352 
00354 int 
00355 TzSimple1::revertToStart(void)
00356 {
00357 
00358         // If tzType = 0, then it is entering with the default constructor.
00359         // To avoid division by zero, set small nonzero values for terms.
00360         //
00361         if(tzType == 0){
00362                 tult = 1.0e-12;
00363                 z50  = 1.0e12;
00364         }
00365 
00366         // Only allow zero or positive dashpot values
00367         //
00368         if(dashpot < 0.0) dashpot = 0.0;
00369 
00370         // Do not allow zero or negative values for z50 or tult.
00371         //
00372         if(tult <= 0.0 || z50 <= 0.0){
00373                 opserr << "WARNING -- only accepts positive nonzero tult and z50" << endln;
00374                 opserr << "TzLiq1: " << endln;
00375                 opserr << "tzType: " << tzType << endln;
00376                 exit(-1);
00377         }
00378                 
00379         // Initialize variables for Near Field plastic component
00380         //
00381         if(tzType ==0) {                        // This will happen with default constructor
00382                 zref  = 0.5*z50;
00383                 np    = 1.5;
00384                 TFar_tang   = 0.70791*tult/(z50);
00385         }
00386         else if(tzType ==1) {           // Backbone approximates Reese & O'Neill 1987
00387                 zref  = 0.5*z50;
00388                 np    = 1.5;
00389                 TFar_tang       = 0.70791*tult/(z50);
00390         }
00391         else if (tzType == 2){          // Backbone approximates Mosher 1984
00392                 zref  = 0.6*z50;
00393                 np    = 0.85;
00394                 TFar_tang   = 2.0504*tult/z50;
00395         }
00396         else{
00397                 opserr << "WARNING -- only accepts tzType of 1 or 2" << endln;
00398                 opserr << "TzLiq1: " << endln;
00399                 opserr << "tzType: " << tzType << endln;
00400                 exit(-1);
00401         }
00402 
00403         // Far Field components: TFar_tang was set under "tzType" statements.
00404         //
00405         TFar_t  = 0.0;
00406         TFar_z  = 0.0;
00407 
00408         // Near Field components
00409         //
00410         TNF_tin = 0.0;
00411         TNF_zin = 0.0;
00412         TNF_t   = 0.0;
00413         TNF_z   = 0.0;
00414         TNF_tang= np*tult*pow(zref,np)*pow(zref,-np-1.0);
00415 
00416         // Entire element (Far field + Near field + Gap in series)
00417         //
00418         Tz       = 0.0;
00419         Tt       = 0.0;
00420         Ttangent = pow(1.0/TNF_tang + 1.0/TFar_tang, -1.0);
00421         TzRate   = 0.0;
00422 
00423         // Now get all the committed variables initiated
00424         //
00425         this->commitState();
00426 
00427     return 0;
00428 }
00429 
00431 UniaxialMaterial *
00432 TzSimple1::getCopy(void)
00433 {
00434     TzSimple1 *theCopy;                 // pointer to a TzSimple1 class
00435         theCopy = new TzSimple1();      // new instance of this class
00436         *theCopy= *this;                        // theCopy (dereferenced) = this (dereferenced pointer)
00437         return theCopy;
00438 }
00439 
00441 int 
00442 TzSimple1::sendSelf(int cTag, Channel &theChannel)
00443 {
00444         int res = 0;
00445   
00446         static Vector data(20);
00447   
00448         data(0) = this->getTag();
00449         data(1) = tzType;
00450         data(2) = tult;
00451         data(3) = z50;
00452         data(4) = dashpot;
00453         data(5) = zref;
00454         data(6) = np;
00455 
00456         data(7)  = CNF_tin;
00457         data(8)  = CNF_zin;
00458         data(9)  = CNF_t;
00459         data(10) = CNF_z;
00460         data(11) = CNF_tang;
00461 
00462         data(12) = CFar_z;
00463         data(13) = CFar_t;
00464         data(14) = CFar_tang;
00465 
00466         data(15) = Cz;
00467         data(16) = Ct;
00468         data(17) = Ctangent;
00469         data(18) = TzRate;
00470 
00471         data(19) = initialTangent;
00472 
00473         res = theChannel.sendVector(this->getDbTag(), cTag, data);
00474         if (res < 0) 
00475                 opserr << "TzSimple1::sendSelf() - failed to send data\n";
00476 
00477         return res;
00478 }
00479 
00481 int 
00482 TzSimple1::recvSelf(int cTag, Channel &theChannel, 
00483                                FEM_ObjectBroker &theBroker)
00484 {
00485   int res = 0;
00486   
00487   static Vector data(20);
00488   res = theChannel.recvVector(this->getDbTag(), cTag, data);
00489   
00490   if (res < 0) {
00491       opserr << "TzSimple1::recvSelf() - failed to receive data\n";
00492       this->setTag(0);      
00493   }
00494   else {
00495     this->setTag((int)data(0));
00496         tzType = (int)data(1);
00497         tult     = data(2);
00498         z50      = data(3);
00499         dashpot  = data(4);
00500         zref     = data(5);
00501         np       = data(6);
00502         
00503         CNF_tin  = data(7);
00504     CNF_zin      = data(8);
00505         CNF_t    = data(9);
00506         CNF_z    = data(10);
00507         CNF_tang = data(11);
00508 
00509         CFar_z    = data(12);
00510         CFar_t    = data(13);
00511         CFar_tang = data(14);
00512 
00513         Cz        = data(15);
00514         Ct        = data(16);
00515         Ctangent  = data(17);
00516         TzRate    = data(18);
00517         
00518         initialTangent = data(19);
00519         
00520         this->revertToLastCommit();
00521   }
00522     
00523   return res;
00524 }
00525 
00527 void 
00528 TzSimple1::Print(OPS_Stream &s, int flag)
00529 {
00530     s << "TzSimple1, tag: " << this->getTag() << endln;
00531     s << "  tzType: " << tzType << endln;
00532     s << "  tult: " << tult << endln;
00533     s << "  z50: " << z50 << endln;
00534     s << "  dashpot: " << dashpot << endln;
00535 }
00536 
00538 

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