Subversion Repositories OpenSees

Rev

Rev 1796 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1118 fmk 1
// YieldSurface_BC2D.cpp: implementation of the YieldSurfaceBC class.
2
//
3
//////////////////////////////////////////////////////////////////////
4
 
5
#include "YieldSurface_BC2D.h"
6
#define modifDebug  0
7
#define returnDebug 0
8
#define transDebug  0
9
#define driftDebug  0
10
 
11
#include <MaterialResponse.h>
4628 fmk 12
#include <math.h>
1118 fmk 13
 
14
double YieldSurface_BC2D::error(1.0e-6);
15
Vector YieldSurface_BC2D::v6(6);
16
Vector YieldSurface_BC2D::T2(2);
17
Vector YieldSurface_BC2D::F2(2);
18
Vector YieldSurface_BC2D::g2(2);
19
Vector YieldSurface_BC2D::v2(2);
20
Vector YieldSurface_BC2D::v4(4);
21
 
22
 
23
//////////////////////////////////////////////////////////////////////
24
// Construction/Destruction
25
//////////////////////////////////////////////////////////////////////
26
 
27
YieldSurface_BC2D::YieldSurface_BC2D(int tag, int classTag, double xmax, double ymax,
28
                  YS_Evolution &model)
29
:YieldSurface_BC(tag, classTag, model, xmax, ymax)
30
{
31
        status_hist = -1; //elastic
32
 
33
        fx_hist = 0;
34
        fy_hist = 0;
35
 
36
        offset     = 0.01;
37
        increment  = 0.022;
38
 
39
        state = 0;
40
 
41
}
42
 
43
YieldSurface_BC2D::~YieldSurface_BC2D()
44
{
45
 
46
}
47
 
48
const Vector &YieldSurface_BC2D::getExtent(void)
49
{
50
        v4(0) = xPos;
51
        v4(1) = xNeg;
52
        v4(2) = yPos;
53
        v4(3) = yNeg;
54
 
55
        return v4;
56
}
57
 
58
 
59
//////////////////////////////////////////////////////////////////////
60
// Transformation
61
//////////////////////////////////////////////////////////////////////
62
 
63
// Use this function to initialize other stuff
64
void YieldSurface_BC2D::setTransformation(int xDof, int yDof, int xFact, int yFact)
65
{
66
        this->YieldSurface_BC::setTransformation(xDof, yDof, xFact, yFact);
67
 
68
        this->setExtent();
69
        if(xPos == 0 && yPos == 0 && xNeg ==0 && yNeg == 0)
70
        {
1271 fmk 71
                opserr << "WARNING - YieldSurface_BC2D - surface extent not set correctly\n";
1118 fmk 72
        }
73
 
74
        if(xPos == 0 || xNeg == 0)
1271 fmk 75
                opserr << "Error - YieldSurface_BC2D no X extent\n";
1118 fmk 76
 
77
        ////////////////////////////////////////////////////////
78
        // Next set the 'a' and 'b' for the internal quad
79
        ////////////////////////////////////////////////////////
80
 
81
double x1, y1, x2, y2;
82
 
83
        // QUAD 1
84
        x1 = 0; y1 = yPos - offset ; x2 = xPos - offset; y2 = 0;
85
        a1 = (y1 - y2)/(x1 - x2);
86
        b1 = y1 - a1*x1;
87
 
88
        // QUAD 2
89
        x1 = 0; y1 = yPos - offset; x2 = xNeg + offset; y2 = 0;
90
        a2 = (y1 - y2)/(x1 - x2);
91
        b2 = y1 - a2*x1;
92
 
93
        // QUAD 3
94
        x1 = 0; y1 = yNeg + offset; x2 = xNeg + offset; y2 = 0;
95
        a3 = (y1 - y2)/(x1 - x2);
96
        b3 = y1 - a3*x1;
97
 
98
        // QUAD 4
99
        x1 = 0; y1 = yNeg + offset; x2 = xPos - offset; y2 = 0;
100
        a4 = (y1 - y2)/(x1 - x2);
101
        b4 = y1 - a4*x1;
102
 
103
}
104
 
105
 
106
//////////////////////////////////////////////////////////////////////
107
// Overridden methods
108
//////////////////////////////////////////////////////////////////////
109
 
110
int YieldSurface_BC2D::getState(int stateInfo)
111
{
112
        if(stateInfo == this->StateLoading)
113
                return isLoading;
114
        else
115
                return -1;
116
}
117
 
