00001
00003
00004 #include <Domain.h>
00005 #include <Channel.h>
00006 #include <FEM_ObjectBroker.h>
00007
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
00022 #include <PlainMap.h>
00023 #include <Information.h>
00024 #include <ElementResponse.h>
00025 #include <string.h>
00026
00027
00028
00029 #define updateDebug 0
00030 #define plastkDebug 0
00031
00032 #define ERROR 1e-8
00033 #define TAG_InelasticYS2DGNL -1
00034
00035
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
00049
00050
00051 InelasticYS2DGNL::InelasticYS2DGNL(int tag,
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
00079
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
00090
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
00106
00107 }
00108
00109
00110 int InelasticYS2DGNL::update()
00111 {
00112 if (L == 0)
00113 return 0;
00114
00115 ys1->update();
00116 ys2->update();
00117
00118
00119
00121
00123
00124
00125 getLocalStiff(Stiff);
00126
00127
00128 addInternalGeomStiff(Stiff);
00129
00130
00131 getIncrNaturalDisp(disp);
00132
00133
00134
00135 force = Stiff*disp;
00136
00137 Vector trial_force(6);
00138
00139
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
00150
00151
00152
00153
00155
00157
00158 {
00159 int plastify = this->plasticPredictor(trialForce);
00160 if(!plastify)
00161 return 0;
00162 }
00163
00164
00165
00166
00167
00168
00169
00171
00173
00174 if(end1Plastify)
00175 {
00176
00177 int d1 = ys1->getTrialForceLocation(eleForce);
00178 if(d1 == OUTSIDE)
00179 {
00180 ys1->setToSurface(eleForce, ys1->RadialReturn);
00181
00182 }
00183 else
00184 {
00185 ys1->setToSurface(eleForce, ys1->ConstantYReturn);
00186
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
00197 }
00198 else
00199 {
00200 ys2->setToSurface(eleForce, ys2->ConstantYReturn);
00201
00202 }
00203 }
00204
00206
00208 forceBalance(eleForce, 1);
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
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
00232 if(sign(eleForce(0)) == sign(eleForce(3)))
00233 {
00234 opserr << "oops 1: element " << getTag() << " okay \n";
00235 opserr << eleForce;
00236
00237
00238
00239
00240
00241 getIncrNaturalDisp(disp);
00242 force = Stiff*disp;
00243 eleForce = eleForce_hist + force;
00244
00245
00246 bool end1Drifts, end2Drifts;
00247 this->checkEndStatus(end1Drifts, end2Drifts, eleForce);
00248
00249 if(end1Plastify)
00250 ys1->setToSurface(eleForce, ys1->ConstantYReturn);
00251 if(end2Plastify)
00252 ys2->setToSurface(eleForce, ys2->ConstantYReturn);
00253
00254
00255 forceBalance(eleForce, 1);
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
00284
00285
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)
00293 {
00294
00295 eleForce = trialForce;
00296 return 0;
00297 }
00298
00299
00300
00301
00302
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
00329 this->plastifyOneEnd(1, ys1, trialForce, disp, Stiff, eleForce, -1);
00330 }
00331 else if(end2Plastify && !end1Plastify)
00332 {
00333
00334 this->plastifyOneEnd(2, ys2, trialForce, disp, Stiff, eleForce, -1);
00335 }
00336 else if(end1Plastify && end2Plastify)
00337 {
00338
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
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 }
00394 else
00395 {
00396 if(!end1Plastify && !end2Plastify)
00397 {
00398
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
00411
00412 return 1;
00413 }
00414
00415
00416
00417
00418 void InelasticYS2DGNL::checkEndStatus(bool &end1drifts, bool &end2drifts, Vector &trialForce)
00419 {
00420 int driftOld;
00421
00422 end1Plastify = false;
00423 end2Plastify = false;
00424
00425
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
00441
00442
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
00452
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
00465 }
00466 else
00467 opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 1 remains elastic\n";
00468 }
00469 }
00470
00471
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
00498
00499
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
00514 }
00515 else
00516 opserr << "checkEndStatus(..) ["<<getTag()<<"] - End 2 remains elastic\n";
00517
00518 }
00519 }
00520
00521
00522
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:
00539 {
00540 eleforce(0) = Pavg*sign1;
00541 eleforce(3) = Pavg*sign2;
00542 break;
00543 }
00544 case 2:
00545 {
00546 eleforce(0) = Pmin*sign1;
00547 eleforce(3) = Pmin*sign2;
00548 break;
00549 }
00550
00551 case 3:
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
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
00586
00587 if(!init)
00588 {
00589 this->update();
00590 init = true;
00591 }
00592
00593
00594
00595
00596 transformToGlobal(Stiff);
00597
00598
00599
00600 return Stiff;
00601 }
00602
00603
00604
00605 const Vector &InelasticYS2DGNL::getResistingForce(void)
00606 {
00607
00608
00609 if(!init)
00610 {
00611
00612 this->update();
00613 init = true;
00614 }
00615
00616 if (L == 0)
00617 return ZeroVector;
00618 m_Iter++;
00619
00620
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
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
00655
00656
00657
00658
00659 storage += force[2];
00660
00661 }
00662
00663
00664
00665
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
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 if(plastkDebug)
00687 opserr << "----------------------------------------------------------------------"
00688 << endln;
00689
00690 Vector trialForce(6);
00691
00692 trialForce = trial_force;
00693
00694 Vector surfaceForce(6);
00695 Matrix G(6,1);
00696 bool use_Kr = true;
00697
00698
00699
00700
00701
00702
00703
00704
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);
00716
00717
00718
00719
00720 ys->getTrialGradient(G, surfaceForce);
00721
00722 if(plastkDebug)
00723 {
00724 opserr << "Element (" << getTag() << ") plastifyEnd shoots through end: " << end << "\n";
00725 }
00726 }
00727
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
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 Vector dF_in(6);
00753 dF_in = trialForce - surfaceForce;
00754
00755 Matrix Ktp(6,6);
00756
00757 int drift_test = ys->getTrialForceLocation(surfaceForce);
00758
00759
00760
00761 Ktp = K;
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;
00774
00775 if(lamda < 0)
00776 {
00777
00778
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;
00812 else
00813 total_force = surfaceForce + dF_in;
00814
00815
00816
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
00826 }
00827
00828
00829 if(algo == -10)
00830 use_Kr = false;
00831
00832 if(split_step)
00833 use_Kr = false;
00834
00835
00836
00837 if(use_Kr)
00838 {
00839 Matrix Kr(6,6);
00840 Kr = K*G*(G^K)*inv;
00841 Stiff = Stiff - Kr;
00842
00843
00844
00845
00846 }
00847
00848
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
00857
00858
00859
00860 split_step = true;
00861
00862 Vector F1(6);
00863 F1 = trial_force;
00864 ys_shoots->setToSurface(F1, ys1->dFReturn);
00865
00866
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
00891 Vector trialForce2(6), step_force(6);
00892
00893
00894
00895
00896
00897 trialForce2 = eleForce_hist + t*(trial_force - eleForce_hist);
00898
00899
00900 Vector f_surface = eleForce_hist;
00901 int count =0;
00902
00903 {
00904 this->driftOneEnd(ys_drifts, trialForce2, f_surface, K, step_force);
00905
00906
00907 this->forceBalance(step_force, 1);
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 }
00930
00931
00932
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
00942
00943 this->driftBothEnds(trialForce2, step_force, K, eleForce);
00944
00945 }
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
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;
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;
00974
00975 if(lamda < 0)
00976 {
00977
00978
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
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;
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
01053
01054
01055
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
01062 {
01063
01064
01065
01066
01067
01068
01069
01070
01071 }
01072
01073 Lm = Lm/KI;
01074
01075
01076
01077 double lamda1 = Lm(0);
01078 double lamda2 = Lm(1);
01079
01080 if(fabs(lamda1) < ERROR) lamda1 = 0.0;
01081
01082 if(fabs(lamda2) < ERROR) lamda2 = 0.0;
01083
01084 if(lamda1 < 0 || lamda2 < 0)
01085 {
01086
01087
01088
01089
01090 if(lamda1 < 0.0) lamda1 = 0.0;
01091 if(lamda2 < 0.0) lamda2 = 0.0;
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
01109 total_force = surfaceForce + dF_in;
01110
01111
01112
01113 bool use_Kr = false;
01114
01115 if(use_Kr)
01116 {
01117 Matrix Kr(6,6);
01118
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
01156 void InelasticYS2DGNL::plastifyBothEnds(Vector &trial_force, Vector &incrDisp,
01157 Matrix &K, Vector &total_force)
01158 {
01159
01160
01161 if(plastkDebug)
01162 opserr << "----------------------------------------------------------------------"
01163 << endln;
01164
01165 Vector trialForce(6);
01166
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
01180
01181
01182
01183
01184
01185
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);
01197 ys1->getTrialGradient(G1, surfaceForce);
01198
01199 if(plastkDebug)
01200 {
01201 opserr << "Element (" << getTag() << ") plastifyBothEnds shoots through end: " << end << "\n";
01202 }
01203 }
01204
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
01221
01222
01223 end = 2;
01224
01225
01226
01227
01228
01229
01230
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);
01243
01244
01245
01246
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
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
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 bool force_bal = false;
01290
01291 if( fabs(surfaceForce(0)) != fabs(surfaceForce(3)))
01292 {
01293
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
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324 Vector dF_in(6);
01325 dF_in = trialForce - surfaceForce;
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346 Matrix Ktp(6,6);
01347
01348
01349
01350
01351
01352 Ktp = K;
01353
01354
01355 if(end1drifts)
01356 ys1->addPlasticStiffness(Ktp);
01357 if(end2drifts)
01358 ys2->addPlasticStiffness(Ktp);
01359
01360 Matrix KI = G^(Ktp*G);
01361
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
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382 Lm = Lm/KI;
01383
01384
01385
01386 double lamda1 = Lm(0);
01387 double lamda2 = Lm(1);
01388
01389
01390
01391
01392
01393
01394
01395 if(fabs(lamda1) < ERROR) lamda1 = 0.0;
01396 if(fabs(lamda2) < ERROR) lamda2 = 0.0;
01397
01398
01399 if(lamda1 < 0 || lamda2 < 0)
01400 {
01401
01402
01403 use_Kr = false;
01404
01405
01406
01407
01408
01409
01410 if(lamda1 < 0)
01411 lamda1 = 0.0;
01412 if(lamda2 < 0)
01413 lamda2 = 0.0;
01414
01415 }
01416
01417
01418 int grow1 = ys1->modifySurface(lamda1, surfaceForce, G1);
01419 int grow2 = ys2->modifySurface(lamda2, surfaceForce, G2);
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431 if(grow1 < 0 || grow2 < 0)
01432 {
01433 forceRecoveryAlgo = ys1->ConstantYReturn;
01434 }
01435 else
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
01453
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
01462 }
01463
01464
01465
01466 Matrix Kr(6,6);
01467
01468
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
01496
01497
01498 Stiff = Stiff - Kr;
01499
01500
01501
01502
01503
01504
01505 }
01506
01507
01508
01509
01510 }
01511
01512
01513
01514
01515 int InelasticYS2DGNL::commitState()
01516 {
01517
01518 if(pdebug)
01519 opserr << " ############# commit ############ ["<< getTag() << "]\n";
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
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
01563
01564
01565
01566 return 0;
01567 }
01568
01569
01570
01572
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)
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
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01620
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");
01639 pView->setPlaneDist(1.0, -1.0);
01640 pView->setPRP(0.0, 0.0, 10.0);
01641 pView->setPortWindow(-1, 1, -1, 1);
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
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
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
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
01749
01750
01751
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)
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
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01900
01901
01902
01903
01904
01905
01906
01907
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974