YieldSurface_BC2D.cpp

Go to the documentation of this file.
00001 // YieldSurface_BC2D.cpp: implementation of the YieldSurfaceBC class.
00002 //
00004 
00005 #include "YieldSurface_BC2D.h"
00006 #define modifDebug  0
00007 #define returnDebug 0
00008 #define transDebug  0
00009 #define driftDebug  0
00010 
00011 #include <MaterialResponse.h>
00012 
00013 double YieldSurface_BC2D::error(1.0e-6);
00014 Vector YieldSurface_BC2D::v6(6);
00015 Vector YieldSurface_BC2D::T2(2);
00016 Vector YieldSurface_BC2D::F2(2);
00017 Vector YieldSurface_BC2D::g2(2);
00018 Vector YieldSurface_BC2D::v2(2);
00019 Vector YieldSurface_BC2D::v4(4);
00020 
00021 
00023 // Construction/Destruction
00025 
00026 YieldSurface_BC2D::YieldSurface_BC2D(int tag, int classTag, double xmax, double ymax,
00027                   YS_Evolution &model)
00028 :YieldSurface_BC(tag, classTag, model, xmax, ymax)
00029 {
00030         status_hist = -1; //elastic
00031 
00032         fx_hist = 0;
00033         fy_hist = 0;
00034 
00035         offset     = 0.01;
00036         increment  = 0.022;
00037 
00038         state = 0;
00039 
00040 }
00041 
00042 YieldSurface_BC2D::~YieldSurface_BC2D()
00043 {
00044 
00045 }
00046 
00047 const Vector &YieldSurface_BC2D::getExtent(void)
00048 {
00049         v4(0) = xPos;
00050         v4(1) = xNeg;
00051         v4(2) = yPos;
00052         v4(3) = yNeg;
00053 
00054         return v4;
00055 }
00056 
00057 
00059 // Transformation
00061 
00062 // Use this function to initialize other stuff
00063 void YieldSurface_BC2D::setTransformation(int xDof, int yDof, int xFact, int yFact)
00064 {
00065         this->YieldSurface_BC::setTransformation(xDof, yDof, xFact, yFact);
00066 
00067         this->setExtent();
00068         if(xPos == 0 && yPos == 0 && xNeg ==0 && yNeg == 0)
00069         {
00070                 opserr << "WARNING - YieldSurface_BC2D - surface extent not set correctly\n";
00071         }
00072 
00073         if(xPos == 0 || xNeg == 0)
00074                 opserr << "Error - YieldSurface_BC2D no X extent\n";
00075 
00077         // Next set the 'a' and 'b' for the internal quad
00079 
00080 double x1, y1, x2, y2;
00081 
00082         // QUAD 1
00083         x1 = 0; y1 = yPos - offset ; x2 = xPos - offset; y2 = 0;
00084         a1 = (y1 - y2)/(x1 - x2);
00085         b1 = y1 - a1*x1;
00086 
00087         // QUAD 2
00088         x1 = 0; y1 = yPos - offset; x2 = xNeg + offset; y2 = 0;
00089         a2 = (y1 - y2)/(x1 - x2);
00090         b2 = y1 - a2*x1;
00091 
00092         // QUAD 3
00093         x1 = 0; y1 = yNeg + offset; x2 = xNeg + offset; y2 = 0;
00094         a3 = (y1 - y2)/(x1 - x2);
00095         b3 = y1 - a3*x1;
00096 
00097         // QUAD 4
00098         x1 = 0; y1 = yNeg + offset; x2 = xPos - offset; y2 = 0;
00099         a4 = (y1 - y2)/(x1 - x2);
00100         b4 = y1 - a4*x1;
00101 
00102 }
00103 
00104 
00106 // Overridden methods
00108 
00109 int YieldSurface_BC2D::getState(int stateInfo)
00110 {
00111         if(stateInfo == this->StateLoading)
00112                 return isLoading;
00113         else
00114                 return -1;
00115 }
00116 
00117 int YieldSurface_BC2D::commitState(Vector &force)
00118 {
00119         this->YieldSurface_BC::commitState(force);
00120         
00121         status_hist = this->getTrialForceLocation(force);
00122 //    opserr << "YieldSurface_BC2D::commitState(..), status = " << status_hist << endln;
00123 
00124 //      opserr << "YieldSurface_BC2D::commitState " << getTag() <<" - force location: " << status_hist << endln;
00125 //      opserr << " FORCE = " << force;
00126         if(status_hist > 0)
00127         {
00128                 opserr << "WARNING - YieldSurface_BC2D::commitState(..) [" << getTag()<<"]\n";
00129                 opserr << "Can't commit with force outside the surface\n";
00130                 opserr << "\a";
00131         }
00132 
00133         double driftOld = this->getDrift(fx_hist, fy_hist);
00134         double driftNew = this->getTrialDrift(force);
00135         isLoading = 0;
00136         if(status_hist >= 0)
00137         {
00138                 isLoading = 1;
00139         }
00140         else
00141         {
00142                 if(driftOld < driftNew) // drift will be negative
00143                         isLoading = 1;
00144         }
00145                 
00146         //hModel->commitState(status_hist);
00147         hModel->commitState();
00148 
00149         toLocalSystem(force, fx_hist, fy_hist, true);
00150         hModel->toOriginalCoord(fx_hist, fy_hist);
00151         
00152         // opserr << "yPos = " << yPos << ", fy = " << fy_hist << endln;
00153         if(fy_hist/yPos > 0.85)
00154                 hModel->setDeformable(true);
00155         else
00156                 hModel->setDeformable(false); 
00157 
00158         gx_hist = 0;
00159         gy_hist = 0;
00160 
00161         if(status_hist==0)
00162         {
00163                 // double fx = fx_hist;
00164                 // double fy = fy_hist;
00165 
00166                 // hModel->toOriginalCoord(fx, fy);
00167                 getGradient(gx_hist, gy_hist, fx_hist, fy_hist);
00168         }
00169 
00170         return 0;
00171 }
00172 
00173 
00174 int YieldSurface_BC2D::update(int flag)
00175 {
00176         return hModel->update(flag);
00177 }
00178 
00179 
00180 int YieldSurface_BC2D::revertToLastCommit(void)
00181 {
00182         hModel->revertToLastCommit();
00183         return 0;
00184 }
00185 
00186 // assuming in original coordinates, return value does not account
00187 // for any isotropic factor
00188 Vector& YieldSurface_BC2D::translationTo(Vector &f_new, Vector &f_dir)
00189 {
00190         double x1 = f_dir(0);
00191         double y1 = f_dir(1);
00192 
00193         double x2 = f_new(0);
00194         double y2 = f_new(1);
00195 
00196         // first find the point to interpolate to
00197         bool is_hardening = true;
00198         state = 1;
00199         
00200         double hi = getDrift(x2, y2);
00201                 if(hi < 0)
00202                 {
00203                         is_hardening = false;
00204                         state = -1;
00205                 }
00206         if(fabs(hi) < 1e-12) state = 0;
00207 
00208 //      opserr << "Drift New = " << hi <<endl;
00209 //      opserr << "F new = " << f_new;
00210         
00211         hi = 5*fabs(hi); //approx half to interpolate - that didn't work for all cases
00212         // changed from factor of 2 to 5
00213         // radial/normal evolution -> no problem
00214         // for bounding surface, dir. of evolution with hardening may cause the
00215         // interpolation end point (xi, yi) to be out side
00216 
00217         double h = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
00218         double c = hi/h;
00219         double sign= -1.0;
00220 
00221     if(c > 1.0)
00222     {
00223                 opserr << "oops - YieldSurface_BC2D::translationTo - c > 1.0 \n";
00224                 c = 1.0;
00225         }
00226 
00227         if(!is_hardening)
00228         sign = 1.0;
00229 
00230 //      double xi = x2 + sign*c*fabs(x2 - x1);
00231 //      double yi = y2 + sign*c*fabs(y2 - y1); 
00232         double xi = x2 + sign*c*(x2 - x1);
00233         double yi = y2 + sign*c*(y2 - y1);
00234         
00235     if(is_hardening) // Fi inside, Fnew outside
00236     {
00237         double t = interpolate(xi, yi, x2, y2);
00238         T2(0) = (1 - t)*(x2 - xi);
00239         T2(1) = (1 - t)*(y2 - yi);
00240     }
00241     else // Fnew inside, Fi outside
00242     {
00243         double t = interpolate(x2, y2, xi, yi);
00244         T2(0) = t*(x2 - xi);
00245         T2(1) = t*(y2 - yi);
00246     }
00247 
00248 //      opserr << "F New = " << f_new;
00249 //      opserr << "F dir = " << f_dir;
00250 //      opserr << "Translation vector = " << v2;
00251         
00252         return T2;
00253 }
00254 
00255 // magPlasticDefo is based on incremental force
00256 // we always modify the surface only if the last conv force was on the
00257 // surface, otherwise we'll just set to surface if it shoots through
00258 
00259 // return value >  0 --> surface is expanding
00260 // return value == 0 --> surface unchanged
00261 // return value <  0 --> surface is shrinking
00262 int YieldSurface_BC2D::modifySurface(double magPlasticDefo, Vector &Fsurface, Matrix &G, int flag)
00263 {
00264 
00265 // check 1
00266         if( this->getTrialForceLocation(Fsurface) !=0)
00267         {
00268                 opserr << "Can't modify surface with Force Location = " << getTrialForceLocation(Fsurface) << endln;
00269                 return 0;
00270         }
00271 
00272 
00273 // check 2
00274         if(magPlasticDefo < 0)
00275         {
00276                 opserr << "\nYieldSurface_BC2D::modifySurface(..) \n";
00277                 opserr << "Warning -   magPlasticDefo < 0 " << magPlasticDefo << "\n";
00278                 // magPlasticDefo = 0;
00279                 return 0;
00280         }
00281 
00282 
00283         double fx, fy, fx_def, fy_def, gx, gy;
00284 
00285         toLocalSystem(Fsurface, fx_def, fy_def, true);
00286         // set to ys coordinates
00287         toLocalSystem(G, gx, gy, false, true);
00288 
00289         F2(0) = fx_def;
00290         F2(1) = fy_def;
00291         g2(0) = gx;
00292         g2(1) = gy;
00293 
00294         hModel->evolveSurface(this, magPlasticDefo, g2, F2, flag);
00295         
00296         /*double  isotropicFactor      = hModel->getTrialIsotropicFactor(0);
00297         double  isotropicFactor_hist = hModel->getCommitIsotropicFactor(0);
00298 
00299         int res;
00300         if( fabs (fabs(isotropicFactor) - fabs(isotropicFactor_hist)) < 1e-13) // remains same
00301         {
00302                 res = 0;
00303         }
00304         else if(isotropicFactor > isotropicFactor_hist) // surface is expanding
00305         {
00306                 res = 1;
00307         }
00308         else if(isotropicFactor < isotropicFactor_hist)
00309         {
00310                 res = -1;
00311         }
00312         else
00313                 opserr << "ModifySurface - this condition should not happen\n";
00314     */
00315         return state;
00316 
00317 }
00318 
00319 
00320 void YieldSurface_BC2D::getCommitGradient(Matrix &G)
00321 {
00322 double gx = gx_hist;
00323 double gy = gy_hist;
00324 
00325         toElementSystem(G, gx, gy, false, true);
00326 }
00327 
00328 void YieldSurface_BC2D::getTrialGradient(Matrix &G, Vector &force)
00329 {
00330 double gx, gy, fx, fy;
00331 
00332 
00333 
00334         toLocalSystem(force, fx, fy, true);
00335         hModel->toOriginalCoord(fx, fy);
00336 
00337 //      double drift = getDrift(fx, fy);
00338 //      opserr << "YieldSurface_BC2D::getTrialGradient  trial_drift: " << this->getTrialDrift(force)
00339 //               << "  drift: " << drift << endln;
00340 //      opserr << "----> calling getGradient " << endln;
00341 
00342     getGradient(gx, gy, fx, fy);
00343 //      opserr << "<---- done calling getGradient " << endln;
00344 
00345         toElementSystem(G, gx, gy, false, true);
00346 }
00347 
00348 
00349 double YieldSurface_BC2D::getTrialDrift(Vector &force)
00350 {
00351 double fx, fy;
00352         toLocalSystem(force, fx, fy, true);
00353         hModel->toOriginalCoord(fx, fy);
00354 double drift = getDrift(fx, fy);
00355 
00356     return drift;
00357 }
00358 
00359 
00360 // used by the element
00361 int YieldSurface_BC2D::getTrialForceLocation(Vector &force)
00362 {
00363 double drift = this->getTrialDrift(force);
00364                 return this->forceLocation(drift);
00365 }
00366 
00367 int YieldSurface_BC2D::getCommitForceLocation()
00368 {
00369         return status_hist;
00370 }
00371 
00372 // used by the yield surface
00373 // here we decide on what we define as outside, inside
00374 // and on the surface
00375 // -1 -> inside
00376 //  0 -> within
00377 // +1 -> outside
00378 int  YieldSurface_BC2D::forceLocation(double drift)
00379 {
00380 double tolNeg = 0.00;
00381 double tolPos = 1e-5;
00382 
00383 int        status = -2;
00384 
00385         // first get rid of -1e-13, etc
00386         if(fabs(drift) < 1e-7)
00387         drift = 0;
00388 
00389         if(drift <  -tolNeg)
00390         {
00391                 status = -1; //inside
00392         }
00393         else if(drift >= -tolNeg && drift <= tolPos) // on the surface
00394     {
00395         status = 0;
00396     }
00397         else if(drift > tolPos) // outside the surface
00398         {
00399                 status = 1;
00400         }
00401         else
00402         {
00403                 opserr << "YieldSurface_BC2D::forceLocation(double drift) - this condition not possible\n";
00404                 opserr << "\a";
00405         }
00406 
00407         return status;
00408 }
00409 
00410 void YieldSurface_BC2D::addPlasticStiffness(Matrix &K)
00411 {
00412 Vector v2 = hModel->getEquiPlasticStiffness();
00413 
00414        v6.Zero();
00415 double kpX =  v2(0);
00416 double kpY =  v2(1);
00417 
00418 //void toElementSystem(Vector &eleVector, double &x, double &y);
00419       toElementSystem(v6, kpX, kpY, false, false);
00420 
00421       for(int i=0; i<6; i++)
00422       {
00423         K(i,i) += v6(i);
00424       }
00425 
00426 }
00427 
00428 
00429 double YieldSurface_BC2D::getDrift(double x, double y)
00430 {
00431 
00432 double sdrift = getSurfaceDrift(x, y);
00433 
00434 // if sdrift > 0, trust it to be outside but if
00435 // sdrift < 0, the point may be either inside
00436 // or outside.  Reason is that surfaces close
00437 // on themselves nicely, but may deform or
00438 // open up while expanding.
00439 
00440 //      if(sdrift > 0)
00441 //              return sdrift;
00442 
00443 // Now sdrift < 0, if it is inside the internal
00444 // quad, sdrift is correct
00445 
00446 double R_xy = sqrt(x*x + y*y);
00447 //double x_in, y_in, R_in; //internal
00448 double x0, y0, R0; // intersection
00449 
00450 // find the point where the line joining 0,0 and x,y
00451 // intersects the internal quad -> x_in, y_in (R_in)
00452 
00453         if(x!=0)
00454         {
00455         double x1 =0, y1 = 0;
00456         double x2 = x, y2 = y;
00457         double a_ext = (y1 - y2)/(x1 - x2);
00458         double b_ext =  y1 - a_ext*x1;
00459         double a_int, b_int;
00460 
00461         // y = a_ext*x +b_ext
00462                 if(x > 0 && y >=0)
00463                 {
00464                         a_int = a1;
00465                         b_int = b1;
00466                 }
00467                 else if(x < 0 && y >= 0)
00468                 {
00469                         a_int = a2;
00470                         b_int = b2;
00471                 }
00472                 else if(x < 0 && y <= 0)
00473                 {
00474                         a_int = a3;
00475                         b_int = b3;
00476                 }
00477                 else if(x > 0 && y <= 0)
00478                 {
00479                         a_int = a4;
00480                         b_int = b4;
00481                 }
00482                 else  // happened to be
00483                         opserr << "YieldSurface_BC2D::getDrift(..) - condition not possible, x = " << x << ", y = " << y << endln;
00484 
00485                 if(driftDebug)
00486                 {
00487                         opserr << "Equation Internal: a = " << a_int << ", b = " << b_int << "\n";
00488                         opserr << "Equation External: a = " << a_ext << ", b = " << b_ext << "\n";
00489                 }
00490                 x0 = -(b_int - b_ext)/(a_int - a_ext);
00491                 y0 = a_int*x0 + b_int;
00492         }
00493         else // x = 0
00494         {
00495                 if(y >= 0)
00496                 {
00497                         x0 = 0;
00498                         y0 = yPos - offset;
00499                 }
00500                 else
00501                 {
00502                         x0 = 0;
00503                         y0 = yNeg + offset;
00504                 }
00505         }
00506 
00507         R0 = sqrt(x0*x0 + y0*y0);
00508 
00509         if(driftDebug)
00510         {
00511                 opserr << "R_xy = " << R_xy << " (x= " << x << ", y= " << y << "), R0 = " << R0;
00512                 opserr << " (x0= " << x0 << ", y0= " << y0 << ")\n";
00513         }
00514 
00515         // If the R_xy < R0, then the point is inside the
00516         // internal quad, sdrift is correct
00517         if(R_xy < R0)
00518         {
00519                 if(driftDebug)
00520                 {
00521                         opserr << " R_xy < R0, returning sdrift " << sdrift << "\n";
00522                         opserr << "\a";
00523                 }
00524                 return sdrift;
00525         }
00526         // Now the point can be between the inner quad and the ys
00527         // or outside the surface
00528 
00529         if(R0 == 0)
00530                 opserr << "ERROR: YieldSurface_BC2D::getDrift(..) - R0 = 0 (yPos="<<yPos<<", yNeg="<<yNeg<<"\n";
00531 
00532 double delx = (x0/R0)*increment; // increment already defined
00533 double dely = (y0/R0)*increment;
00534 
00535 double xOld, yOld, xNew, yNew;
00536 double xi, yi, Ri; //incremental
00537 
00538         xOld = x0;
00539         yOld = y0;
00540 
00541 int count = 0;
00542         while(1)
00543         {
00544                 Ri = sqrt(xOld*xOld + yOld*yOld);
00545 
00546                 // check if point is between the inner quad and
00547                 // the yield surface
00548                 if(R_xy < Ri)
00549                 {
00550                         if(driftDebug)
00551                         {
00552                                 opserr << " R_xy < Ri, returning sdrift " << sdrift << "\n";
00553                                 opserr << "\a";
00554                         }
00555                         return sdrift;
00556                 }
00557                 xNew = xOld + delx;
00558                 yNew = yOld + dely;
00559 
00560                 if(getSurfaceDrift(xNew, yNew) > 0) // we just crossed the surface
00561                 {
00562                         double t = interpolateClose(xOld, yOld, xNew, yNew);
00563                         xi =  xOld + t*delx;
00564                         yi =  yOld + t*dely;
00565 
00566                         Ri = sqrt(xi*xi + yi*yi);
00567 
00568                         if(driftDebug)
00569                         {
00570                                 opserr << " Set to surface at xi = " << xi << ", yi = " << yi << ", Ri = " << Ri << "\n";
00571                                 opserr << " Returning drift " << R_xy - Ri << "\n";
00572                                 opserr << "\a";
00573                         }
00574                         return (R_xy - Ri);
00575                 }
00576 
00577                 xOld = xNew;
00578                 yOld = yNew;
00579                 count++;
00580                 if(count > 100)
00581                 {
00582                         opserr << "ERROR: YieldSurface_BC2D::getDrift(..) - not converging\n";
00583                         opserr << "\a";
00584                 }
00585 
00586         }
00587 
00588         opserr << "YieldSurface_BC2D::getDrift(..) - should not reach here\n";
00589         opserr << "\a";
00590 
00591         return sdrift;
00592 }
00593 
00594 
00595 
00596 
00598 // Other
00600 
00601 void YieldSurface_BC2D::customizeInterpolate(double &xi, double &yi, double &xj, double &yj)
00602 {
00603 double yCheck = yNeg;
00604 
00605         if(yj > 0)
00606                 yCheck = yPos;
00607 
00608         if(fabs(yj) > fabs(yCheck)) // switch to radial - whatever the case
00609         {
00610                 xi = 0;
00611                 yi = 0;
00612         }
00613 
00614 }
00615 
00616 double  YieldSurface_BC2D::interpolate(double xi, double yi, double xj, double yj)
00617 {
00618         this->customizeInterpolate(xi, yi, xj, yj);
00619 
00620 //check
00621 double di = getDrift(xi, yi);
00622 double dj = getDrift(xj, yj);
00623         
00624  if(di > 0 && fabs(di) < 1e-7)
00625    return 0;
00626  if(dj < 0 && fabs(dj) < 1e-7)
00627    return 1;
00628 
00629  if( di > 0)
00630    {
00631                 opserr << "ERROR - YieldSurface_BC2D::interpolate(xi, yi, xj, yj)\n";
00632                 opserr << "point 1 is outside\n";
00633                 opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< di<<"\n";
00634                 opserr << "\a";
00635                 return 0;
00636         }
00637         else if(   dj <0 )
00638         {
00639                 opserr << "ERROR - YieldSurface_BC2D::interpolate(xi, yi, xj, yj)\n";
00640                 opserr << "point 2 is inside\n";
00641                 opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< dj<<"\n";
00642                 hModel->Print(opserr);
00643                 opserr << "\a";
00644                 return 0;
00645         }
00646 
00647 double tr, tu, tl, dtu, dtl, dtr=100;
00648 double dy = yj - yi;
00649 double dx = xj - xi;
00650 int count = 0;
00651         tu = 1; tl =0;
00652 
00653         //double d = getDrift(xi, yi, false);
00654         //if(d>0) opserr << "WARNING - Orbison2D::interpolate, Drift inside > 0 (" << d << ")\n";
00655 
00656         while(fabs(dtr) > 1.0e-7)
00657         {
00658                 count++;
00659                 if(count > 1000)
00660                 {
00661                         opserr << "\nYieldSurface_BC2D::Interpolate()-> Error: Unable to converge\n";
00662                         opserr << "xi, yi: " << xi << ","<< yi << "\t xj, yj: " << xj << "," << yj << "\n";
00663                         opserr << "Drift Point j = " << dj << "\n";
00664                         hModel->Print(opserr);
00665                         opserr << "\a";
00666                         return 1;
00667                 }
00668 
00669                 dtl = getDrift(xi + tl*dx, yi + tl*dy);
00670                 dtu = getDrift(xi + tu*dx, yi + tu*dy);
00671 
00672                 tr      =       tu - (  dtu*(tl - tu)/(dtl - dtu)  );
00673                 dtr = getDrift(xi + tr*dx, yi + tr*dy);
00674 
00675                 if(dtr >= 0)
00676                 {
00677                         if(dtu >= 0)
00678                                 tu = tr;
00679                         else
00680                                 tl = tr;
00681                 }
00682                 else
00683                 {
00684                         if(dtu < 0)
00685                                 tu = tr;
00686                         else
00687                                 tl = tr;
00688                 }
00689 
00690         }// while
00691         //opserr << "opserr for iterpolation = " << count << "\n"; 5 ~ 15
00692         return tr;
00693 }
00694 
00695 double  YieldSurface_BC2D::interpolateClose(double xi, double yi, double xj, double yj)
00696 {
00697 
00698 //check
00699 double di = getSurfaceDrift(xi, yi);
00700 double dj = getSurfaceDrift(xj, yj);
00701         if( di > 0)
00702         {
00703                 opserr << "ERROR - YieldSurface_BC2D::interpolateClose(xi, yi, xj, yj)\n";
00704                 opserr << "point 1 is outside\n";
00705                 opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< di<<"\n";
00706                 opserr << "\a";
00707                 return 0;
00708         }
00709         else if(   dj <0 )
00710         {
00711                 opserr << "ERROR - YieldSurface_BC2D::interpolateClose(xi, yi, xj, yj)\n";
00712                 opserr << "point 2 is inside\n";
00713                 opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< dj<<"\n";
00714                 hModel->Print(opserr);
00715                 opserr << "\a";
00716                 return 0;
00717         }
00718 
00719 double tr, tu, tl, dtu, dtl, dtr=100;
00720 double dy = yj - yi;
00721 double dx = xj - xi;
00722 int count = 0;
00723         tu = 1; tl =0;
00724 
00725         //double d = getDrift(xi, yi, false);
00726         //if(d>0) opserr << "WARNING - Orbison2D::interpolate, Drift inside > 0 (" << d << ")\n";
00727 
00728         while(fabs(dtr) > 1.0e-7)
00729         {
00730                 count++;
00731                 if(count > 1000)
00732                 {
00733                         opserr << "\nYieldSurface_BC2D::InterpolateClose()-> Error: Unable to converge\n";
00734                         opserr << "xi, yi: " << xi << ","<< yi << "\t xj, yj: " << xj << "," << yj << "\n";
00735                         hModel->Print(opserr);
00736                         opserr << "\a";
00737                         return 1;
00738                 }
00739 
00740                 dtl = getSurfaceDrift(xi + tl*dx, yi + tl*dy);
00741                 dtu = getSurfaceDrift(xi + tu*dx, yi + tu*dy);
00742 
00743                 tr      =       tu - (  dtu*(tl - tu)/(dtl - dtu)  );
00744                 dtr = getSurfaceDrift(xi + tr*dx, yi + tr*dy);
00745 
00746                 if(dtr >= 0)
00747                 {
00748                         if(dtu >= 0)
00749                                 tu = tr;
00750                         else
00751                                 tl = tr;
00752                 }
00753                 else
00754                 {
00755                         if(dtu < 0)
00756                                 tu = tr;
00757                         else
00758                                 tl = tr;
00759                 }
00760 
00761         }// while
00762         //opserr << "opserr for iterpolation = " << count << "\n"; 5 ~ 15
00763         return tr;
00764 }
00765 
00766 double YieldSurface_BC2D::setToSurface(Vector &force, int algoType, int color)
00767 {
00768 double x2, y2;
00769 double xi, yi, xj, yj;
00770 double dx, dy, t;
00771 double x, y;
00772 
00773         if(returnDebug)
00774         {
00775                 opserr << "\nYieldSurface_BC2D::setToSurface(Vector &force, int algoType)\n";
00776                 opserr << "Element system force = " << force << "\n";
00777         }
00778 
00779         // if force point is already on surface,
00780         // no need to proceed further
00781     if(getTrialForceLocation(force) == 0)
00782         return 0;
00783 
00784 
00785         toLocalSystem(force, x2, y2, true);
00786         xj = x2;
00787         yj = y2;
00788 
00789         hModel->toOriginalCoord(xj, yj);
00790 
00791         if(color != 0)
00792         {
00793                 theView->clearImage();
00794                 this->displaySelf(*theView, 1, 1);
00795                 theView->startImage();
00796                 this->displayForcePoint(false, xj, yj, color);
00797         }
00798 
00799 
00800         if(returnDebug)
00801         {
00802                 opserr << "Local system force - " << "fx = " << x2 << ",\tfy = " << y2 << "\n";
00803                 opserr << "toOriginalCoord    - " << "fx = " << xj << ",\tfy = " << yj << "\n";
00804         }
00805 
00806                 switch(algoType)
00807                 {
00808                         case 0: //dFReturn:
00809                         {
00810                                 xi = fx_hist;
00811                                 yi = fy_hist;
00812                                 // hModel->toOriginalCoord(xi, yi); - stored as that
00813 
00814                                 break;
00815                         }
00816 
00817                         case 1: //RadialReturn:
00818                         {
00819                                 xi = 0;
00820                                 yi = 0;
00821 
00822                                 break;
00823 
00824                         }
00825 
00826                         case 2: //ConstantXReturn:
00827                         {
00828                                 xi = xj;
00829                                 yi = 0;                                         //if point is outside the ys
00830 
00831                                 if(getDrift(xj, yj) < 0)        //point is inside the ys
00832                                 {
00833                                   //opserr << "ConstantXReturn - Point is inside: " << getDrift(xj, yj) << "\n";
00834                                         if(yj < 0)                              //point is below x-axis
00835                                                 yj = yj - 1;
00836                                         else
00837                                                 yj = yj + 1;
00838                                 }
00839                                 break;
00840                         }
00841 
00842 
00843                         case 3: //ConstantYReturn:
00844                         {
00845                                 xi = 0;                                         //if point is outside the ys
00846                                 yi = yj;
00847 
00848                                 if(getDrift(xj, yj) < 0)        //point is inside the ys
00849                                 {
00850                                     //opserr << " ConstantYReturn - Point Inside\n"; //
00851                                         if(xj < 0)                              //point is left of y-axis
00852                                                 xj = xj - 1;
00853                                 else
00854                                                 xj = xj + 1;
00855                                 }
00856                                 break;
00857                         }
00858 
00859 
00860                         default:
00861                         {
00862                                 opserr << "YieldSurface_BC2D: Method not implemented yet\n";
00863                                 xi = 0; yi = 0; //revert to radial return
00864                                 break;
00865                         }
00866                 }//switch
00867 
00868                 dx = xj - xi;
00869                 dy = yj - yi;
00870 
00871                 t =  interpolate(xi, yi, xj, yj);
00872                 x =  xi + t*dx;
00873                 y =  yi + t*dy;
00874 
00875                 if(color != 0)
00876                 {
00877                         this->displayForcePoint(false, x, y, color);
00878                         theView->doneImage();
00879                         opserr << "\a";
00880                 }
00881 
00882                 hModel->toDeformedCoord(x, y);
00883 
00884                 toElementSystem(force, x, y, true);
00885 
00886         return t;
00887 }
00888 
00889 int YieldSurface_BC2D::displaySelf(Renderer &theViewer, int displayMode, float fact)
00890 {
00891         if(displayMode == this->SurfOnly)
00892                 return 0;
00893 
00894         hModel->displaySelf(theViewer, this->SurfOnly, fact);
00895         
00896 Vector p1(3), p2(3);
00897 Vector rgb(3);
00898 // Draw the axis
00899 rgb(0) = 0.8; rgb(1) = 0.8; rgb(2) = 0.8;
00900  double d = 0.04;
00901 
00902         p1(0) =  -10;
00903         p1(1) =    0;
00904         p2(0) =   10;
00905         p2(1) =    0;
00906         theViewer.drawLine(p1, p2, rgb, rgb);
00907 
00908         p1(0) =    0;
00909         p1(1) =  -10;
00910         p2(0) =    0;
00911         p2(1) =   10;
00912         theViewer.drawLine(p1, p2, rgb, rgb);
00913 // Mark every 0.5
00914         for(double i=-10; i <= 10; i = i+ 0.5)
00915           {
00916                 p1(0) = -d;
00917                 p1(1) = i;
00918                 p2(0) = d;
00919                 p2(1) = i;
00920                 theViewer.drawLine(p1, p2, rgb, rgb);
00921           }
00922         for(double j=-10; j <= 10; j = j+0.5)
00923           {
00924                 p1(0) = j;
00925                 p1(1) = -d;
00926                 p2(0) = j;
00927                 p2(1) = d;
00928                 theViewer.drawLine(p1, p2, rgb, rgb);
00929           }
00930 
00931         this->displayCommitForcePoint(theViewer, displayMode, fact);
00932         this->displayForcePoint(true, 0.0, 0.0, 0);
00933 
00934         // draw the 4 quadrants - to make sure that the
00935         // line coef are correct, just need 1 point between
00936         // tested okay for Orbison, Attalla, Hajjar
00937         // return here till more surfaces have to be tested
00938 
00939         if(!driftDebug)
00940         {
00941                 return 0;
00942         }
00943 
00944         // quad 1
00945         p1(0) = 0;
00946         p1(1) = yPos - offset;
00947 
00948         p2(0) = 0.5;
00949         p2(1) = a1*p2(0) + b1;
00950         theViewer.drawLine(p1, p2, rgb, rgb);
00951 
00952         p1(0) = xPos - offset;
00953         p1(1) = 0;
00954         theViewer.drawLine(p1, p2, rgb, rgb);
00955 
00956 
00957         // quad 2
00958         p1(0) = 0;
00959         p1(1) = yPos - offset;
00960 
00961         p2(0) = -0.5;
00962         p2(1) = a2*p2(0) + b2;
00963         theViewer.drawLine(p1, p2, rgb, rgb);
00964 
00965         p1(0) = xNeg + offset;
00966         p1(1) = 0;
00967         theViewer.drawLine(p1, p2, rgb, rgb);
00968 
00969         // quad 3
00970         p1(0) = 0;
00971         p1(1) = yNeg + offset;
00972 
00973         p2(0) = -0.5;
00974         p2(1) = a3*p2(0) + b3;
00975         theViewer.drawLine(p1, p2, rgb, rgb);
00976 
00977         p1(0) = xNeg + offset;
00978         p1(1) = 0;
00979         theViewer.drawLine(p1, p2, rgb, rgb);
00980 
00981         // quad 4
00982         p1(0) = 0;
00983         p1(1) = yNeg + offset;
00984 
00985         p2(0) = 0.5;
00986         p2(1) = a4*p2(0) + b4;
00987         theViewer.drawLine(p1, p2, rgb, rgb);
00988 
00989         p1(0) = xPos - offset;
00990         p1(1) = 0;
00991         theViewer.drawLine(p1, p2, rgb, rgb);
00992 
00993         return 0;
00994 }
00995 
00996 int YieldSurface_BC2D::displayCommitForcePoint(Renderer &theViewer, int displayMode, float fact)
00997 {
00998 Vector p1(3), p2(3);
00999 Vector rgb(3);
01000 rgb(0) = 1; rgb(1) = 0; rgb(2) = 0;
01001 //  toOriginalCoord(fx_hist, fy_hist);
01002 double isotropicFactor = hModel->getCommitIsotropicFactor(0);
01003 double del = 0.1*isotropicFactor;//( (fx_hist + fy_hist)/2);
01004  if(del< 0.05) del = 0.05;
01005 
01006 double fx = fx_hist;
01007 double fy = fy_hist;
01008 
01009         hModel->toDeformedCoord(fx, fy);
01010 
01011         p1(0) =  fx - del;
01012         p1(1) =  fy;
01013         p2(0) =  fx + del;
01014         p2(1) =  fy;
01015         theViewer.drawLine(p1, p2, rgb, rgb);
01016 
01017         p1(0) =  fx;
01018         p1(1) =  fy - del;
01019         p2(0) =  fx;
01020         p2(1) =  fy + del;
01021         theViewer.drawLine(p1, p2, rgb, rgb);
01022 
01023         return 0;
01024 }
01025 
01026 
01027 int YieldSurface_BC2D::displayForcePoint(Vector &force, int color)
01028 {
01029  if(!theView)
01030                 return -1;
01031 
01032         double x, y;
01033         toLocalSystem(force, x, y, true);
01034 
01035         theView->startImage();
01036                 displayForcePoint(false, x, y, color);
01037         theView->doneImage();
01038 
01039         return 0;
01040 }
01041 // color can be r, g or b
01042 int YieldSurface_BC2D::displayForcePoint(bool toDeformed, double f_x, double f_y, int color)
01043 {
01044 Vector p1(3), p2(3);
01045 Vector rgb(3);
01046 
01047         if(!theView)
01048                 return -1;
01049 
01050         if(color== 1)
01051         {
01052                 rgb(0) = 1; rgb(1) = 0; rgb(2) = 0;
01053         }
01054         else if(color == 2)
01055         {
01056        rgb(0) = 0; rgb(1) = 1; rgb(2) = 0;
01057         }
01058     else if(color == 3)
01059         {
01060        rgb(0) = 0; rgb(1) = 0; rgb(2) = 1;
01061         }
01062         else
01063         {
01064                 rgb(0) = 0; rgb(1) = 0; rgb(2) = 0;
01065         }
01066 //  toOriginalCoord(fx_hist, fy_hist);
01067 /*
01068 double isotropicFactor = hModel->getTrialIsotropicFactor(0);
01069 double del = 0.1*isotropicFactor;//( (fx_hist + fy_hist)/2);
01070  if(del< 0.05) del = 0.05;
01071 */
01072 double fx = f_x;
01073 double fy = f_y;
01074 
01075         if(toDeformed)
01076                 hModel->toDeformedCoord(fx, fy);
01077 
01078         v2(0) = fx;
01079         v2(1) = fy;
01080 
01081         theView->drawPoint(v2, rgb, 3);
01082 /*
01083         p1(0) =  fx - del;
01084         p1(1) =  fy;
01085         p2(0) =  fx + del;
01086         p2(1) =  fy;
01087         theView->drawLine(p1, p2, rgb, rgb);
01088 
01089         p1(0) =  fx;
01090         p1(1) =  fy - del;
01091         p2(0) =  fx;
01092         p2(1) =  fy + del;
01093         theView->drawLine(p1, p2, rgb, rgb);
01094 */
01095         return 0;
01096 }
01097 
01098 

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