118
int YieldSurface_BC2D::commitState(Vector &force)
119
{
120
        this->YieldSurface_BC::commitState(force);
121
 
122
        status_hist = this->getTrialForceLocation(force);
1433 fmk 123
//    opserr << "YieldSurface_BC2D::commitState(..), status = " << status_hist << endln;
1118 fmk 124
 
1433 fmk 125
//      opserr << "YieldSurface_BC2D::commitState " << getTag() <<" - force location: " << status_hist << endln;
126
//      opserr << " FORCE = " << force;
1118 fmk 127
        if(status_hist > 0)
128
        {
1271 fmk 129
                opserr << "WARNING - YieldSurface_BC2D::commitState(..) [" << getTag()<<"]\n";
130
                opserr << "Can't commit with force outside the surface\n";
1433 fmk 131
                opserr << "\a";
1118 fmk 132
        }
133
 
134
        double driftOld = this->getDrift(fx_hist, fy_hist);
135
        double driftNew = this->getTrialDrift(force);
136
        isLoading = 0;
137
        if(status_hist >= 0)
138
        {
139
                isLoading = 1;
140
        }
141
        else
142
        {
143
                if(driftOld < driftNew) // drift will be negative
144
                        isLoading = 1;
145
        }
146
 
1433 fmk 147
        //hModel->commitState(status_hist);
148
        hModel->commitState();
1118 fmk 149
 
150
        toLocalSystem(force, fx_hist, fy_hist, true);
151
        hModel->toOriginalCoord(fx_hist, fy_hist);
1433 fmk 152
 
153
        // opserr << "yPos = " << yPos << ", fy = " << fy_hist << endln;
154
        if(fy_hist/yPos > 0.85)
155
                hModel->setDeformable(true);
156
        else
157
                hModel->setDeformable(false);
1118 fmk 158
 
159
        gx_hist = 0;
160
        gy_hist = 0;
161
 
162
        if(status_hist==0)
163
        {
164
                // double fx = fx_hist;
165
                // double fy = fy_hist;
166
 
167
                // hModel->toOriginalCoord(fx, fy);
168
                getGradient(gx_hist, gy_hist, fx_hist, fy_hist);
169
        }
170
 
171
        return 0;
172
}
173
 
174
 
175
int YieldSurface_BC2D::update(int flag)
176
{
177
        return hModel->update(flag);
178
}
179
 
180
 
181
int YieldSurface_BC2D::revertToLastCommit(void)
182
{
183
        hModel->revertToLastCommit();
184
        return 0;
185
}
186
 
187
// assuming in original coordinates, return value does not account
188
// for any isotropic factor
189
Vector& YieldSurface_BC2D::translationTo(Vector &f_new, Vector &f_dir)
190
{
191
        double x1 = f_dir(0);
192
        double y1 = f_dir(1);
193
 
194
        double x2 = f_new(0);
195
        double y2 = f_new(1);
196
 
197
        // first find the point to interpolate to
198
        bool is_hardening = true;
199
        state = 1;
200
 
201
        double hi = getDrift(x2, y2);
202
                if(hi < 0)
203
                {
204
                        is_hardening = false;
205
                        state = -1;
206
                }
207
        if(fabs(hi) < 1e-12) state = 0;
208
 
1433 fmk 209
//      opserr << "Drift New = " << hi <<endl;
210
//      opserr << "F new = " << f_new;
1118 fmk 211
 
212
        hi = 5*fabs(hi); //approx half to interpolate - that didn't work for all cases
213
        // changed from factor of 2 to 5
214
        // radial/normal evolution -> no problem
215
        // for bounding surface, dir. of evolution with hardening may cause the
216
        // interpolation end point (xi, yi) to be out side
217
 
218
        double h = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
219
        double c = hi/h;
220
        double sign= -1.0;
221
 
222
    if(c > 1.0)
223
    {
1271 fmk 224
                opserr << "oops - YieldSurface_BC2D::translationTo - c > 1.0 \n";
1118 fmk 225
                c = 1.0;
226
        }
227
 
228
        if(!is_hardening)
229
        sign = 1.0;
230
 
231
//      double xi = x2 + sign*c*fabs(x2 - x1);
232
//      double yi = y2 + sign*c*fabs(y2 - y1); 
233
        double xi = x2 + sign*c*(x2 - x1);
234
        double yi = y2 + sign*c*(y2 - y1);
235
 
236
    if(is_hardening) // Fi inside, Fnew outside
237
    {
238
        double t = interpolate(xi, yi, x2, y2);
239
        T2(0) = (1 - t)*(x2 - xi);
240
        T2(1) = (1 - t)*(y2 - yi);
241
    }
242
    else // Fnew inside, Fi outside
243
    {
244
        double t = interpolate(x2, y2, xi, yi);
245
        T2(0) = t*(x2 - xi);
246
        T2(1) = t*(y2 - yi);
247
    }
248
 
1433 fmk 249
//      opserr << "F New = " << f_new;
250
//      opserr << "F dir = " << f_dir;
251
//      opserr << "Translation vector = " << v2;
1118 fmk 252
 
253
        return T2;
254
}
255
 
256
// magPlasticDefo is based on incremental force
257
// we always modify the surface only if the last conv force was on the
258
// surface, otherwise we'll just set to surface if it shoots through
259
 
