InelasticYS2DGNL.cpp

Go to the documentation of this file.
00001 // InelasticYS2DGNL.cpp
00003 
00004 #include <Domain.h>
00005 #include <Channel.h>
00006 #include <FEM_ObjectBroker.h>
00007 //#include <Renderer.h>
00008 #include <math.h>
00009 #include <stdlib.h>
00010 
00011 #ifdef _NOGRAPHICS
00012 
00013 #else
00014 #ifdef _GLX    // Boris Jeremic added 23Oct2002
00015 #include <OpenGLRenderer.h>
00016 #endif         // Boris Jeremic added 23Oct2002
00017 #endif
00018 
00019 #include "InelasticYS2DGNL.h"
00020 #include <Renderer.h>
00021 //#include <WindowManager.h>
00022 #include <PlainMap.h>
00023 #include <Information.h>
00024 #include <ElementResponse.h>
00025 #include <string.h>
00026 //#define debug  1
00027 //#define fdebug 1
00028 //#define pdebug 1
00029 #define updateDebug 0
00030 #define plastkDebug 0
00031 
00032 #define ERROR 1e-8
00033 #define TAG_InelasticYS2DGNL -1
00034 
00035 // Vector InelasticYS2DGNL::trialForce(6);
00036 Vector InelasticYS2DGNL::elasticForce(6);
00037 Vector InelasticYS2DGNL::F1(6);
00038 Vector InelasticYS2DGNL::F2(6);
00039 Vector InelasticYS2DGNL::Fs(6);
00040 double InelasticYS2DGNL::storage(0);
00041 
00042 const int InelasticYS2DGNL::INSIDE(-1);
00043 const int InelasticYS2DGNL::WITHIN(0);
00044 const int InelasticYS2DGNL::OUTSIDE(1);
00045 
00047 // Construction/Destruction
00049 
00050 // Element specific to PM interaction only
00051 InelasticYS2DGNL::InelasticYS2DGNL(int tag, // double a, double e, double i,
00052                                    int Nd1, int Nd2,
00053                                    YieldSurface_BC *ysEnd1,
00054                                    YieldSurface_BC *ysEnd2,
00055                                    int rf_algo, bool islinear, double rho)
00056   :UpdatedLagrangianBeam2D(tag, TAG_InelasticYS2DGNL, Nd1, Nd2, islinear),
00057    end1G(6,1), end2G(6,1), Stiff(6,6),
00058    forceRecoveryAlgo(rf_algo), forceRecoveryAlgo_orig(rf_algo),
00059    end1Damage(false), end2Damage(false), split_step(false)
00060 {
00061   
00062   {
00063     debug  = 0;
00064     fdebug = 0;
00065     pdebug = 0;
00066     ydebug = 0;
00067     statusDebug = 0;
00068   }
00069   
00070   
00071   
00072   if(ysEnd1==0) {
00073       opserr << "WARNING - InelasticYS2DGNL(): ys1 = 0" << endln;
00074   } else {
00075     ys1 =  ysEnd1->getCopy();
00076     ys1->setTransformation(2, 0, -1,  1);
00077     ys1->setEleInfo(getTag(), 1);
00078     // Hogging moment at end1 => Negative moment
00079     // Positive disp at node 1 (compression) => Positive axial force
00080   }
00081   
00082   if(ysEnd2==0) {
00083       opserr << "WARNING - InelasticYS2DGNL(): ys2 = 0" << endln;
00084   } else {
00085     
00086     ys2 =  ysEnd2->getCopy();
00087     ys2->setTransformation(5, 3, 1, -1);
00088     ys2->setEleInfo(getTag(), 2);
00089                 // Sagging moment at end2 positive => Positive moment
00090     // Positive disp at node 2 (tension) => Negative axial force
00091   }
00092   
00093   pView = 0;
00094   end1Plastify = false;
00095   end2Plastify = false;
00096   end1Plastify_hist = false;
00097   end2Plastify_hist = false;
00098   
00099   init = false;
00100 }
00101 
00102 
00103 InelasticYS2DGNL::~InelasticYS2DGNL()
00104 {
00105   //~ if(theMap != NULL)
00106         //~ delete theMap;
00107 }
00108 
00109 // do everything here
00110 int InelasticYS2DGNL::update()
00111 {
00112     if (L == 0)
00113             return 0;
00114 
00115         ys1->update();
00116         ys2->update();          
00117                         
00118 //      split_step = false;
00119 
00121 // Step 1: Trial Elastic Forces
00123 
00124          // Get the local elastic stiffness matrix, store in Stiff
00125      getLocalStiff(Stiff);
00126 
00127      // Add internal geometric stiffness matrix
00128      addInternalGeomStiff(Stiff);
00129 
00130      // Get incremental local displacements  trial-conv.
00131      getIncrNaturalDisp(disp);
00132          //getIncrLocalDisp(disp);   IMPORTANT - Do not change!!
00133 
00134      // Compute local incremental force
00135      force = Stiff*disp;
00136 
00137 Vector trial_force(6);
00138 
00139      // Compute total trial local force - store in trialForce
00140      trial_force = eleForce_hist + force;        
00141          computeTrueEleForce(trial_force);
00142          checkSpecialCases();
00143          return 0;
00144 }
00145 
00146 
00147 int InelasticYS2DGNL::computeTrueEleForce(Vector &trialForce)
00148 {
00149          // ys1->displayForcePoint(trialForce);
00150          // opserr << "\a";
00151 
00152          // opserr << "Trial Force = " << trialForce; opserr << "\a";
00153 
00155 // Step 2: Check and plastify ends if required
00157         // if(forceRecoveryAlgo == -1)
00158         {
00159                 int plastify = this->plasticPredictor(trialForce);
00160                 if(!plastify) // did not plastify
00161                         return 0;
00162         }
00163         /*else
00164         {
00165                 int plastify = this->elasticCorrector(trialForce); // needs debugging
00166                 if(!plastify) // did not plastify
00167                         return 0;
00168         }*/
00169 
00171 // Step 3: Drift control
00173 
00174     if(end1Plastify)
00175     {
00176 
00177         int d1 = ys1->getTrialForceLocation(eleForce);
00178         if(d1 == OUTSIDE)
00179                 {
00180                 ys1->setToSurface(eleForce, ys1->RadialReturn);
00181                 //cout <<" ys1 outside\n";
00182                 }
00183         else
00184                 {
00185             ys1->setToSurface(eleForce, ys1->ConstantYReturn);
00186                 //cout << "ys1 inside \n";
00187                 }
00188     }
00189 
00190     if(end2Plastify)
00191     {
00192         int d2 = ys2->getTrialForceLocation(eleForce);
00193         if(d2 == OUTSIDE)
00194                 {
00195                 ys2->setToSurface(eleForce, ys2->RadialReturn);
00196                 //cout << "ys2 outside\n";
00197                 }
00198         else
00199                 {
00200                 ys2->setToSurface(eleForce, ys2->ConstantYReturn);
00201                 //cout << "ys2 inside\n";
00202                 }
00203     }
00204 
00206 // Step 4: Force Balance  first Axial, then Shear - still have to do dF for elastic case
00208     forceBalance(eleForce, 1);
00209 
00210     /*if(
00211         (eleForce(0) > 0 && eleForce_hist(0) < 0) ||
00212         (eleForce(0) < 0 && eleForce_hist(0) > 0)
00213       )
00214     {
00215         opserr << "NOTE: Axial force sign changed from converged state\n";
00216      // nothing can be done about that
00217 //      eleForce(0) =  eleForce_hist(0);
00218 //      eleForce(3) =  eleForce_hist(3);
00219     }*/
00220         return 0;
00221 }
00222 
00223 void InelasticYS2DGNL::checkSpecialCases(void)
00224 {
00225         if(fabs(eleForce(0)) < ERROR && fabs(eleForce(3)) < ERROR)
00226         {
00227                 eleForce(0) = 0.0;
00228                 eleForce(3) = 0.0;
00229                 return;
00230         }
00231     // check if the 2 force-points are on the same side in YS    
00232     if(sign(eleForce(0)) == sign(eleForce(3))) // special case
00233     {
00234                 opserr << "oops 1: element " << getTag() << " okay \n";
00235                 opserr << eleForce;
00236                 // ys is already evolved
00237                 
00238                 // Stiff = Kt now
00239                 // getLocalStiff(Stiff);
00240                 // addInternalGeomStiff(Stiff);
00241                 getIncrNaturalDisp(disp);
00242                 force = Stiff*disp;
00243                 eleForce = eleForce_hist + force;
00244                 // elasticCorrector(trialForce, ys1->ConstantYReturn); - untested
00245                 // trial force vector is stored in eleForce
00246                 bool end1Drifts, end2Drifts;
00247                 this->checkEndStatus(end1Drifts, end2Drifts, eleForce);
00248                 // Have to use constantY only
00249         if(end1Plastify)
00250                         ys1->setToSurface(eleForce, ys1->ConstantYReturn);
00251         if(end2Plastify)
00252                         ys2->setToSurface(eleForce, ys2->ConstantYReturn);
00253                 
00254         // the two P's should be same now, so Pavg should be = P's
00255         forceBalance(eleForce, 1); // shear
00256         if(sign(eleForce(0)) == sign(eleForce(3)))
00257         {
00258                         opserr << "oops 2: element " << getTag() << " not okay \n";
00259                         opserr << eleForce;
00260                 }
00261         }
00262 
00263         if(updateDebug)
00264         {
00265         if(pView)
00266                 {
00267                 pView->clearImage();
00268                 pView->startImage();
00269                 ys1->displaySelf(*pView, 1, 1);
00270                 ys1->displayForcePoint(eleForce, 2);
00271                 
00272                 ys2->displaySelf(*pView, 1, 1);
00273 
00274                 ys2->displayForcePoint(eleForce, 2);
00275                 
00276                 pView->doneImage();
00277                 opserr << "Trial Force points plotted \n";
00278                 opserr << "\a";
00279                 }
00280         }
00281                         
00282 }
00283 // update
00284 
00285 // no longer valid
00286 int InelasticYS2DGNL::elasticCorrector(Vector &trialForce, int algo)
00287 {
00288 bool    end1Drifts, end2Drifts;
00289 
00290         this->checkEndStatus(end1Drifts, end2Drifts, trialForce);
00291 
00292         if(!end1Plastify && !end2Plastify) // still elastic
00293         {
00294                 // opserr << "InelasticYS2DGNL::elasticCorrector - Trial Force Elastic" << endln;
00295                 eleForce = trialForce;
00296                 return 0;
00297         }
00298         
00299         // if any end shoot through, force point is retracted
00300         // else if they drift, lamda is computed and the
00301         // surface modified, force point is retracted back to
00302         // the surface using the forceRecoveryAlgo
00303 
00304         if(end1Plastify)
00305         {
00306                 this->plastifyOneEnd(1, ys1, trialForce, disp, Stiff, eleForce, algo);
00307         }
00308 
00309     if(end2Plastify)
00310         {
00311                 this->plastifyOneEnd(2, ys2, trialForce, disp, Stiff, eleForce, algo);
00312         }
00313 
00314         return 1;
00315 }
00316 
00317 
00318 int InelasticYS2DGNL::plasticPredictor(Vector &trialForce)
00319 {
00320 
00321 bool    end1Drifts, end2Drifts;
00322 Vector totalForce(6);
00323 
00324         this->checkEndStatus(end1Drifts, end2Drifts, trialForce);
00325                 
00326         if(end1Plastify && !end2Plastify)
00327         {
00328                 // this updates both Kt and F
00329                 this->plastifyOneEnd(1, ys1, trialForce, disp, Stiff, eleForce, -1);
00330         }
00331         else if(end2Plastify && !end1Plastify)
00332         {
00333                 // this updates both Kt and F
00334                 this->plastifyOneEnd(2, ys2, trialForce, disp, Stiff, eleForce, -1);
00335         }
00336         else if(end1Plastify && end2Plastify)
00337         {
00338                 // opserr << "drift status both plastify = " << end1Drifts << " " << end2Drifts << endln; opserr << "\a";
00339         
00340            if( (end1Drifts && !end2Drifts))
00341         {               
00342                 this->splitStep(2, ys2, ys1, trialForce, Stiff, eleForce);
00343         }
00344             else if ((end2Drifts && !end1Drifts))
00345             {                   
00346                  this->splitStep(1, ys1, ys2, trialForce, Stiff, eleForce);
00347             }
00348          else
00349                         this->plastifyBothEnds(trialForce, disp, Stiff, eleForce);
00350 
00351 //         if( (end1Drifts && !end2Drifts) || (end2Drifts && !end1Drifts))
00352 //      {               
00353 //              this->elasticCorrector(trialForce, -10);
00354 //      }
00355 //          else
00356 //                      this->plastifyBothEnds(trialForce, disp, Stiff, eleForce);
00357                         
00358                                         
00359                 /* if(!end1Drifts && !end2Drifts)
00360                 {
00361                         // order does not matter,
00362                         // only the force point is retracted
00363                         this->plastifyOneEnd(1, ys1, trialForce, disp, Stiff, eleForce, -1);
00364                         this->plastifyOneEnd(2, ys2, trialForce, disp, Stiff, eleForce, -1);
00365                 }
00366                 else if(end1Drifts && !end2Drifts)
00367                 {
00368                         // end that drifts modifies Kt and F
00369                         // then call the end that shoots through -
00370                         // retracts the force point - order matters
00371                         this->plastifyOneEnd(1, ys1, trialForce, disp, Stiff, eleForce, -1);
00372                         this->plastifyOneEnd(2, ys2, trialForce, disp, Stiff, eleForce, -1);
00373                 }
00374                 else if(end2Drifts && !end1Drifts)
00375 
00376                 {
00377                         // end that drifts modifies Kt and F
00378                         // then call the end that shoots through -
00379                         // retracts the force point - order matters
00380                         this->plastifyOneEnd(2, ys2, trialForce, disp, Stiff, eleForce, -1);
00381                         this->plastifyOneEnd(1, ys1, trialForce, disp, Stiff, eleForce, -1);
00382                 }
00383                 else if(end1Drifts && end2Drifts)
00384                 {
00385                         this->plastifyBothEnds(trialForce, disp, Stiff, eleForce);
00386                 }
00387                 else
00388                 {
00389                         opserr << "InelasticYS2DGNL::predictor() - This condition should not happen\n";
00390                         opserr << "\a";
00391                 } */
00392                 
00393         }
00394         else
00395         {
00396                 if(!end1Plastify && !end2Plastify)
00397                 {
00398                         // both ends elastic
00399                         eleForce = trialForce;
00400                         return 0;
00401                 }
00402                 else
00403                 {
00404                         opserr << "InelasticYS2DGNL::predictor() - didn't think of this condition\n";
00405 
00406                         opserr << "\a";
00407                 }
00408         }
00409         
00410         // opserr << "RETURNING FROM PLASTIC PREDICTOR \n"; opserr << "\a";
00411         
00412         return 1;
00413 }
00414 
00415 
00416 // if an end plastifies, it can either shoot through or drift
00417 
00418 void InelasticYS2DGNL::checkEndStatus(bool &end1drifts, bool &end2drifts, Vector &trialForce)
00419 {
00420 int driftOld;
00421 
00422         end1Plastify = false;
00423         end2Plastify = false;
00424 
00425         // check the status for end1
00426         int d1 = ys1->getTrialForceLocation(trialForce);
00427     if(d1 != INSIDE)
00428     {
00429         end1Plastify = true;
00430         
00431         driftOld = ys1->getCommitForceLocation();
00432         if(driftOld == INSIDE)
00433                 {
00434                         end1drifts = false;
00435                         if(statusDebug)
00436                                 opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 1 shoots through\n";
00437                 }
00438                 else if(driftOld == WITHIN)
00439                 {
00440                         // in this case if the current point is within or
00441                 // outside, eiher way, force point is taken as
00442                 // drifted
00443                         end1drifts = true;
00444                         if(statusDebug)
00445                                 opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 1 drifts\n";
00446                         
00447                 }
00448                 else
00449                 {
00450                         opserr << "WARNING - checkEndStatus end1 force_hist outside ["<<getTag()<<"]\n";
00451                         //cin.get();
00452                         //ys1->setToSurface(eleForce, ys1->ConstantYReturn);
00453                 }
00454     }
00455     else
00456     {
00457         if(statusDebug)
00458         {
00459                 driftOld = ys1->getCommitForceLocation();
00460                 if(driftOld != INSIDE)
00461                 {
00462                         double drift = ys1->getTrialDrift(trialForce);
00463                         opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 1 unloading "<<drift<<" \n";
00464                         // opserr << "\a";
00465                 }
00466                 else
00467                         opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 1 remains elastic\n";
00468         }
00469     }
00470 
00471     // check the status for end2
00472         int d2 = ys2->getTrialForceLocation(trialForce);
00473     if(d2 != INSIDE)
00474     {
00475         end2Plastify = true;
00476         
00477         driftOld = ys2->getCommitForceLocation();
00478         if(driftOld == INSIDE)
00479                 {
00480                         end2drifts = false;
00481 
00482                         if(statusDebug)
00483                                 opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 2 shoots through\n";
00484                 }
00485                 else if(driftOld == WITHIN)
00486                 {
00487                         end2drifts = true;
00488                         if(statusDebug)
00489                                 opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 2 drifts\n";
00490                 }
00491                 else
00492                 {
00493 
00494 
00495                         opserr << "WARNING - checkEndStatus end2 force_hist outside ["<<getTag()<<"]\n";
00496 
00497                         // opserr << "\a";
00498                         // this condition could happen due to force balance at
00499                         // privous step
00500 
00501 
00502                 }
00503     }
00504     else
00505     {
00506         if(statusDebug)
00507         {
00508                 driftOld = ys2->getCommitForceLocation();
00509                 if(driftOld != INSIDE)
00510                 {
00511                         double drift = ys2->getTrialDrift(trialForce);
00512                         opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 2 unloading "<<drift<<"\a \n";
00513                         //cin.get();
00514                 }
00515                 else
00516                         opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 2 remains elastic\n";
00517 
00518         }
00519     }
00520 
00521 //    if(statusDebug)
00522 //      opserr << "\a";
00523 }
00524 
00525 
00526 void InelasticYS2DGNL::forceBalance(Vector &eleforce, int algo)
00527 {
00528     int sign1 = 1, sign2 = 1;
00529         if(eleforce(0) <0) sign1 = -1;
00530         if(eleforce(3) <0) sign2 = -1;
00531         double Pavg = (fabs(eleforce(0)) + fabs(eleforce(3)))/2;
00532 
00533         double Pmin = min_(fabs(eleforce(0)), fabs(eleforce(3)));
00534         double Pmax = max_(fabs(eleforce(0)), fabs(eleforce(3)));
00535 
00536     switch (algo)
00537         {
00538                 case 1: // use Pavg
00539                 {
00540                         eleforce(0) = Pavg*sign1;
00541                         eleforce(3) = Pavg*sign2;
00542                         break;
00543                 }
00544                 case 2: // use Pmin
00545                 {
00546                         eleforce(0) = Pmin*sign1;
00547                         eleforce(3) = Pmin*sign2;
00548                         break;
00549                 }
00550 
00551                 case 3: // use Pmax
00552                 {
00553                         eleforce(0) = Pmax*sign1;
00554                         eleforce(3) = Pmax*sign2;
00555                         break;
00556                 }
00557                 default:
00558                         opserr << "InelasticYS2DGNL::forceBalance - unkown algo\n";
00559                         break;
00560         }
00561 
00562 
00563         if(end1Plastify)
00564         {
00565                 ys1->setToSurface(eleforce, ys1->ConstantYReturn);
00566 
00567         }
00568 
00569         if(end2Plastify)
00570         {
00571                 ys2->setToSurface(eleforce, ys2->ConstantYReturn);
00572 
00573         }
00574 
00575 
00576         // shear force balance
00577     eleforce(1) = (eleforce(2) + eleforce(5))/L;
00578         eleforce(4) = -eleforce(1);
00579 
00580 
00581 }
00582 
00583 const Matrix &InelasticYS2DGNL::getTangentStiff(void)
00584 {
00585         // opserr << " getTangentStiff Called \n";
00586 
00587         if(!init)
00588         {
00589                 this->update();
00590                 init = true;
00591         }
00592 
00593 //      if(forceRecoveryAlgo != -1) // do not use Kt
00594 //              return this->Element2D02::getTangentStiff();
00595         
00596         transformToGlobal(Stiff);
00597         
00598 //      opserr << "Kt = " << Stiff;
00599         
00600         return Stiff;
00601 }
00602 
00603 
00604 
00605 const Vector &InelasticYS2DGNL::getResistingForce(void)
00606 {
00607         // opserr << "getResistingForce Called \n";
00608 
00609         if(!init)
00610         {
00611                 //~ eleForce.Zero();
00612                 this->update();
00613                 init = true;
00614         }
00615     // check for quick return
00616     if (L == 0)
00617             return ZeroVector;
00618         m_Iter++;
00619 
00620         // untested code !!
00621         bool needBal = false;
00622     if(ys1->hModel->freezeEvolution)
00623     {
00624                 needBal = true;
00625                 for(int i=0; i<3; i++)
00626                         eleForce(i) = eleForce_hist(i);
00627         }
00628     if(ys2->hModel->freezeEvolution)
00629     {
00630                 needBal = true;
00631                 for(int i=3; i<6; i++)
00632                         eleForce(i) = eleForce_hist(i);
00633         }
00634         if(needBal)
00635                 this->forceBalance(eleForce, 1);
00636         
00637         // determine the ele end forces in global coords - want -F into rForce
00638     force(0) =  cs*eleForce(0) - sn*eleForce(1);
00639     force(1) =  sn*eleForce(0) + cs*eleForce(1);
00640     force(2) =  eleForce(2);
00641     force(3) =  cs*eleForce(3) - sn*eleForce(4);
00642     force(4) =  sn*eleForce(3) + cs*eleForce(4);
00643     force(5) =  eleForce(5);
00644 
00645     if(pdebug)
00646     {
00647         opserr << "Returning Force \n";
00648         opserr << force;
00649     }
00650 
00651     storage = 0;
00652     if(getTag()==1 || getTag() ==3)
00653     {
00654         // opserr << "EleForce - global [" << getTag() << "]\n";
00655 
00656         // for(int i = 0; i<6; i++)
00657 
00658         // opserr << force[2] << " ";
00659         storage += force[2];
00660         //cerr << "\n";
00661     }
00662 
00663    // opserr << m_Iter << " RF = " << force; //cin.get();
00664 //    if(getTag()==3)
00665 //      opserr << "\n" << storage;
00666         return force;
00667 }
00668 
00669 
00670 
00671 
00672 void InelasticYS2DGNL::plastifyOneEnd(int end, YieldSurface_BC *ys,  Vector &trial_force,
00673                                                                 Vector &incrDisp, Matrix &K, Vector &total_force, int algo)
00674 {
00675 
00676 // only one end is plastifying
00677 // need to calculate lambda = G'Ke d(Del)_in / G'(Ke+Kp)G
00678 //                          = G' dF_in / G'(Ke+Kp)G
00679 // F_trial ( = F_hist + dF_in ) is outside the surface
00680 // set F_trial to surface (modify dF_in)
00681 // no need to re-balance the axial force or shear
00682 // for 1 end plastifying G' is such that the numerator is uncoupled from
00683 // the other end
00684 
00685         // opserr << "InelasticYS2DGNL::plastifyOneEnd " << endln;
00686         if(plastkDebug)
00687                 opserr << "----------------------------------------------------------------------"
00688                      << endln;
00689 
00690 Vector trialForce(6);
00691         // copy trial_force so that it does not get modified
00692         trialForce =  trial_force;
00693 
00694 Vector surfaceForce(6);
00695 Matrix G(6,1);
00696 bool use_Kr = true;
00697 
00698 // case: if it shoots through
00699 //         use dF return to surface
00700 
00701         // driftnew is either outside or within (that's why plastify end was called)
00702 
00703         // either case, if previous point was elastic, implies a partly elastic load step
00704         // and remaining inelastic
00705         int driftOld = ys->getCommitForceLocation();
00706 
00707         if(driftOld == INSIDE)
00708         {
00709                 use_Kr = false;         
00710                 surfaceForce = trialForce;
00711 
00712 
00713 
00714 
00715                 ys->setToSurface(surfaceForce, ys->RadialReturn);  //dFReturn, ConstantYReturn, RadialReturn
00716                 // this part can get crazy!!
00717                 // opserr << "    -------------- HERE? ------------ \n";
00718                 // opserr << "surface drift = " << ys->getTrialDrift(surfaceForce) << endln; opserr << "\a";
00719 
00720                 ys->getTrialGradient(G, surfaceForce);
00721 
00722                 if(plastkDebug)
00723                 {
00724                         opserr << "Element (" << getTag() << ") plastifyEnd shoots through end: " << end << "\n";
00725                 }
00726         }
00727         // Now we know that force point has drifted from the surface
00728         else if(driftOld != WITHIN)
00729         {
00730                 opserr << "WARNING: InelasticYS2DGNL::plastifyOneEnd = " << end << " - driftOld outside [" << getTag()<<"]\n";
00731                 opserr << "\a";
00732         }
00733         else
00734         {
00735                 ys->getCommitGradient(G);
00736                 surfaceForce =  eleForce_hist;
00737 
00738                 if(plastkDebug)
00739                         opserr << "Element (" << getTag() << ") plastifyEnd (" << end << ") drifts from surface\n";
00740         }
00741 
00742         /*if(driftOld==INSIDE)
00743         {
00744                 surfaceForce = trial_force;
00745                 ys->setToSurface(surfaceForce, ys->RadialReturn);
00746                 total_force = surfaceForce;
00747                 //cout << "returning surface force\n"; opserr << "\a";
00748                 return;
00749         }*/
00750 
00751         
00752 Vector dF_in(6);
00753         dF_in = trialForce - surfaceForce;
00754         
00755 Matrix Ktp(6,6); //Ke(6,6); // want to leave 'K' unmodified for now
00756 
00757         int drift_test = ys->getTrialForceLocation(surfaceForce);
00758 //      opserr << " force_hist = " << eleForce_hist;
00759 //      opserr << " drift_test = " << drift_test << endln;
00760 
00761         Ktp = K; //includes Ke + Kg
00762         ys->addPlasticStiffness(Ktp);
00763 
00764 
00765         Matrix KI = G^(Ktp*G);
00766 
00767         double inv = 1/KI(0,0);
00768 
00769         Vector Lm = G^(dF_in);
00770 
00771         Lm = Lm*inv;
00772         double lamda = Lm(0);
00773         if(fabs(lamda) < ERROR) lamda = 0.0; // to get rid of -1e-15 etc
00774 
00775         if(lamda < 0)
00776         {
00777                 //cout << "lamda = " << lamda << endln;
00778                 //cin.get();
00779                 use_Kr = false;
00780                 lamda = 0.0;
00781         }
00782 
00783         Vector delP(6);
00784         delP(0) = G(0,0);
00785         delP(1) = G(1,0);
00786 
00787         delP(2) = G(2,0);
00788         delP(3) = G(3,0);
00789         delP(4) = G(4,0);
00790         delP(5) = G(5,0);
00791         
00792         delP = delP*lamda;      
00793 int grow;
00794         if(algo != 20)  
00795                 grow = ys->modifySurface(lamda, surfaceForce, G);
00796         else
00797         {
00798                 grow = ys->modifySurface(lamda, surfaceForce, G, 1);
00799                 use_Kr = false;
00800         }
00801 
00802         if(grow < 0)
00803                 forceRecoveryAlgo = ys->ConstantYReturn;
00804         else
00805                 forceRecoveryAlgo = forceRecoveryAlgo_orig;
00806 
00807 Vector dF_t(6);
00808         dF_t = dF_in - K*delP;
00809 
00810         if(split_step)
00811                 total_force = surfaceForce + dF_t; //otherwise convergence problem
00812         else
00813                 total_force = surfaceForce + dF_in; // faster convergence
00814         
00815 
00816         // ys->displayForcePoint(total_force, 3);
00817 
00818         if(plastkDebug)
00819     {
00820                 opserr << " InelasticYS2DGNL::plastifyOneEnd - tag = " << getTag() << "\n";
00821 
00822         opserr << "lamda = " << lamda << "\n";
00823         opserr << " G = " << G << endln;
00824         opserr << "delP = " << delP <<endln;
00825                 // opserr << "\a";
00826     }
00827         
00828         // now we update the stiffness
00829         if(algo == -10) 
00830                 use_Kr = false;
00831 
00832         if(split_step)
00833                 use_Kr = false; 
00834                 
00835         // opserr << "Plastify One End, not using Kr\n";
00836                 
00837         if(use_Kr)
00838         {
00839         Matrix Kr(6,6);
00840                 Kr = K*G*(G^K)*inv;
00841                 Stiff = Stiff - Kr;
00842                 
00843                 // F1 = (Stiff)*incrDisp + surfaceForce;
00844                 // ys->displayForcePoint(F1, 3); 
00845                 // opserr << "\a";
00846         }
00847         // else
00848         //       opserr << "NOT USING Kr " << endln;
00849 
00850 }
00851 
00852 
00853 void InelasticYS2DGNL::splitStep(int end_shoot, YieldSurface_BC *ys_shoots, YieldSurface_BC *ys_drifts,
00854                        Vector &trial_force, Matrix &K, Vector &total_force)
00855 {
00856 // first we need to find a factor by which to split the step
00857 
00858 //      opserr << " InelasticYS2DGNL::splitStep(" << end_shoot << ")\n"; // opserr << "\a";
00859         
00860         split_step = true;
00861         
00862 Vector F1(6);
00863         F1 =  trial_force;
00864         ys_shoots->setToSurface(F1, ys1->dFReturn);
00865         
00866         // opserr << "trial force location " << ys_shoots->getTrialForceLocation(F1) << endln; opserr << "\a";
00867         
00868 int Pi = 0, Mi = 2;
00869 int p_shoot = 0, m_shoot = 2;
00870 int p_drift = 3, m_drift = 5;
00871 
00872         if(end_shoot==2)
00873         {
00874                 Pi = 3;  p_shoot = 3; p_drift = 0;
00875                 Mi = 5;  m_shoot = 5; m_drift = 2;
00876         }
00877                 
00878         double num = pow((F1(Pi) - eleForce_hist(Pi)),2)
00879                                  + pow((F1(Mi) - eleForce_hist(Mi)),2);
00880                                         
00881         num = sqrt(num);
00882                 
00883         double denom = pow((trial_force(Pi) - eleForce_hist(Pi)),2)
00884                                  + pow((trial_force(Mi) - eleForce_hist(Mi)),2);
00885         
00886         denom = sqrt(denom);
00887 
00888 double t= num/denom;
00889 
00890 // now drift the other end by the same amount
00891         Vector trialForce2(6), step_force(6);
00892         
00893         
00894         
00895         //cout << "Splitting step by - " << t << endl ;
00896         //cout << "Original trial force = " << trial_force;
00897         trialForce2 = eleForce_hist + t*(trial_force - eleForce_hist);
00898         //cout << "Drift one end by trial force = " <<  trialForce2;
00899         
00900 Vector f_surface = eleForce_hist;
00901 int count =0;
00902         // while(1)
00903         {
00904         this->driftOneEnd(ys_drifts, trialForce2, f_surface, K, step_force);
00905         
00906 
00907         this->forceBalance(step_force, 1);      
00908         // opserr << "After force balance, force = " << step_force;     
00909         // opserr << "Drift both ends, trialForce = " <<  trial_force
00910         // << "surface force = " << step_force;
00911         
00912         /* Vector df =   trial_force - step_force;
00913         // opserr << "df = " << df;
00914         
00915         double ratio =  fabs(df(m_shoot)/df(m_drift));
00916         // opserr << "ratio = " << ratio << endln; // opserr << "\a";
00917         
00918         if(ratio > 0.75)
00919                 break;
00920         count++;
00921         
00922         if(count > 100)
00923         {
00924                 opserr << "WARNING: InelasticYS2DGNL::splitStep - artificial hardening not converging\n";
00925                 break;
00926         }
00927         
00928         f_surface = step_force;   */
00929         }
00930         
00931 //      opserr << "Count = " << count << endln; // opserr << "\a";
00932 // now drift both ends by the remainder amount  
00933         
00934         trialForce2 = step_force + (1-t)*(trial_force - eleForce_hist);
00935         
00936         if(ys1->getTrialForceLocation(trialForce2) <0)
00937                 opserr << "oops - 1\n";
00938         if(ys2->getTrialForceLocation(trialForce2) <0)
00939                 opserr << "oops - 2\n"; 
00940         
00941         // check the status first!
00942 //      this->driftBothEnds(trialForce2, step_force, K, total_force);
00943         this->driftBothEnds(trialForce2, step_force, K, eleForce);      
00944 
00945 }// split step  
00946 
00947 
00948 void InelasticYS2DGNL::driftOneEnd(YieldSurface_BC *ys, Vector &trialForce, Vector &surfaceForce,
00949                                          Matrix &K, Vector &total_force)
00950 {
00951         
00952 Matrix G(6,1);  
00954         // ys->setToSurface(surfaceForce, ys->ConstantYReturn);
00955         ys->getTrialGradient(G, surfaceForce);  
00956         
00957 Vector dF_in(6);
00958         dF_in = trialForce - surfaceForce;
00959         
00960 Matrix Ktp(6,6); 
00961         
00962         Ktp = K; //includes Ke + Kg
00963         ys->addPlasticStiffness(Ktp);
00964 
00965         Matrix KI = G^(Ktp*G);
00966 
00967         double inv = 1/KI(0,0);
00968 
00969         Vector Lm = G^(dF_in);
00970 
00971         Lm = Lm*inv;
00972         double lamda = Lm(0);
00973         if(fabs(lamda) < ERROR) lamda = 0.0; // to get rid of -1e-15 etc
00974 
00975         if(lamda < 0)
00976         {
00977                 //cout << "lamda = " << lamda << endln;
00978                 //cin.get();
00979 
00980                 lamda = 0.0;
00981         }
00982 
00983         Vector delP(6);
00984         delP(0) = G(0,0);
00985         delP(1) = G(1,0);
00986         delP(2) = G(2,0);
00987         delP(3) = G(3,0);
00988         delP(4) = G(4,0);
00989         delP(5) = G(5,0);
00990         
00991         delP = delP*lamda;      
00992         
00993         int grow = ys->modifySurface(lamda, surfaceForce, G);
00994 
00995         if(grow < 0)
00996                 forceRecoveryAlgo = ys->ConstantYReturn;
00997         else
00998                 forceRecoveryAlgo = forceRecoveryAlgo_orig;
00999 
01000 Vector dF_t(6);
01001         dF_t = dF_in - K*delP;
01002 
01003 //      total_force = surfaceForce + dF_t;
01004         total_force = surfaceForce + dF_in;
01005         
01006         bool use_Kr = false;
01007         if(use_Kr)
01008         {
01009                 
01010         Matrix Kr(6,6);
01011                 Kr = K*G*(G^K)*inv;
01012         Matrix Ks = Stiff;
01013                 Stiff = Ks - Kr;                
01014         }
01015 }
01016 
01017 
01018 void InelasticYS2DGNL::driftBothEnds(Vector &trialForce, Vector &surfaceForce,
01019                                                   Matrix &K, Vector &total_force)
01020 {
01021 Matrix G1(6,1), G2(6,1), G(6, 2);
01022 
01023         ys1->getTrialGradient(G1, surfaceForce);
01024         ys2->getTrialGradient(G2, surfaceForce);
01025         
01026 
01027         for(int i=0; i<6; i++)
01028     {
01029         G(i, 0) = G1(i,0);
01030         G(i, 1) = G2(i,0);
01031     }
01032 
01033 
01034         
01035 Vector dF_in(6);
01036         dF_in = trialForce - surfaceForce;
01037 
01038 Matrix Ktp(6,6); 
01039         
01040         Ktp = K; //includes Ke + Kg
01041 
01042         
01043         ys1->addPlasticStiffness(Ktp);
01044         ys2->addPlasticStiffness(Ktp);
01045 
01046         Matrix KI = G^(Ktp*G);
01047         
01048         Vector Lm(2);
01049         Lm(0) = G1(0,0)*dF_in(0) + G1(2,0)*dF_in(2);
01050         Lm(1) = G2(3,0)*dF_in(3) + G2(5,0)*dF_in(5);    
01051         
01052         //cout << "dF = "  << dF_in;
01053         //cout << "G  = "  << G;
01054         //cout << "Lm = " << Lm;
01055         //cout << "KI = " << KI;
01056         
01057         double mx = max_(Lm(0), Lm(1));
01058         double mn = min_(Lm(0), Lm(1));
01059         double avg = (mx + mn)/2;
01060         
01061 //       if(    fabs(mn/mx)*100 < 25)
01062         {
01063 //              opserr << "BALANCING Lm"<<endl;
01064 //              Lm(0) = mx;
01065 //              Lm(1) = mx;
01066                 
01067 //          if(Lm(0)==mn)
01068 //              Lm(0) = 0.0;
01069 //          if(Lm(1)==mn)
01070 //              Lm(1) = 0.0;            
01071         }
01072         
01073         Lm = Lm/KI;
01074         
01075         //cout << " Lamda = " << Lm; //cin.get();
01076         
01077         double lamda1 = Lm(0);
01078         double lamda2 = Lm(1);
01079         
01080         if(fabs(lamda1) < ERROR) lamda1 = 0.0; // to get rid of -1e-15 etc
01081 
01082         if(fabs(lamda2) < ERROR) lamda2 = 0.0; // to get rid of -1e-15 etc      
01083 
01084         if(lamda1 < 0 || lamda2 < 0)
01085         {
01086                 //cout << "lamda1 = " << lamda1 << " lamda2 = " << lamda2 << endln;
01087                 //cin.get();    
01088                 
01089 
01090                 if(lamda1 < 0.0) lamda1 = 0.0; //fabs(lamda1);
01091                 if(lamda2 < 0.0) lamda2 = 0.0; //fabs(lamda2);
01092         }
01093         
01094         int grow1 = ys1->modifySurface(lamda1, surfaceForce, G1, 1);
01095         int grow2 = ys2->modifySurface(lamda2, surfaceForce, G2, 1);
01096         
01097 Vector delP(6);
01098         delP(0) = G(0,0)*lamda1;
01099         delP(1) = G(1,0)*lamda1;
01100         delP(2) = G(2,0)*lamda1;
01101         delP(3) = G(3,1)*lamda2;
01102         delP(4) = G(4,1)*lamda2;
01103         delP(5) = G(5,1)*lamda2;
01104 
01105 Vector dF_t(6);
01106         dF_t = dF_in - K*delP;
01107 
01108 //      total_force = surfaceForce + dF_t;      
01109         total_force = surfaceForce + dF_in;
01110         
01111         // now we update the stiffness
01112 
01113         bool use_Kr = false;
01114         
01115         if(use_Kr)
01116         {
01117                 Matrix Kr(6,6);
01118                 // opserr << "  ----- USING KR -----" << endln;
01119                 Matrix inv(2,2);
01120 
01121                 inv(0,0) =    KI(1,1);
01122                 inv(0,1) = -1*KI(0,1);
01123                 inv(1,0) = -1*KI(1,0);
01124                 inv(1,1) =    KI(0,0);
01125 
01126                 double det = KI(0,0)*KI(1,1) - KI(1,0)*KI(0,1);
01127 
01128                 if(fabs(det) < 1e-8) det = 1e-8;
01129 
01130                 for(int i=0; i< 2; i++)
01131 
01132                 {
01133                         for(int j=0; j<2; j++)
01134                         {
01135                                 inv(i,j) = inv(i,j)/det;
01136                         }
01137                 }
01138 
01139                 Matrix Gn1 = G*inv;
01140                 Matrix K1 = K*Gn1;
01141                 Kr = K1*(G^K);
01142                 
01143 
01144                 Matrix Ks = Stiff;
01145                 
01146 
01147                 Stiff = Ks - Kr;
01148         }
01149 
01150 
01151 }
01152 
01153 
01154 
01155 // called only when force point at both the ends has drifted from the surface
01156 void InelasticYS2DGNL::plastifyBothEnds(Vector &trial_force, Vector &incrDisp,
01157                                                                          Matrix &K, Vector &total_force)
01158 {
01159 
01160         // opserr << "InelasticYS2DGNL::plastifyBothEnds " << endln;
01161         if(plastkDebug)
01162                 opserr << "----------------------------------------------------------------------"
01163                      << endln;
01164 
01165 Vector trialForce(6);
01166         // copy trial_force so that it does not get modified
01167         trialForce =  trial_force;
01168 
01169 Vector surfaceForce(6);
01170 Matrix G1(6,1), G2(6,1), G(6, 2);
01171 bool use_Kr = true;
01172 bool end1drifts = true;
01173 bool end2drifts = true;
01174         
01175         if(split_step)
01176                 use_Kr = false;
01177 int end = 1;
01178         
01179         // check for ys1 if the ysfp has shot through or drifted        
01180         // case: if it shoots through
01181         //         use dF return to surface
01182         // driftnew is either outside or within (that's why plastify end was called)
01183         // either case, if previous point was elastic, implies a partly elastic load step
01184 
01185         // and remaining inelastic
01186 int driftOld = ys1->getCommitForceLocation();
01187         
01188         if(driftOld == INSIDE)
01189         {
01190                 use_Kr = false;
01191                 end1drifts = false;
01192 
01193                 for(int i=0; i< 3; i++)
01194                         surfaceForce(i) = trialForce(i);
01195                 
01196                         ys1->setToSurface(surfaceForce, ys1->RadialReturn);  //dFReturn, ConstantYReturn, RadialReturn
01197                         ys1->getTrialGradient(G1, surfaceForce);
01198 
01199                 if(plastkDebug)
01200                 {
01201                         opserr << "Element (" << getTag() << ") plastifyBothEnds shoots through end: " << end << "\n";
01202                 }
01203         }
01204         // Now we know that force point has drifted from the surface
01205         else if(driftOld != WITHIN)
01206         {
01207                 opserr << "WARNING: InelasticYS2DGNL::plastifyBothEnds = " << end << " - driftOld outside [" << getTag()<<"]\n";
01208                 opserr << "\a";
01209         }
01210         else
01211         {
01212                 ys1->getCommitGradient(G1);
01213                 
01214                 for(int i=0; i< 3; i++)         
01215                         surfaceForce(i) =  eleForce_hist(i);
01216 
01217                 if(plastkDebug)
01218                         opserr << "Element (" << getTag() << ") plastifyBothEnds (" << end << ") drifts from surface\n";
01219         }
01220 // end1 stuff over      
01221         
01222         
01223 end = 2;
01224         
01225         // check for ys2 if the ysfp has shot through or drifted        
01226         // case: if it shoots through
01227         //         use dF return to surface
01228         // driftnew is either outside or within (that's why plastify end was called)
01229         // either case, if previous point was elastic, implies a partly elastic load step
01230         // and remaining inelastic
01231         driftOld = ys2->getCommitForceLocation();
01232 
01233 
01234         if(driftOld == INSIDE)
01235         {
01236                 use_Kr = false;
01237                 end2drifts = false;
01238                 
01239                 for(int i=3; i<6; i++)
01240                         surfaceForce(i) = trialForce(i);
01241 
01242                         ys2->setToSurface(surfaceForce, ys2->RadialReturn);  //dFReturn, ConstantYReturn, RadialReturn
01243                 // this part can get crazy!!  - FIXED
01244                 // actually, if dF return is used, trial force in different iterations can change
01245                 // radial-return might be better to use         
01246              // opserr << "surface drift = " << ys2->getTrialDrift(surfaceForce) << endln; opserr << "\a";
01247 
01248                         ys2->getTrialGradient(G2, surfaceForce);
01249 
01250                 if(plastkDebug)
01251 
01252                 {
01253                         opserr << "Element (" << getTag() << ") plastifyBothEnds shoots through end: " << end << "\n";
01254                 }
01255         }
01256         // Now we know that force point has drifted from the surface
01257         else if(driftOld != WITHIN)
01258         {
01259                 opserr << "WARNING: InelasticYS2DGNL::plastifyBothEnds = " << end << " - driftOld outside [" << getTag()<<"]\n";
01260                 opserr << "\a";
01261         }
01262         else
01263         {
01264                 ys2->getCommitGradient(G2);
01265                 
01266                 for(int i=3; i< 6; i++)         
01267                         surfaceForce(i) =  eleForce_hist(i);
01268 
01269                 if(plastkDebug)
01270                         opserr << "Element (" << getTag() << ") plastifyBothEnds (" << end << ") drifts from surface\n";
01271         }
01272 // end2 stuff over      
01273         
01274         
01275         /*if(!end1drifts && !end2drifts)
01276         {
01277                 surfaceForce = trial_force;
01278                 ys1->setToSurface(surfaceForce, ys1->ConstantYReturn);
01279                 ys2->setToSurface(surfaceForce, ys2->ConstantYReturn);
01280                 total_force = surfaceForce;
01281                 //cout << "returning surface force\n"; opserr << "\a";
01282                 return;
01283         }*/
01284         
01285         // now check that axial force is still the same, else take avg.
01286 
01287 
01288 
01289 bool force_bal = false;
01290         
01291         if( fabs(surfaceForce(0)) != fabs(surfaceForce(3)))
01292         {
01293                 //cout << "FORCE IMBALANCE \n";
01294                 force_bal = true;
01295 
01296                 this->forceBalance(surfaceForce, 1);
01297                 
01298                 ys1->setToSurface(surfaceForce, ys1->ConstantYReturn);
01299                 ys2->setToSurface(surfaceForce, ys2->ConstantYReturn);
01300                 
01301                 ys1->getTrialGradient(G1, surfaceForce);                
01302                 ys2->getTrialGradient(G2, surfaceForce);
01303         }
01304         
01305         for(int i=0; i<6; i++)
01306     {
01307         G(i, 0) = G1(i,0);
01308         G(i, 1) = G2(i,0);
01309     }
01310         
01311     //cout << "Matrix G = " << G;
01312         // opserr << "G1 = " << G1;
01313         // opserr << "G2 = " << G2;
01314         
01315 // now to make the shear term consistent
01316 // do axial force balancing later       
01317         
01318         // shear force balance - not needed now
01319     //~ surfaceForce(1) = (surfaceForce(2) + surfaceForce(5))/L;
01320         //~ surfaceForce(4) = -surfaceForce(1);
01321         
01322         
01323         
01324 Vector dF_in(6);
01325         dF_in = trialForce - surfaceForce;
01326         
01327         /*if(force_bal)
01328         {
01329                 opserr << "df_in before f_bal = " << dF_in;
01330                 double avg = (dF_in(2) + dF_in(5)) / 2;
01331                 opserr << "avg = " << avg << endln;
01332                 
01333                 dF_in(2) = avg;
01334 
01335                 dF_in(5) = avg;
01336 
01337 
01338                 
01339                 // this->forceBalance(dF_in,1);
01340         }*/
01341 
01342         // opserr << "trialForce   = " << trialForce;
01343         // opserr << "surfaceForce = " << surfaceForce;
01344         // opserr << "dF_in        = " << dF_in << endln;
01345 
01346 Matrix Ktp(6,6); //Ke(6,6); // want to leave 'K' unmodified for now
01347 
01348 //      int drift_test = ys->getTrialForceLocation(surfaceForce);
01349 //      opserr << " force_hist = " << eleForce_hist;
01350 //      opserr << " drift_test = " << drift_test << endln;
01351 
01352         Ktp = K; //includes Ke + Kg
01353 
01354         
01355         if(end1drifts)
01356                 ys1->addPlasticStiffness(Ktp);
01357         if(end2drifts)
01358                 ys2->addPlasticStiffness(Ktp);
01359 
01360         Matrix KI = G^(Ktp*G);
01361         //Vector Lm = G^(dF_in);
01362         
01363         Vector Lm(2);
01364         Lm(0) = G1(0,0)*dF_in(0) + G1(2,0)*dF_in(2);
01365         Lm(1) = G2(3,0)*dF_in(3) + G2(5,0)*dF_in(5);    
01366                 
01367         /*double mx = max_(Lm(0), Lm(1));
01368         double mn = min_(Lm(0), Lm(1));
01369         double avg = (mx + mn)/2;
01370         
01371         if(    (mn/mx)*100 < 50)
01372         {
01373                 Lm(0) = mn;
01374                 Lm(1) = mn;
01375         }*/
01376         
01377         //cout << "dF = " << dF_in;
01378         //cout << "Lm = " << Lm;
01379         //cout << "KI = " << KI;
01380 
01381         
01382         Lm = Lm/KI;
01383         
01384         //cout << " Lamda = " << Lm;  // opserr << "\a";
01385         
01386         double lamda1 = Lm(0);
01387         double lamda2 = Lm(1);
01388         
01389         
01390         // opserr << "KI = " << KI;
01391         // opserr << "lamda = " << lamda1 << " " << lamda2 << endln;
01392 
01393 
01394         
01395         if(fabs(lamda1) < ERROR) lamda1 = 0.0; // to get rid of -1e-15 etc
01396         if(fabs(lamda2) < ERROR) lamda2 = 0.0; // to get rid of -1e-15 etc      
01397 
01398         // happens when one end is shooting through and other drifting
01399         if(lamda1 < 0 || lamda2 < 0)
01400         {
01401                 //~ opserr << "lamda = " << lamda1 << " " << lamda2 << endln;
01402                 // opserr << "\a";
01403                 use_Kr = false;
01404                 
01405                 //~ if(lamda1 < 0)
01406                         //~ lamda1 = fabs(lamda1);
01407                 //~ if(lamda2 < 0)
01408                         //~ lamda2 = fabs(lamda1);
01409                 
01410                 if(lamda1 < 0)
01411                         lamda1 = 0.0;
01412                 if(lamda2 < 0)
01413                         lamda2 = 0.0;
01414 
01415         }
01416                         
01417         // Given the force point modify the surface
01418         int grow1 = ys1->modifySurface(lamda1, surfaceForce, G1);
01419         int grow2 = ys2->modifySurface(lamda2, surfaceForce, G2);
01420         
01421         // int factor = 1;
01422         //~ if(grow1 <= 0)
01423 
01424 
01425                         //~ factor -= 0.5;
01426         //~ if(grow2 <= 0)
01427                         //~ factor -= 0.5;
01428 
01429                 
01430         // separate this also
01431         if(grow1 < 0 || grow2 < 0)
01432         {
01433                 forceRecoveryAlgo = ys1->ConstantYReturn;
01434         }
01435         else // need to check every-time
01436                 forceRecoveryAlgo = forceRecoveryAlgo_orig;
01437         
01438         Vector delP(6);
01439         delP(0) = G(0,0)*lamda1;
01440         delP(1) = G(1,0)*lamda1;
01441         delP(2) = G(2,0)*lamda1;
01442         delP(3) = G(3,1)*lamda2;
01443         delP(4) = G(4,1)*lamda2;
01444         delP(5) = G(5,1)*lamda2;
01445 
01446 
01447 Vector dF_t(6);
01448         dF_t = dF_in - K*delP;
01449 
01450         total_force = surfaceForce + dF_t;
01451         
01452         //ys1->displayForcePoint(total_force, 3);
01453         //ys2->displayForcePoint(total_force, 3);
01454         
01455         if(plastkDebug)
01456     {
01457                 opserr << " InelasticYS2DGNL::plastifyOneEnd - tag = " << getTag() << "\n";
01458         opserr << "lamda = " << lamda1 << " " << lamda2 << "\n";
01459                 opserr << " G = " << G << endln;
01460                 opserr << "delP = " << delP <<endln;
01461                 // opserr << "\a";
01462     }
01463 
01464         // now we update the stiffness
01465 
01466         Matrix Kr(6,6);
01467 
01468         //use_Kr = false;
01469         
01470         if(use_Kr)
01471         {
01472                 Matrix inv(2,2);
01473 
01474                 inv(0,0) =    KI(1,1);
01475                 inv(0,1) = -1*KI(0,1);
01476                 inv(1,0) = -1*KI(1,0);
01477                 inv(1,1) =    KI(0,0);
01478 
01479                 double det = KI(0,0)*KI(1,1) - KI(1,0)*KI(0,1);
01480 
01481                 if(fabs(det) < 1e-8) det = 1e-8;
01482 
01483 
01484                 for(int i=0; i< 2; i++)
01485                 {
01486                         for(int j=0; j<2; j++)
01487                         {
01488                                 inv(i,j) = inv(i,j)/det;
01489                         }
01490                 }
01491 
01492                 Matrix Gn1 = G*inv;
01493                 Matrix K1 = K*Gn1;
01494                 Kr = K1*(G^K);
01495                 //Kr = K*G*(G^K)*inv;
01496                 // opserr << "factor = " << factor << endln; opserr << "\a";
01497                 
01498                 Stiff = Stiff - Kr;
01499                 
01500                 // opserr << Stiff;
01501                 
01502                 // F1 = (Stiff)*incrDisp + surfaceForce;
01503                 // ys->displayForcePoint(F1, 3); 
01504                 // opserr << "\a";
01505         }
01506 //      else
01507 //              opserr << "NOT USING Kr " << endln;
01508         
01509         
01510 }
01511 
01512 
01513 
01514 
01515 int InelasticYS2DGNL::commitState()
01516 {
01517 
01518          if(pdebug)
01519                 opserr << " ############# commit ############ ["<< getTag() << "]\n";
01520         //cin.get();
01521         /*bool end1drifts, end2drifts;
01522         this->checkEndStatus(end1drifts, end2drifts, eleForce);
01523 
01524         if(plastkDebug)
01525         {
01526                 opserr << "End1Plastify = " << end1Plastify << ", End2Plastify = " << end2Plastify << "\n";
01527                 opserr << "End1Drifts   = " << end1drifts   << ", End2Drifts   = " << end2drifts   << "\n";
01528                 opserr << " ------------------------------------\n\n";
01529         }*/
01530         //cin.get();
01531 //      if(getTag()==3)
01532 //      {
01533 //              opserr << eleForce;
01534 //              opserr << "\a";
01535 //      }
01536 
01537     split_step = false;
01538         this->UpdatedLagrangianBeam2D::commitState();
01539 
01540         if(end1Plastify)
01541                 end1Damage = true;
01542 
01543         if(end2Plastify)
01544                 end2Damage = true;
01545 
01547         ys1->commitState(eleForce);
01548         ys2->commitState(eleForce);
01549 
01550         end1Plastify_hist =  end1Plastify;
01551         end2Plastify_hist =  end2Plastify;
01552 
01553         if(pView)
01554         {
01555         pView->clearImage();
01556         pView->startImage();
01557         ys1->displaySelf(*pView, 1, 1);
01558         ys2->displaySelf(*pView, 1, 1);
01559         pView->doneImage();
01560         }
01561 
01562         // opserr << "--- commit ---\n"; opserr << "\a";
01563 
01564         //if(getTag()==3) opserr << storage << "000000";
01565 
01566         return 0;
01567 }
01568 
01569 
01570 
01572 // Pure virtual abstract methods
01574 
01575 void InelasticYS2DGNL::getLocalMass(Matrix &M)
01576 {
01577         if(massDof < 0)
01578     {
01579                 opserr << "Element2dGNL::getMass - Distributed mass not implemented\n";
01580             M.Zero();
01581     }
01582     else if(massDof == 0)//this cond. is taken care of already
01583     {
01584         M.Zero();
01585     }
01586     else
01587     {
01588         M.Zero();
01589             M(0,0) = M(1,1) = M(2,2) = M(3,3) = M(4,4) = M(5,5) = massDof;
01590     }
01591 
01592 }
01593 
01594 /*
01595 void InelasticYS2DGNL::getLocalStiff(Matrix &K)
01596 {
01597  double EIbyL = E*Iz/L;
01598 
01599     K(0, 1) = K(0, 2) = K(0, 4) = K(0, 5)=0;
01600     K(1, 0) = K(1, 3) =0;
01601     K(2, 0) = K(2, 3) =0;
01602     K(3, 1) = K(3, 2) = K(3, 4) = K(3, 5)=0;
01603     K(4, 0) = K(4, 3) =0;
01604     K(5, 0) = K(5, 3) =0;
01605 
01606         K(0,0) = K(3,3) = (A/Iz)*(EIbyL);
01607         K(0,3) = K(3,0) = (-A/Iz)*(EIbyL);
01608         K(1,1) = K(4,4) = (12/(L*L))*(EIbyL);
01609         K(1,4) = K(4,1) = (-12/(L*L))*(EIbyL);
01610         K(1,2) = K(2,1) = K(1,5) = K(5,1) = (6/L)*(EIbyL);
01611         K(2,4) = K(4,2) = K(4,5) = K(5,4) = (-6/L)*(EIbyL);
01612         K(2,2) = K(5,5) = 4*(EIbyL);
01613         K(2,5) = K(5,2) = 2*(EIbyL);
01614 
01615 
01616 }//getLocalStiff
01617 */
01618 
01620 // Print/Render  Send/Recv
01622 void InelasticYS2DGNL::createView(char *title, double scale, int x, int y, int cx, int cy, char displaytype)
01623 {
01624         displayType = displaytype;
01625 
01626 
01627 #ifdef _NOGRAPHICS
01628 
01629 #else
01630 #ifdef _GLX // Boris Jeremic added 23Oct2002
01631 theMap = new PlainMap();
01632 pView =  new OpenGLRenderer(title, x, y, cx, cy, *theMap);
01633 
01634  if(pView){
01635    pView->setVRP(0.0, 0.0, 0.0);
01636    pView->setVPN(0.0, 0.0, 1.0);
01637    pView->setVUP(0.0, 1.0, 0.0);
01638    pView->setFillMode("wire");             // wire mode
01639    pView->setPlaneDist(1.0, -1.0);
01640    pView->setPRP(0.0, 0.0, 10.0);
01641    pView->setPortWindow(-1, 1, -1, 1);  // use the whole window
01642    
01643    pView->setViewWindow(-scale, scale, -scale, scale);
01644    
01645    pView->clearImage();
01646    pView->startImage();
01647    
01648 
01649    ys1->setView(pView);
01650    ys2->setView(pView);
01651    
01652    ys1->displaySelf(*pView, 10, 1);
01653    ys2->displaySelf(*pView, 10, 1);
01654 pView->doneImage();
01655  
01656  }
01657  else
01658    opserr << "WARNING: InelasticYS2DGNL::createView - Renderer not available\n";
01659 #endif   // Boris Jeremic added 23Oct2002
01660 #endif
01661 
01662 }
01663 
01664 
01665 
01666 /*
01667 void InelasticYS2DGNL::createView(char *title, WindowManager *theWM, char displaytype)
01668 {
01669         displayType = displaytype;
01670         theMap = new PlainMap();
01671         pView = theWM->getRenderer(title, *theMap);
01672         //pView = new OpenGLRenderer(title, *theMap);
01673         if(!pView)
01674                 opserr << "WARNING: InelasticYS2DGNL::createView - Renderer not available\n";
01675         //theWM->setRenderer(*pView);   
01676                 
01677         if(pView)
01678         {
01679         pView->setViewWindow(-3.5, 3.5, -3.5, 3.5);
01680 
01681         pView->clearImage();
01682         pView->startImage();
01683 
01684         ys1->setView(pView);
01685                 ys2->setView(pView);
01686 
01687         ys1->displaySelf(*pView, 1, 1);
01688         ys2->displaySelf(*pView, 1, 1);
01689         pView->doneImage();
01690         }
01691 }
01692 */
01693 
01694 void InelasticYS2DGNL::Print(OPS_Stream &s, int flag)
01695 {
01696     s << "\nElement No: " << this->getTag();
01697     s << " type: InelasticYS2DGNL  iNode: " << connectedExternalNodes(0);
01698     s << " jNode: " << connectedExternalNodes(1);
01699     //s << "\nElement Forces ";
01700 }
01701 
01702 int InelasticYS2DGNL::sendSelf(int commitTag, Channel &theChannel)
01703 {
01704         return -1;
01705 }
01706 
01707 int InelasticYS2DGNL::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
01708 {
01709         return -1;
01710 }
01711 
01712 
01713 Response* InelasticYS2DGNL::setResponse(const char **argv, int argc, Information &eleInformation)
01714 {
01715 Response *suResponse=0;
01716 
01717         suResponse = this->UpdatedLagrangianBeam2D::setResponse(argv, argc, eleInformation);
01718 
01719         if(suResponse != 0)
01720                 return suResponse;
01721 
01722     if (strcmp(argv[0],"ysVisual") == 0)
01723         {
01724                 suResponse =  new ElementResponse(this, DISPLAY_YS);
01725     }
01726 
01727         return suResponse;
01728 }
01729 
01730 
01731 int InelasticYS2DGNL::getResponse(int responseID, Information &eleInformation)
01732 {
01733 int res = this->UpdatedLagrangianBeam2D::getResponse(responseID, eleInformation);
01734 
01735         if(res != -1)
01736                 return res;
01737 
01738         if(responseID == DISPLAY_YS)
01739                 res = responseID;
01740 
01741         return res;
01742 }
01743 
01744 
01745 
01746 int InelasticYS2DGNL::displaySelf(Renderer &theViewer, int displayMode, float fact)
01747 {
01748     // first determine the two end points of the element based on
01749     // the display factor (a measure of the distorted image)
01750     // store this information in 2 3d vectors v1 and v2
01751     //cerr << "Inside display self mode: " << displayMode << " fact " << fact <<"\n";
01752 
01753         if(displayMode == DISPLAY_YS)
01754         {
01755                 ys1->setView(&theViewer);
01756                 ys2->setView(&theViewer);
01757 
01758                 ys1->displaySelf(theViewer, 1, 1);
01759                 ys2->displaySelf(theViewer, 1, 1);
01760                 return 0;
01761         }
01762 
01763 
01764   this->UpdatedLagrangianBeam2D::displaySelf(theViewer, displayMode, fact);
01765 
01766   const Vector &end1Crd = end1Ptr->getCrds();
01767   const Vector &end2Crd = end2Ptr->getCrds();
01768   const Vector &end1Disp = end1Ptr->getTrialDisp();
01769   const Vector &end2Disp = end2Ptr->getTrialDisp();
01770 
01771         Vector v1(3);
01772     Vector v2(3);
01773         Vector vc(3);
01774 
01775         Vector rgb(3);
01776         rgb(0) = 0;
01777         rgb(1) = 0.9;
01778         rgb(2) = 0;
01779 
01780     for (int i=0; i<2; i++) { 
01781         v1(i) = end1Crd(i)+end1Disp(i)*fact;
01782         v2(i) = end2Crd(i)+end2Disp(i)*fact;
01783     }
01784         double e = 0.05;
01785 
01786         if (displayMode == 1) //theViewer.drawLine(v1, v2, 1, 1);
01787         {
01788                 if(end1Damage && !end1Plastify)
01789                 {
01790                         vc(2) = v1(2);
01791                         vc(0) = v1(0) + e*(v2(0) - v1(0));
01792 
01793 
01794                         vc(1) = v1(1) + e*(v2(1) - v1(1));
01795 
01796                         theViewer.drawPoint(vc, rgb, 3);
01797                 }
01798 
01799                 if(end2Damage && !end2Plastify)
01800                 {
01801                         vc(2) = v2(2);
01802                         vc(0) = v2(0) + e*(v1(0) - v2(0));
01803                         vc(1) = v2(1) + e*(v1(1) - v2(1));
01804 
01805                         theViewer.drawPoint(vc, rgb, 3);
01806                 }
01807 
01808 
01809                 if(!end1Plastify && !end2Plastify) return 0;
01810 
01811                 rgb(0) = 1;
01812                 rgb(1) = 0;
01813                 rgb(2) = 0;
01814                 if(end1Plastify)
01815                 {
01816                         vc(2) = v1(2);
01817 
01818                         vc(0) = v1(0) + e*(v2(0) - v1(0));
01819                         vc(1) = v1(1) + e*(v2(1) - v1(1));
01820 
01821                         theViewer.drawPoint(vc, rgb, 3);
01822                 }
01823                 if(end2Plastify)
01824                 {
01825                         vc(2) = v2(2);
01826                         vc(0) = v2(0) + e*(v1(0) - v2(0));
01827                         vc(1) = v2(1) + e*(v1(1) - v2(1));
01828 
01829                         theViewer.drawPoint(vc, rgb, 3);
01830 
01831                 }
01832         }
01833         return 0;
01834 
01835 }
01836 
01837 
01838 
01839 
01840 /* if(split_step && !end1Plastify)
01841         {
01842                 ys1->setToSurface(trialForce, ys1->ConstantYReturn);
01843                 trialForce(2) = trialForce(2)*1.00001;
01844             this->forceBalance(trialForce, 1);
01845         }
01846         
01847         if(split_step && !end2Plastify)
01848         {
01849                 ys2->setToSurface(trialForce, ys1->ConstantYReturn);
01850                 trialForce(5) = trialForce(5)*1.00001;
01851             this->forceBalance(trialForce, 1);
01852         }
01853     this->checkEndStatus(end1Drifts, end2Drifts, trialForce);
01854 */
01855 
01856 
01857 
01858 
01859 
01860 
01861 /*
01862 // called only when force point at both the ends has drifted from the surface
01863 void InelasticYS2DGNL::plastifyBothEnds(Vector &trial_force, Vector &incrDisp,
01864                                                                          Matrix &K, Vector &total_force)
01865 {
01866 Vector trialForce(6);
01867 
01868         // copy trial_force so that it does not get modified
01869         trialForce =  trial_force;
01870     Matrix G(6, 2);
01871     Matrix Kt(6,6), Ktp(6,6), Ke(6,6);
01872 
01873     Ke  =  K;
01874     Ktp = Ke;
01875     Kt  = Ktp;
01876 
01877         ys1->addPlasticStiffness(Ktp);
01878         ys2->addPlasticStiffness(Ktp);
01879         
01880         Matrix ysG1(6,1), ysG2(6,1);
01881         Vector elasticForce(6);
01882 
01883         elasticForce =  eleForce_hist;
01884         
01885 //      int driftOld = ys1->getTrialForceLocation(elasticForce);
01886 //    if(driftOld == OUTSIDE)
01887 //      {
01888 //              opserr << "WARNING: InelasticYS2DGNL::plastifyBothEnds - end1 driftOld outside\n";
01889 
01890 //              opserr << "\a";
01891 //      }
01892         // In a trial state, elasticForce may not exactly be on surface, esp. in case
01893         // of hardening - it may actually be inside, from second trial step onwards
01894         // since phi = phi_hist + dR
01895         // set elasticForce to surface anyway, there might a minute difference in G,
01896         // but computation of phi will be accurate, and the force-balance step will
01897         // take care of any difference in F_total ( = F_on_surface + Kt*ddel)
01898         
01900         // this causes convergence problems, especially if ys is shrinking
01901         
01902 //      driftOld = ys2->getTrialForceLocation(elasticForce);
01903 //    if(driftOld == OUTSIDE)
01904 //      {
01905 //              opserr << "WARNING: InelasticYS2DGNL::plastifyBothEnds - end2 driftOld outside\n";
01906 //              opserr << "\a";
01907 //      }
01909         
01910     ys1->getCommitGradient(ysG1);
01911     ys2->getCommitGradient(ysG2);
01912 
01913     for(int i=0; i<6; i++)
01914     {
01915         G(i, 0) = ysG1(i,0);
01916         G(i, 1) = ysG2(i,0);
01917     }
01918 
01919         Matrix KI = G^(Ktp*G);
01920         Matrix inv(2,2);
01921 
01922         inv(0,0) =    KI(1,1);
01923         inv(0,1) = -1*KI(0,1);
01924         inv(1,0) = -1*KI(1,0);
01925         inv(1,1) =    KI(0,0);
01926 
01927         double det = KI(0,0)*KI(1,1) - KI(1,0)*KI(0,1);
01928 
01929         if(fabs(det) < 1e-8) det = 1e-8;
01930 
01931         for(int i=0; i< 2; i++)
01932         {
01933                 for(int j=0; j<2; j++)
01934                 {
01935                         inv(i,j) = inv(i,j)/det;
01936                 }
01937         }
01938 
01939         // Calculate modified stiffness
01940         Matrix G1 = G*inv;
01941         Matrix K1 = Ke*G1;
01942         Matrix Kr = K1*(G^Ke);
01943         Kt = Ke - Kr;
01944 
01945         Vector din = incrDisp;
01946         total_force = Kt*din;
01947 
01948 
01949         // add to the elastic force point on the surface
01950         total_force +=  elasticForce;
01951 
01952         Matrix dinc(6,1);
01953         for(int i=0; i<6; i++)
01954                 dinc(i,0) = din(i);
01955 
01956         Matrix Lm = inv*(G^Ke)*dinc;
01957 
01958         double lamda1 = Lm(0,0), lamda2 = Lm(1,0);
01959     if(fabs(lamda1) < ERROR) lamda1 = 0; // to get rid of -1e-15 etc
01960     if(fabs(lamda2) < ERROR) lamda2 = 0; // to get rid of -1e-15 etc
01961 
01962         // Given the force points drifted, modify the surface
01963         //~ int grow1 = ys1->modifySurface(lamda1, elasticForce);
01964         //~ int grow2 = ys2->modifySurface(lamda2, elasticForce);
01965 
01966         //~ if(grow1 < 0 || grow2 < 0)
01967                 //~ forceRecoveryAlgo = ys1->ConstantYReturn;
01968     //~ else
01969                 //~ forceRecoveryAlgo = forceRecoveryAlgo_orig;
01970 
01971 
01972 }
01973 */
01974 

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