260
// return value >  0 --> surface is expanding
261
// return value == 0 --> surface unchanged
262
// return value <  0 --> surface is shrinking
1122 mhscott 263
int YieldSurface_BC2D::modifySurface(double magPlasticDefo, Vector &Fsurface, Matrix &G, int flag)
1118 fmk 264
{
265
 
266
// check 1
267
        if( this->getTrialForceLocation(Fsurface) !=0)
268
        {
1271 fmk 269
                opserr << "Can't modify surface with Force Location = " << getTrialForceLocation(Fsurface) << endln;
1118 fmk 270
                return 0;
271
        }
272
 
273
 
274
// check 2
275
        if(magPlasticDefo < 0)
276
        {
1271 fmk 277
                opserr << "\nYieldSurface_BC2D::modifySurface(..) \n";
278
                opserr << "Warning -   magPlasticDefo < 0 " << magPlasticDefo << "\n";
1118 fmk 279
                // magPlasticDefo = 0;
280
                return 0;
281
        }
282
 
283
 
284
        double fx, fy, fx_def, fy_def, gx, gy;
285
 
286
        toLocalSystem(Fsurface, fx_def, fy_def, true);
287
        // set to ys coordinates
288
        toLocalSystem(G, gx, gy, false, true);
289
 
290
        F2(0) = fx_def;
291
        F2(1) = fy_def;
292
        g2(0) = gx;
293
        g2(1) = gy;
294
 
295
        hModel->evolveSurface(this, magPlasticDefo, g2, F2, flag);
296
 
297
        /*double  isotropicFactor      = hModel->getTrialIsotropicFactor(0);
298
        double  isotropicFactor_hist = hModel->getCommitIsotropicFactor(0);
299
 
300
        int res;
301
        if( fabs (fabs(isotropicFactor) - fabs(isotropicFactor_hist)) < 1e-13) // remains same
302
        {
303
                res = 0;
304
        }
305
        else if(isotropicFactor > isotropicFactor_hist) // surface is expanding
306
        {
307
                res = 1;
308
        }
309
        else if(isotropicFactor < isotropicFactor_hist)
310
        {
311
                res = -1;
312
        }
313
        else
1271 fmk 314
                opserr << "ModifySurface - this condition should not happen\n";
1118 fmk 315
    */
316
        return state;
317
 
318
}
319
 
320
 
321
void YieldSurface_BC2D::getCommitGradient(Matrix &G)
322
{
323
double gx = gx_hist;
324
double gy = gy_hist;
325
 
326
        toElementSystem(G, gx, gy, false, true);
327
}
328
 
329
void YieldSurface_BC2D::getTrialGradient(Matrix &G, Vector &force)
330
{
331
double gx, gy, fx, fy;
332
 
333
 
334
 
335
        toLocalSystem(force, fx, fy, true);
336
        hModel->toOriginalCoord(fx, fy);
337
 
338
//      double drift = getDrift(fx, fy);
1271 fmk 339
//      opserr << "YieldSurface_BC2D::getTrialGradient  trial_drift: " << this->getTrialDrift(force)
340
//               << "  drift: " << drift << endln;
341
//      opserr << "----> calling getGradient " << endln;
1118 fmk 342
 
343
    getGradient(gx, gy, fx, fy);
1271 fmk 344
//      opserr << "<---- done calling getGradient " << endln;
1118 fmk 345
 
346
        toElementSystem(G, gx, gy, false, true);
347
}
348
 
349
 
350
double YieldSurface_BC2D::getTrialDrift(Vector &force)
351
{
352
double fx, fy;
353
        toLocalSystem(force, fx, fy, true);
354
        hModel->toOriginalCoord(fx, fy);
355
double drift = getDrift(fx, fy);
356
 
357
    return drift;
358
}
359
 
360
 
361
// used by the element
362
int YieldSurface_BC2D::getTrialForceLocation(Vector &force)
363
{
364
double drift = this->getTrialDrift(force);
365
                return this->forceLocation(drift);
366
}
367
 
368
int YieldSurface_BC2D::getCommitForceLocation()
369
{
370
        return status_hist;
371
}
372
 
373
// used by the yield surface
374
// here we decide on what we define as outside, inside
375
// and on the surface
376
// -1 -> inside
377
//  0 -> within
378
// +1 -> outside
379
int  YieldSurface_BC2D::forceLocation(double drift)
380
{
381
double tolNeg = 0.00;
382
double tolPos = 1e-5;
383
 
384
int        status = -2;
385
 
386
        // first get rid of -1e-13, etc
387
        if(fabs(drift) < 1e-7)
388
        drift = 0;
389
 
390
        if(drift <  -tolNeg)
391
        {
392
                status = -1; //inside
393
        }
394
        else if(drift >= -tolNeg && drift <= tolPos) // on the surface
395
    {
396
        status = 0;
397
    }
398
        else if(drift > tolPos) // outside the surface
399
        {
400
                status = 1;
401
        }
402
        else
403
        {
1271 fmk 404
                opserr << "YieldSurface_BC2D::forceLocation(double drift) - this condition not possible\n";
1433 fmk 405
                opserr << "\a";
1118 fmk 406
        }
407
 
408
        return status;
409
}
410
 
411
void YieldSurface_BC2D::addPlasticStiffness(Matrix &K)
412
{
413
Vector v2 = hModel->getEquiPlasticStiffness();
414
 
415
       v6.Zero();
416
double kpX =  v2(0);
417
double kpY =  v2(1);
418
 
419
//void toElementSystem(Vector &eleVector, double &x, double &y);
420
      toElementSystem(v6, kpX, kpY, false, false);
421
 
422
      for(int i=0; i<6; i++)
423
      {
424
        K(i,i) += v6(i);
425
      }
426
 
427
}
428
 
429
 
430
double YieldSurface_BC2D::getDrift(double x, double y)
431
{
432
 
433
double sdrift = getSurfaceDrift(x, y);
434
 
435
// if sdrift > 0, trust it to be outside but if
436
// sdrift < 0, the point may be either inside
437
// or outside.  Reason is that surfaces close
438
// on themselves nicely, but may deform or
439
// open up while expanding.
440
 
441
//      if(sdrift > 0)
442
//              return sdrift;
443
 
444
// Now sdrift < 0, if it is inside the internal
445
// quad, sdrift is correct
446
 
447
double R_xy = sqrt(x*x + y*y);
448
//double x_in, y_in, R_in; //internal
449
double x0, y0, R0; // intersection
450
 
451
// find the point where the line joining 0,0 and x,y
452
// intersects the internal quad -> x_in, y_in (R_in)
453
 
454
        if(x!=0)
455
        {
456
        double x1 =0, y1 = 0;
457
        double x2 = x, y2 = y;
458
        double a_ext = (y1 - y2)/(x1 - x2);
459
        double b_ext =  y1 - a_ext*x1;
460
        double a_int, b_int;
461
 
462
        // y = a_ext*x +b_ext
463
                if(x > 0 && y >=0)
464
                {
465
                        a_int = a1;
466
                        b_int = b1;
467
                }
468
                else if(x < 0 && y >= 0)
469
                {
470
                        a_int = a2;
471
                        b_int = b2;
472
                }
473
                else if(x < 0 && y <= 0)
474
                {
475
                        a_int = a3;
476
                        b_int = b3;
477
                }
478
                else if(x > 0 && y <= 0)
479
                {
480
                        a_int = a4;
481
                        b_int = b4;
482
                }
483
                else  // happened to be
1271 fmk 484
                        opserr << "YieldSurface_BC2D::getDrift(..) - condition not possible, x = " << x << ", y = " << y << endln;
1118 fmk 485
 
486
                if(driftDebug)
487
                {
1271 fmk 488
                        opserr << "Equation Internal: a = " << a_int << ", b = " << b_int << "\n";
489
                        opserr << "Equation External: a = " << a_ext << ", b = " << b_ext << "\n";
1118 fmk 490
                }
491
                x0 = -(b_int - b_ext)/(a_int - a_ext);
492
                y0 = a_int*x0 + b_int;
493
        }
494
        else // x = 0
495
        {
496
                if(y >= 0)
497
                {
498
                        x0 = 0;
499
                        y0 = yPos - offset;
500
                }
501
                else
502
                {
503
                        x0 = 0;
504
                        y0 = yNeg + offset;
505
                }
506
        }
507
 
508
        R0 = sqrt(x0*x0 + y0*y0);
509
 
510
        if(driftDebug)
511
        {
1271 fmk 512
                opserr << "R_xy = " << R_xy << " (x= " << x << ", y= " << y << "), R0 = " << R0;
513
                opserr << " (x0= " << x0 << ", y0= " << y0 << ")\n";
1118 fmk 514
        }
515
 
516
        // If the R_xy < R0, then the point is inside the
517
        // internal quad, sdrift is correct
518
        if(R_xy < R0)
519
        {
520
                if(driftDebug)
521
                {
1271 fmk 522
                        opserr << " R_xy < R0, returning sdrift " << sdrift << "\n";
1433 fmk 523
                        opserr << "\a";
1118 fmk 524
                }
525
                return sdrift;
526
        }
527
        // Now the point can be between the inner quad and the ys
528
        // or outside the surface
529
 
530
        if(R0 == 0)
1271 fmk 531
                opserr << "ERROR: YieldSurface_BC2D::getDrift(..) - R0 = 0 (yPos="<<yPos<<", yNeg="<<yNeg<<"\n";
1118 fmk 532
 
533
double delx = (x0/R0)*increment; // increment already defined
534
double dely = (y0/R0)*increment;
535
 
536
double xOld, yOld, xNew, yNew;
537
double xi, yi, Ri; //incremental
538
 
539
        xOld = x0;
540
        yOld = y0;
541
 
542
int count = 0;
543
        while(1)
544
        {
545
                Ri = sqrt(xOld*xOld + yOld*yOld);
546
 
547
                // check if point is between the inner quad and
548
                // the yield surface
549
                if(R_xy < Ri)
550
                {
551
                        if(driftDebug)
552
                        {
1271 fmk 553
                                opserr << " R_xy < Ri, returning sdrift " << sdrift << "\n";
1433 fmk 554
                                opserr << "\a";
1118 fmk 555
                        }
556
                        return sdrift;
557
                }
558
                xNew = xOld + delx;
559
                yNew = yOld + dely;
560
 
561
                if(getSurfaceDrift(xNew, yNew) > 0) // we just crossed the surface
562
                {
563
                        double t = interpolateClose(xOld, yOld, xNew, yNew);
564
                        xi =  xOld + t*delx;
565
                        yi =  yOld + t*dely;
566
 
567
                        Ri = sqrt(xi*xi + yi*yi);
568
 
569
                        if(driftDebug)
570
                        {
1271 fmk 571
                                opserr << " Set to surface at xi = " << xi << ", yi = " << yi << ", Ri = " << Ri << "\n";
572
                                opserr << " Returning drift " << R_xy - Ri << "\n";
1433 fmk 573
                                opserr << "\a";
1118 fmk 574
                        }
575
                        return (R_xy - Ri);
576
                }
577
 
578
                xOld = xNew;
579
                yOld = yNew;
580
                count++;
581
                if(count > 100)
582
                {
1271 fmk 583
                        opserr << "ERROR: YieldSurface_BC2D::getDrift(..) - not converging\n";
1433 fmk 584
                        opserr << "\a";
1118 fmk 585
                }
586
 
587
        }
588
 
1271 fmk 589
        opserr << "YieldSurface_BC2D::getDrift(..) - should not reach here\n";
1433 fmk 590
        opserr << "\a";
1118 fmk 591
 
592
        return sdrift;
593
}
594
 
595
 
596
 
597
 
598
//////////////////////////////////////////////////////////////////////
599
// Other
600
//////////////////////////////////////////////////////////////////////
601
 
602
void YieldSurface_BC2D::customizeInterpolate(double &xi, double &yi, double &xj, double &yj)
603
{
604
double yCheck = yNeg;
605
 
606
        if(yj > 0)
607
                yCheck = yPos;
608
 
609
        if(fabs(yj) > fabs(yCheck)) // switch to radial - whatever the case
610
        {
611
                xi = 0;
612
                yi = 0;
613
        }
614
 
615
}
616
 
617
double  YieldSurface_BC2D::interpolate(double xi, double yi, double xj, double yj)
618
{
619
        this->customizeInterpolate(xi, yi, xj, yj);
620
 
621
//check
622
double di = getDrift(xi, yi);
623
double dj = getDrift(xj, yj);
624
 
1796 fmk 625
 if(di > 0 && fabs(di) < 1e-7)
626
   return 0;
627
 if(dj < 0 && fabs(dj) < 1e-7)
628
   return 1;
1118 fmk 629
 
1796 fmk 630
 if( di > 0)
631
   {
1271 fmk 632
                opserr << "ERROR - YieldSurface_BC2D::interpolate(xi, yi, xj, yj)\n";
633
                opserr << "point 1 is outside\n";
634
                opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< di<<"\n";
1433 fmk 635
                opserr << "\a";
1118 fmk 636
                return 0;
637
        }
638
        else if(   dj <0 )
639
        {
1271 fmk 640
                opserr << "ERROR - YieldSurface_BC2D::interpolate(xi, yi, xj, yj)\n";
641
                opserr << "point 2 is inside\n";
642
                opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< dj<<"\n";
643
                hModel->Print(opserr);
1433 fmk 644
                opserr << "\a";
1118 fmk 645
                return 0;
646
        }
647
 
648
double tr, tu, tl, dtu, dtl, dtr=100;
649
double dy = yj - yi;
650
double dx = xj - xi;
651
int count = 0;
652
        tu = 1; tl =0;
653
 
654
        //double d = getDrift(xi, yi, false);
1271 fmk 655
        //if(d>0) opserr << "WARNING - Orbison2D::interpolate, Drift inside > 0 (" << d << ")\n";
1118 fmk 656
 
657
        while(fabs(dtr) > 1.0e-7)
658
        {
659
                count++;
660
                if(count > 1000)
661
                {
1271 fmk 662
                        opserr << "\nYieldSurface_BC2D::Interpolate()-> Error: Unable to converge\n";
663
                        opserr << "xi, yi: " << xi << ","<< yi << "\t xj, yj: " << xj << "," << yj << "\n";
664
                        opserr << "Drift Point j = " << dj << "\n";
665
                        hModel->Print(opserr);
1433 fmk 666
                        opserr << "\a";
1118 fmk 667
                        return 1;
668
                }
669
 
670
                dtl = getDrift(xi + tl*dx, yi + tl*dy);
671
                dtu = getDrift(xi + tu*dx, yi + tu*dy);
672
 
673
                tr      =       tu - (  dtu*(tl - tu)/(dtl - dtu)  );
674
                dtr = getDrift(xi + tr*dx, yi + tr*dy);
675
 
676
                if(dtr >= 0)
677
                {
678
                        if(dtu >= 0)
679
                                tu = tr;
680
                        else
681
                                tl = tr;
682
                }
683
                else
684
                {
685
                        if(dtu < 0)
686
                                tu = tr;
687
                        else
688
                                tl = tr;
689
                }
690
 
691
        }// while
1271 fmk 692
        //opserr << "opserr for iterpolation = " << count << "\n"; 5 ~ 15
1118 fmk 693
        return tr;
694
}
695
 
696
double  YieldSurface_BC2D::interpolateClose(double xi, double yi, double xj, double yj)
697
{
698
 
699
//check
700
double di = getSurfaceDrift(xi, yi);
701
double dj = getSurfaceDrift(xj, yj);
702
        if( di > 0)
703
        {
1271 fmk 704
                opserr << "ERROR - YieldSurface_BC2D::interpolateClose(xi, yi, xj, yj)\n";
705
                opserr << "point 1 is outside\n";
706
                opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< di<<"\n";
1433 fmk 707
                opserr << "\a";
1118 fmk 708
                return 0;
709
        }
710
        else if(   dj <0 )
711
        {
1271 fmk 712
                opserr << "ERROR - YieldSurface_BC2D::interpolateClose(xi, yi, xj, yj)\n";
713
                opserr << "point 2 is inside\n";
714
                opserr << xi << "," << yi << "  " << xj << "," << yj << " : "<< dj<<"\n";
715
                hModel->Print(opserr);
1433 fmk 716
                opserr << "\a";
1118 fmk 717
                return 0;
718
        }
719
 
720
double tr, tu, tl, dtu, dtl, dtr=100;
721
double dy = yj - yi;
722
double dx = xj - xi;
723
int count = 0;
724
        tu = 1; tl =0;
725
 
726
        //double d = getDrift(xi, yi, false);
1271 fmk 727
        //if(d>0) opserr << "WARNING - Orbison2D::interpolate, Drift inside > 0 (" << d << ")\n";
1118 fmk 728
 
729
        while(fabs(dtr) > 1.0e-7)
730
        {
731
                count++;
732
                if(count > 1000)
733
                {
1271 fmk 734
                        opserr << "\nYieldSurface_BC2D::InterpolateClose()-> Error: Unable to converge\n";
735
                        opserr << "xi, yi: " << xi << ","<< yi << "\t xj, yj: " << xj << "," << yj << "\n";
736
                        hModel->Print(opserr);
1433 fmk 737
                        opserr << "\a";
1118 fmk 738
                        return 1;
739
                }
740
 
741
                dtl = getSurfaceDrift(xi + tl*dx, yi + tl*dy);
742
                dtu = getSurfaceDrift(xi + tu*dx, yi + tu*dy);
743
 
744
                tr      =       tu - (  dtu*(tl - tu)/(dtl - dtu)  );
745
                dtr = getSurfaceDrift(xi + tr*dx, yi + tr*dy);
746
 
747
                if(dtr >= 0)
748
                {
749
                        if(dtu >= 0)
750
                                tu = tr;
751
                        else
752
                                tl = tr;
753
                }
754
                else
755
                {
756
                        if(dtu < 0)
757
                                tu = tr;
758
                        else
759
                                tl = tr;
760
                }
761
 
762
        }// while
1271 fmk 763
        //opserr << "opserr for iterpolation = " << count << "\n"; 5 ~ 15
1118 fmk 764
        return tr;
765
}
766
 
767
double YieldSurface_BC2D::setToSurface(Vector &force, int algoType, int color)
768
{
769
double x2, y2;
770
double xi, yi, xj, yj;
771
double dx, dy, t;
772
double x, y;
773
 
774
        if(returnDebug)
775
        {
1271 fmk 776
                opserr << "\nYieldSurface_BC2D::setToSurface(Vector &force, int algoType)\n";
777
                opserr << "Element system force = " << force << "\n";
1118 fmk 778
        }
779
 
780
        // if force point is already on surface,
781
        // no need to proceed further
782
    if(getTrialForceLocation(force) == 0)
783
        return 0;
784
 
785
 
786
        toLocalSystem(force, x2, y2, true);
787
        xj = x2;
788
        yj = y2;
789
 
790
        hModel->toOriginalCoord(xj, yj);
791
 
792
        if(color != 0)
793
        {
794
                theView->clearImage();
795
                this->displaySelf(*theView, 1, 1);
796
                theView->startImage();
797
                this->displayForcePoint(false, xj, yj, color);
798
        }
799
 
800
 
801
        if(returnDebug)
802
        {
1271 fmk 803
                opserr << "Local system force - " << "fx = " << x2 << ",\tfy = " << y2 << "\n";
804
                opserr << "toOriginalCoord    - " << "fx = " << xj << ",\tfy = " << yj << "\n";
1118 fmk 805
        }
806
 
807
                switch(algoType)
808
                {
809
                        case 0: //dFReturn:
810
                        {
811
                                xi = fx_hist;
812
                                yi = fy_hist;
813
                                // hModel->toOriginalCoord(xi, yi); - stored as that
814
 
815
                                break;
816
                        }
817
 
818
                        case 1: //RadialReturn:
819
                        {
820
                                xi = 0;
821
                                yi = 0;
822
 
823
                                break;
824
 
825
                        }
826
 
827
                        case 2: //ConstantXReturn:
828
                        {
829
                                xi = xj;
830
                                yi = 0;                                         //if point is outside the ys
831
 
832
                                if(getDrift(xj, yj) < 0)        //point is inside the ys
833
                                {
1271 fmk 834
                                  //opserr << "ConstantXReturn - Point is inside: " << getDrift(xj, yj) << "\n";
1118 fmk 835
                                        if(yj < 0)                              //point is below x-axis
836
                                                yj = yj - 1;
837
                                        else
838
                                                yj = yj + 1;
839
                                }
840
                                break;
841
                        }
842
 
843
 
844
                        case 3: //ConstantYReturn:
845
                        {
846
                                xi = 0;                                         //if point is outside the ys
847
                                yi = yj;
848
 
849
                                if(getDrift(xj, yj) < 0)        //point is inside the ys
850
                                {
1271 fmk 851
                                    //opserr << " ConstantYReturn - Point Inside\n"; //
1118 fmk 852
                                        if(xj < 0)                              //point is left of y-axis
853
                                                xj = xj - 1;
854
                                else
855
                                                xj = xj + 1;
856
                                }
857
                                break;
858
                        }
859
 
860
 
861
                        default:
862
                        {
1271 fmk 863
                                opserr << "YieldSurface_BC2D: Method not implemented yet\n";
1118 fmk 864
                                xi = 0; yi = 0; //revert to radial return
865
                                break;
866
                        }
867
                }//switch
868
 
869
                dx = xj - xi;
870
                dy = yj - yi;
871
 
872
                t =  interpolate(xi, yi, xj, yj);
873
                x =  xi + t*dx;
874
                y =  yi + t*dy;
875
 
876
                if(color != 0)
877
                {
878
                        this->displayForcePoint(false, x, y, color);
879
                        theView->doneImage();
1433 fmk 880
                        opserr << "\a";
1118 fmk 881
                }
882
 
883
                hModel->toDeformedCoord(x, y);
884
 
885
                toElementSystem(force, x, y, true);
886
 
887
        return t;
888
}
889
 
890
int YieldSurface_BC2D::displaySelf(Renderer &theViewer, int displayMode, float fact)
891
{
892
        if(displayMode == this->SurfOnly)
893
                return 0;
894
 
895
        hModel->displaySelf(theViewer, this->SurfOnly, fact);
896
 
897
Vector p1(3), p2(3);
898
Vector rgb(3);
899
// Draw the axis
900
rgb(0) = 0.8; rgb(1) = 0.8; rgb(2) = 0.8;
901
 double d = 0.04;
902
 
903
        p1(0) =  -10;
904
        p1(1) =    0;
905
        p2(0) =   10;
906
        p2(1) =    0;
907
        theViewer.drawLine(p1, p2, rgb, rgb);
908
 
909
        p1(0) =    0;
910
        p1(1) =  -10;
911
        p2(0) =    0;
912
        p2(1) =   10;
913
        theViewer.drawLine(p1, p2, rgb, rgb);
914
// Mark every 0.5
915
        for(double i=-10; i <= 10; i = i+ 0.5)
916
          {
917
                p1(0) = -d;
918
                p1(1) = i;
919
                p2(0) = d;
920
                p2(1) = i;
921
                theViewer.drawLine(p1, p2, rgb, rgb);
922
          }
923
        for(double j=-10; j <= 10; j = j+0.5)
924
          {
925
                p1(0) = j;
926
                p1(1) = -d;
927
                p2(0) = j;
928
                p2(1) = d;
929
                theViewer.drawLine(p1, p2, rgb, rgb);
930
          }
931
 
932
        this->displayCommitForcePoint(theViewer, displayMode, fact);
933
        this->displayForcePoint(true, 0.0, 0.0, 0);
934
 
935
        // draw the 4 quadrants - to make sure that the
936
        // line coef are correct, just need 1 point between
937
        // tested okay for Orbison, Attalla, Hajjar
938
        // return here till more surfaces have to be tested
939
 
940
        if(!driftDebug)
941
        {
942
                return 0;
943
        }
944
 
945
        // quad 1
946
        p1(0) = 0;
947
        p1(1) = yPos - offset;
948
 
949
        p2(0) = 0.5;
950
        p2(1) = a1*p2(0) + b1;
951
        theViewer.drawLine(p1, p2, rgb, rgb);
952
 
953
        p1(0) = xPos - offset;
954
        p1(1) = 0;
955
        theViewer.drawLine(p1, p2, rgb, rgb);
956
 
957
 
958
        // quad 2
959
        p1(0) = 0;
960
        p1(1) = yPos - offset;
961
 
962
        p2(0) = -0.5;
963
        p2(1) = a2*p2(0) + b2;
964
        theViewer.drawLine(p1, p2, rgb, rgb);
965
 
966
        p1(0) = xNeg + offset;
967
        p1(1) = 0;
968
        theViewer.drawLine(p1, p2, rgb, rgb);
969
 
970
        // quad 3
971
        p1(0) = 0;
972
        p1(1) = yNeg + offset;
973
 
974
        p2(0) = -0.5;
975
        p2(1) = a3*p2(0) + b3;
976
        theViewer.drawLine(p1, p2, rgb, rgb);
977
 
978
        p1(0) = xNeg + offset;
979
        p1(1) = 0;
980
        theViewer.drawLine(p1, p2, rgb, rgb);
981
 
982
        // quad 4
983
        p1(0) = 0;
984
        p1(1) = yNeg + offset;
985
 
986
        p2(0) = 0.5;
987
        p2(1) = a4*p2(0) + b4;
988
        theViewer.drawLine(p1, p2, rgb, rgb);
989
 
990
        p1(0) = xPos - offset;
991
        p1(1) = 0;
992
        theViewer.drawLine(p1, p2, rgb, rgb);
993
 
994
        return 0;
995
}
996
 
997
int YieldSurface_BC2D::displayCommitForcePoint(Renderer &theViewer, int displayMode, float fact)
998
{
999
Vector p1(3), p2(3);
1000
Vector rgb(3);
1001
rgb(0) = 1; rgb(1) = 0; rgb(2) = 0;
1002
//  toOriginalCoord(fx_hist, fy_hist);
1003
double isotropicFactor = hModel->getCommitIsotropicFactor(0);
1004
double del = 0.1*isotropicFactor;//( (fx_hist + fy_hist)/2);
1005
 if(del< 0.05) del = 0.05;
1006
 
1007
double fx = fx_hist;
1008
double fy = fy_hist;
1009
 
1010
        hModel->toDeformedCoord(fx, fy);
1011
 
1012
        p1(0) =  fx - del;
1013
        p1(1) =  fy;
1014
        p2(0) =  fx + del;
1015
        p2(1) =  fy;
1016
        theViewer.drawLine(p1, p2, rgb, rgb);
1017
 
1018
        p1(0) =  fx;
1019
        p1(1) =  fy - del;
1020
        p2(0) =  fx;
1021
        p2(1) =  fy + del;
1022
        theViewer.drawLine(p1, p2, rgb, rgb);
1023
 
1024
        return 0;
1025
}
1026
 
1027
 
1028
int YieldSurface_BC2D::displayForcePoint(Vector &force, int color)
1029
{
1030
 if(!theView)
1031
                return -1;
1032
 
1033
        double x, y;
1034
        toLocalSystem(force, x, y, true);
1035
 
1036
        theView->startImage();
1037
                displayForcePoint(false, x, y, color);
1038
        theView->doneImage();
1039
 
1040
        return 0;
1041
}
1042
// color can be r, g or b
1043
int YieldSurface_BC2D::displayForcePoint(bool toDeformed, double f_x, double f_y, int color)
1044
{
1045
Vector p1(3), p2(3);
1046
Vector rgb(3);
1047
 
1048
        if(!theView)
1049
                return -1;
1050
 
1051
        if(color== 1)
1052
        {
1053
                rgb(0) = 1; rgb(1) = 0; rgb(2) = 0;
1054
        }
1055
        else if(color == 2)
1056
        {
1057
       rgb(0) = 0; rgb(1) = 1; rgb(2) = 0;
1058
        }
1059
    else if(color == 3)
1060
        {
1061
       rgb(0) = 0; rgb(1) = 0; rgb(2) = 1;
1062
        }
1063
        else
1064
        {
1065
                rgb(0) = 0; rgb(1) = 0; rgb(2) = 0;
1066
        }
1067
//  toOriginalCoord(fx_hist, fy_hist);
1068
/*
1069
double isotropicFactor = hModel->getTrialIsotropicFactor(0);
1070
double del = 0.1*isotropicFactor;//( (fx_hist + fy_hist)/2);
1071
 if(del< 0.05) del = 0.05;
1072
*/
1073
double fx = f_x;
1074
double fy = f_y;
1075
 
1076
        if(toDeformed)
1077
                hModel->toDeformedCoord(fx, fy);
1078
 
1079
        v2(0) = fx;
1080
        v2(1) = fy;
1081
 
1082
        theView->drawPoint(v2, rgb, 3);
1083
/*
1084
        p1(0) =  fx - del;
1085
        p1(1) =  fy;
1086
        p2(0) =  fx + del;
1087
        p2(1) =  fy;
1088
        theView->drawLine(p1, p2, rgb, rgb);
1089
 
1090
        p1(0) =  fx;
1091
        p1(1) =  fy - del;
1092
        p2(0) =  fx;
1093
        p2(1) =  fy + del;
1094
        theView->drawLine(p1, p2, rgb, rgb);
1095
*/
1096
        return 0;
1097
}
1098
 
1099