00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <math.h>
00013 #include <stdlib.h>
00014 #include <PressureIndependMultiYield.h>
00015 #include <Information.h>
00016 #include <ID.h>
00017 #include <MaterialResponse.h>
00018
00019 Matrix PressureIndependMultiYield::theTangent(6,6);
00020 T2Vector PressureIndependMultiYield::subStrainRate;
00021 int PressureIndependMultiYield::matCount=0;
00022 int* PressureIndependMultiYield::loadStagex=0;
00023 int* PressureIndependMultiYield::ndmx=0;
00024 double* PressureIndependMultiYield::rhox=0;
00025 double* PressureIndependMultiYield::frictionAnglex=0;
00026 double* PressureIndependMultiYield::peakShearStrainx=0;
00027 double* PressureIndependMultiYield::refPressurex=0;
00028 double* PressureIndependMultiYield::cohesionx=0;
00029 double* PressureIndependMultiYield::pressDependCoeffx=0;
00030 int* PressureIndependMultiYield::numOfSurfacesx=0;
00031 double* PressureIndependMultiYield::residualPressx=0;
00032
00033 PressureIndependMultiYield::PressureIndependMultiYield (int tag, int nd,
00034 double r, double refShearModul,
00035 double refBulkModul,
00036 double cohesi, double peakShearStra,
00037 double frictionAng, double refPress, double pressDependCoe,
00038 int numberOfYieldSurf, double * gredu)
00039 : NDMaterial(tag,ND_TAG_PressureIndependMultiYield), currentStress(),
00040 trialStress(), currentStrain(), strainRate()
00041 {
00042 if (nd !=2 && nd !=3) {
00043 opserr << "FATAL:PressureIndependMultiYield:: dimension error" << endln;
00044 opserr << "Dimension has to be 2 or 3, you give nd= " << nd << endln;
00045 exit(-1);
00046 }
00047 if (refShearModul <= 0) {
00048 opserr << "FATAL:PressureIndependMultiYield::PressureIndependMultiYield: refShearModulus <= 0" << endln;
00049 exit(-1);
00050 }
00051 if (refBulkModul <= 0) {
00052 opserr << "FATAL:PressureIndependMultiYield::PressureIndependMultiYield: refBulkModulus <= 0" << endln;
00053 exit(-1);
00054 }
00055 if (frictionAng < 0.) {
00056 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: frictionAngle < 0" << endln;
00057 opserr << "Will reset frictionAngle to zero." << endln;
00058 frictionAng = 0.;
00059 }
00060 if (frictionAng == 0. && cohesi <= 0. ) {
00061 opserr << "FATAL:PressureIndependMultiYield::PressureIndependMultiYield: frictionAngle && cohesion <= 0." << endln;
00062 exit(-1);
00063 }
00064 if (cohesi <= 0) {
00065 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: cohesion <= 0" << endln;
00066 opserr << "Will reset cohesion to zero." << endln;
00067 cohesi = 0.;
00068 }
00069 if (peakShearStra <= 0) {
00070 opserr << "FATAL:PressureIndependMultiYield::PressureIndependMultiYield: peakShearStra <= 0" << endln;
00071 exit(-1);
00072 }
00073 if (refPress <= 0) {
00074 opserr << "FATAL:PressureIndependMultiYield::PressureIndependMultiYield: refPress <= 0" << endln;
00075 exit(-1);
00076 }
00077 if (pressDependCoe < 0) {
00078 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: pressDependCoe < 0" << endln;
00079 opserr << "Will reset pressDependCoe to zero." << endln;
00080 pressDependCoe = 0.;
00081 }
00082 if (pressDependCoe > 0 && frictionAng == 0) {
00083 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: pressDependCoe > 0 while frictionAngle = 0" << endln;
00084 opserr << "Will reset pressDependCoe to zero." << endln;
00085 pressDependCoe = 0.;
00086 }
00087 if (numberOfYieldSurf <= 0) {
00088 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: numberOfSurfaces <= 0" << endln;
00089 opserr << "Will use 10 yield surfaces." << endln;
00090 numberOfYieldSurf = 10;
00091 }
00092 if (numberOfYieldSurf > 100) {
00093 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: numberOfSurfaces > 100" << endln;
00094 opserr << "Will use 100 yield surfaces." << endln;
00095 numberOfYieldSurf = 100;
00096 }
00097 if (r < 0) {
00098 opserr << "WARNING:PressureIndependMultiYield::PressureIndependMultiYield: mass density < 0" << endln;
00099 opserr << "Will use rho = 0." << endln;
00100 r = 0.;
00101 }
00102
00103 if (matCount%20 == 0) {
00104 int * temp1 = loadStagex;
00105 int * temp2 = ndmx;
00106 double * temp3 = rhox;
00107 double * temp6 = frictionAnglex;
00108 double * temp7 = peakShearStrainx;
00109 double * temp8 = refPressurex;
00110 double * temp9 = cohesionx;
00111 double * temp10 = pressDependCoeffx;
00112 int * temp11 = numOfSurfacesx;
00113 double * temp12 = residualPressx;
00114 loadStagex = new int[matCount+20];
00115 ndmx = new int[matCount+20];
00116 rhox = new double[matCount+20];
00117 frictionAnglex = new double[matCount+20];
00118 peakShearStrainx = new double[matCount+20];
00119 refPressurex = new double[matCount+20];
00120 cohesionx = new double[matCount+20];
00121 pressDependCoeffx = new double[matCount+20];
00122 numOfSurfacesx = new int[matCount+20];
00123 residualPressx = new double[matCount+20];
00124
00125 for (int i=0; i<matCount; i++) {
00126 loadStagex[i] = temp1[i];
00127 ndmx[i] = temp2[i];
00128 rhox[i] = temp3[i];
00129 frictionAnglex[i] = temp6[i];
00130 peakShearStrainx[i] = temp7[i];
00131 refPressurex[i] = temp8[i];
00132 cohesionx[i] = temp9[i];
00133 pressDependCoeffx[i] = temp10[i];
00134 numOfSurfacesx[i] = temp11[i];
00135 residualPressx[i] = temp12[i];
00136 }
00137
00138 if (matCount > 0) {
00139 delete [] temp1; delete [] temp2; delete [] temp3;
00140 delete [] temp6; delete [] temp7; delete [] temp8;
00141 delete [] temp9; delete [] temp10; delete [] temp11;
00142 delete [] temp12;
00143 }
00144 }
00145
00146 ndmx[matCount] = nd;
00147 loadStagex[matCount] = 0;
00148 refShearModulus = refShearModul;
00149 refBulkModulus = refBulkModul;
00150 frictionAnglex[matCount] = frictionAng;
00151 peakShearStrainx[matCount] = peakShearStra;
00152 refPressurex[matCount] = -refPress;
00153 cohesionx[matCount] = cohesi;
00154 pressDependCoeffx[matCount] = pressDependCoe;
00155 numOfSurfacesx[matCount] = numberOfYieldSurf;
00156 rhox[matCount] = r;
00157
00158 e2p = 0;
00159 matN = matCount;
00160 matCount ++;
00161
00162 theSurfaces = new MultiYieldSurface[numberOfYieldSurf+1];
00163 committedSurfaces = new MultiYieldSurface[numberOfYieldSurf+1];
00164 activeSurfaceNum = committedActiveSurf = 0;
00165
00166 setUpSurfaces(gredu);
00167 }
00168
00169
00170 PressureIndependMultiYield::PressureIndependMultiYield ()
00171 : NDMaterial(0,ND_TAG_PressureIndependMultiYield),
00172 currentStress(), trialStress(), currentStrain(),
00173 strainRate(), theSurfaces(0), committedSurfaces(0)
00174 {
00175
00176 }
00177
00178
00179 PressureIndependMultiYield::PressureIndependMultiYield (const PressureIndependMultiYield & a)
00180 : NDMaterial(a.getTag(),ND_TAG_PressureIndependMultiYield),
00181 currentStress(a.currentStress), trialStress(a.trialStress),
00182 currentStrain(a.currentStrain), strainRate(a.strainRate)
00183 {
00184 matN = a.matN;
00185 e2p = a.e2p;
00186 refShearModulus = a.refShearModulus;
00187 refBulkModulus = a.refBulkModulus;
00188
00189 int numOfSurfaces = numOfSurfacesx[matN];
00190
00191 committedActiveSurf = a.committedActiveSurf;
00192 activeSurfaceNum = a.activeSurfaceNum;
00193
00194 theSurfaces = new MultiYieldSurface[numOfSurfaces+1];
00195 committedSurfaces = new MultiYieldSurface[numOfSurfaces+1];
00196 for(int i=1; i<=numOfSurfaces; i++) {
00197 committedSurfaces[i] = a.committedSurfaces[i];
00198 theSurfaces[i] = a.theSurfaces[i];
00199 }
00200 }
00201
00202
00203 PressureIndependMultiYield::~PressureIndependMultiYield ()
00204 {
00205 if (theSurfaces != 0) delete [] theSurfaces;
00206 if (committedSurfaces != 0) delete [] committedSurfaces;
00207 }
00208
00209
00210 void PressureIndependMultiYield::elast2Plast(void)
00211 {
00212 int loadStage = loadStagex[matN];
00213 double frictionAngle = frictionAnglex[matN];
00214 int numOfSurfaces = numOfSurfacesx[matN];
00215
00216 if (loadStage != 1 || e2p == 1) return;
00217 e2p = 1;
00218
00219 if (currentStress.volume() > 0. && frictionAngle > 0.) {
00220
00221 currentStress.setData(currentStress.deviator(),0);
00222 }
00223
00224 paramScaling();
00225
00226
00227 if (currentStress.deviatorLength() == 0.) return;
00228
00229
00230 while (yieldFunc(currentStress, committedSurfaces, ++committedActiveSurf) > 0) {
00231 if (committedActiveSurf == numOfSurfaces) {
00232
00233 deviatorScaling(currentStress, committedSurfaces, numOfSurfaces);
00234 initSurfaceUpdate();
00235 return;
00236 }
00237 }
00238 committedActiveSurf--;
00239 initSurfaceUpdate();
00240 }
00241
00242
00243 int PressureIndependMultiYield::setTrialStrain (const Vector &strain)
00244 {
00245 int ndm = ndmx[matN];
00246
00247 static Vector temp(6);
00248 if (ndm==3 && strain.Size()==6)
00249 temp = strain;
00250 else if (ndm==2 && strain.Size()==3) {
00251 temp[0] = strain[0];
00252 temp[1] = strain[1];
00253 temp[2] = 0.0;
00254 temp[3] = strain[2];
00255 temp[4] = 0.0;
00256 temp[5] = 0.0;
00257 }
00258 else {
00259 opserr << "Fatal:D2PressDepMYS:: Material dimension is: " << ndm << endln;
00260 opserr << "But strain vector size is: " << strain.Size() << endln;
00261 exit(-1);
00262 }
00263
00264
00265 temp -= currentStrain.t2Vector(1);
00266 strainRate.setData(temp, 1);
00267
00268 return 0;
00269 }
00270
00271
00272 int PressureIndependMultiYield::setTrialStrain (const Vector &strain, const Vector &rate)
00273 {
00274 return setTrialStrain (strain);
00275 }
00276
00277
00278 int PressureIndependMultiYield::setTrialStrainIncr (const Vector &strain)
00279 {
00280 int ndm = ndmx[matN];
00281
00282 static Vector temp(6);
00283 if (ndm==3 && strain.Size()==6)
00284 temp = strain;
00285 else if (ndm==2 && strain.Size()==3) {
00286 temp[0] = strain[0];
00287 temp[1] = strain[1];
00288 temp[3] = strain[2];
00289 }
00290 else {
00291 opserr << "Fatal:D2PressDepMYS:: Material dimension is: " << ndm << endln;
00292 opserr << "But strain vector size is: " << strain.Size() << endln;
00293 exit(-1);
00294 }
00295
00296 strainRate.setData(temp,1);
00297 return 0;
00298 }
00299
00300
00301 int PressureIndependMultiYield::setTrialStrainIncr (const Vector &strain, const Vector &rate)
00302 {
00303 return setTrialStrainIncr(strain);
00304 }
00305
00306
00307 const Matrix & PressureIndependMultiYield::getTangent (void)
00308 {
00309 int loadStage = loadStagex[matN];
00310 int ndm = ndmx[matN];
00311
00312 if (loadStage == 1 && e2p == 0) elast2Plast();
00313
00314 if (loadStage!=1) {
00315 for (int i=0;i<6;i++)
00316 for (int j=0;j<6;j++) {
00317 theTangent(i,j) = 0.;
00318 if (i==j) theTangent(i,j) += refShearModulus;
00319 if (i<3 && j<3 && i==j) theTangent(i,j) += refShearModulus;
00320 if (i<3 && j<3) theTangent(i,j) += (refBulkModulus - 2.*refShearModulus/3.);
00321 }
00322
00323 }
00324 else {
00325 double coeff;
00326 static Vector devia(6);
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 if (activeSurfaceNum > 0) {
00338
00339 devia = trialStress.deviator();
00340 devia -= theSurfaces[activeSurfaceNum].center();
00341
00342 double size = theSurfaces[activeSurfaceNum].size();
00343 double plastModul = theSurfaces[activeSurfaceNum].modulus();
00344 coeff = 6.*refShearModulus*refShearModulus/(2.*refShearModulus+plastModul)/size/size;
00345 }
00346
00347 else coeff = 0.;
00348
00349 for (int i=0;i<6;i++)
00350 for (int j=0;j<6;j++) {
00351 theTangent(i,j) = - coeff*devia[i]*devia[j];
00352 if (i==j) theTangent(i,j) += refShearModulus;
00353 if (i<3 && j<3 && i==j) theTangent(i,j) += refShearModulus;
00354 if (i<3 && j<3) theTangent(i,j) += (refBulkModulus - 2.*refShearModulus/3.);
00355 }
00356 }
00357
00358 if (ndm==3)
00359 return theTangent;
00360 else {
00361 static Matrix workM(3,3);
00362 workM(0,0) = theTangent(0,0);
00363 workM(0,1) = theTangent(0,1);
00364 workM(0,2) = theTangent(0,3);
00365 workM(1,0) = theTangent(1,0);
00366 workM(1,1) = theTangent(1,1);
00367 workM(1,2) = theTangent(1,3);
00368 workM(2,0) = theTangent(3,0);
00369 workM(2,1) = theTangent(3,1);
00370 workM(2,2) = theTangent(3,3);
00371 return workM;
00372 }
00373 }
00374
00375
00376 const Matrix & PressureIndependMultiYield::getInitialTangent (void)
00377 {
00378 int ndm = ndmx[matN];
00379
00380 for (int i=0;i<6;i++)
00381 for (int j=0;j<6;j++) {
00382 theTangent(i,j) = 0.;
00383 if (i==j) theTangent(i,j) += refShearModulus;
00384 if (i<3 && j<3 && i==j) theTangent(i,j) += refShearModulus;
00385 if (i<3 && j<3) theTangent(i,j) += (refBulkModulus - 2.*refShearModulus/3.);
00386 }
00387
00388 if (ndm==3)
00389 return theTangent;
00390 else {
00391 static Matrix workM(3,3);
00392 workM(0,0) = theTangent(0,0);
00393 workM(0,1) = theTangent(0,1);
00394 workM(0,2) = theTangent(0,3);
00395 workM(1,0) = theTangent(1,0);
00396 workM(1,1) = theTangent(1,1);
00397 workM(1,2) = theTangent(1,3);
00398 workM(2,0) = theTangent(3,0);
00399 workM(2,1) = theTangent(3,1);
00400 workM(2,2) = theTangent(3,3);
00401 return workM;
00402 }
00403 }
00404
00405
00406 const Vector & PressureIndependMultiYield::getStress (void)
00407 {
00408 int loadStage = loadStagex[matN];
00409 int numOfSurfaces = numOfSurfacesx[matN];
00410 int ndm = ndmx[matN];
00411
00412 int i;
00413 if (loadStage == 1 && e2p == 0) elast2Plast();
00414
00415 if (loadStage!=1) {
00416
00417 getTangent();
00418 static Vector a(6);
00419 a = currentStress.t2Vector();
00420 a.addMatrixVector(1.0, theTangent, strainRate.t2Vector(1), 1.0);
00421 trialStress.setData(a);
00422 }
00423
00424 else {
00425 for (i=1; i<=numOfSurfaces; i++) theSurfaces[i] = committedSurfaces[i];
00426 activeSurfaceNum = committedActiveSurf;
00427 subStrainRate = strainRate;
00428 setTrialStress(currentStress);
00429 if (isLoadReversal()) {
00430 updateInnerSurface();
00431 activeSurfaceNum = 0;
00432 }
00433 int numSubIncre = setSubStrainRate();
00434
00435 for (i=0; i<numSubIncre; i++) {
00436 if (i==0)
00437 setTrialStress(currentStress);
00438 else
00439 setTrialStress(trialStress);
00440 if (activeSurfaceNum==0 && !isCrossingNextSurface()) continue;
00441 if (activeSurfaceNum==0) activeSurfaceNum++;
00442 stressCorrection(0);
00443 updateActiveSurface();
00444 }
00445
00446 double volum = refBulkModulus*(strainRate.volume()*3.);
00447 volum += currentStress.volume();
00448
00449 trialStress.setData(trialStress.deviator(),volum);
00450 }
00451
00452 if (ndm==3)
00453 return trialStress.t2Vector();
00454 else {
00455 static Vector workV(3);
00456 workV[0] = trialStress.t2Vector()[0];
00457 workV[1] = trialStress.t2Vector()[1];
00458 workV[2] = trialStress.t2Vector()[3];
00459 return workV;
00460 }
00461 }
00462
00463
00464 const Vector & PressureIndependMultiYield::getStrain (void)
00465 {
00466 return getCommittedStrain();
00467 }
00468
00469
00470 int PressureIndependMultiYield::commitState (void)
00471 {
00472 int loadStage = loadStagex[matN];
00473 int numOfSurfaces = numOfSurfacesx[matN];
00474
00475 currentStress = trialStress;
00476
00477
00478 static Vector temp(6);
00479 temp = currentStrain.t2Vector();
00480 temp += strainRate.t2Vector();
00481 currentStrain.setData(temp);
00482 temp.Zero();
00483 strainRate.setData(temp);
00484
00485 if (loadStage==1) {
00486 committedActiveSurf = activeSurfaceNum;
00487 for (int i=1; i<=numOfSurfaces; i++) committedSurfaces[i] = theSurfaces[i];
00488 }
00489
00490 return 0;
00491 }
00492
00493
00494 int PressureIndependMultiYield::revertToLastCommit (void)
00495 {
00496 return 0;
00497 }
00498
00499
00500 NDMaterial * PressureIndependMultiYield::getCopy (void)
00501 {
00502 PressureIndependMultiYield * copy = new PressureIndependMultiYield(*this);
00503 return copy;
00504 }
00505
00506
00507 NDMaterial * PressureIndependMultiYield::getCopy (const char *code)
00508 {
00509 if (strcmp(code,"PressureIndependMultiYield") == 0 || strcmp(code,"PlaneStrain") == 0
00510 || strcmp(code,"ThreeDimensional") == 0) {
00511 PressureIndependMultiYield * copy = new PressureIndependMultiYield(*this);
00512 return copy;
00513 }
00514
00515 return 0;
00516 }
00517
00518
00519 const char * PressureIndependMultiYield::getType (void) const
00520 {
00521 int ndm = ndmx[matN];
00522
00523 return (ndm == 2) ? "PlaneStrain" : "ThreeDimensional";
00524 }
00525
00526
00527 int PressureIndependMultiYield::getOrder (void) const
00528 {
00529 int ndm = ndmx[matN];
00530
00531 return (ndm == 2) ? 3 : 6;
00532 }
00533
00534
00535 int PressureIndependMultiYield::updateParameter(int responseID, Information &info)
00536 {
00537 if (responseID<10)
00538 loadStagex[matN] = responseID;
00539
00540 return 0;
00541 }
00542
00543
00544 int PressureIndependMultiYield::sendSelf(int commitTag, Channel &theChannel)
00545 {
00546 int loadStage = loadStagex[matN];
00547 int ndm = ndmx[matN];
00548 int numOfSurfaces = numOfSurfacesx[matN];
00549 double rho = rhox[matN];
00550 double frictionAngle = frictionAnglex[matN];
00551 double peakShearStrain = peakShearStrainx[matN];
00552 double refPressure = refPressurex[matN];
00553 double cohesion = cohesionx[matN];
00554 double pressDependCoeff = pressDependCoeffx[matN];
00555 double residualPress = residualPressx[matN];
00556
00557 int i, res = 0;
00558
00559 static ID idData(5);
00560 idData(0) = this->getTag();
00561 idData(1) = numOfSurfaces;
00562 idData(2) = loadStage;
00563 idData(3) = ndm;
00564 idData(4) = matN;
00565
00566 res += theChannel.sendID(this->getDbTag(), commitTag, idData);
00567 if (res < 0) {
00568 opserr << "PressureDependMultiYield::sendSelf -- could not send ID\n";
00569 return res;
00570 }
00571
00572 Vector data(23+numOfSurfaces*8);
00573 static Vector temp(6);
00574 data(0) = rho;
00575 data(1) = refShearModulus;
00576 data(2) = refBulkModulus;
00577 data(3) = frictionAngle;
00578 data(4) = peakShearStrain;
00579 data(5) = refPressure;
00580 data(6) = cohesion;
00581 data(7) = pressDependCoeff;
00582 data(8) = residualPress;
00583 data(9) = e2p;
00584 data(10) = committedActiveSurf;
00585
00586 temp = currentStress.t2Vector();
00587 for(i = 0; i < 6; i++) data(i+11) = temp[i];
00588
00589 temp = currentStrain.t2Vector();
00590 for(i = 0; i < 6; i++) data(i+17) = temp[i];
00591
00592 for(i = 0; i < numOfSurfaces; i++) {
00593 int k = 23 + i*8;
00594 data(k) = committedSurfaces[i+1].size();
00595 data(k+1) = committedSurfaces[i+1].modulus();
00596 temp = committedSurfaces[i+1].center();
00597 data(k+2) = temp(0);
00598 data(k+3) = temp(1);
00599 data(k+4) = temp(2);
00600 data(k+5) = temp(3);
00601 data(k+6) = temp(4);
00602 data(k+7) = temp(5);
00603 }
00604
00605 res += theChannel.sendVector(this->getDbTag(), commitTag, data);
00606 if (res < 0) {
00607 opserr << "PressureDependMultiYield::sendSelf -- could not send Vector\n";
00608 return res;
00609 }
00610
00611 return res;
00612 }
00613
00614
00615 int PressureIndependMultiYield::recvSelf(int commitTag, Channel &theChannel,
00616 FEM_ObjectBroker &theBroker)
00617 {
00618 int i, res = 0;
00619
00620 static ID idData(5);
00621
00622 res += theChannel.recvID(this->getDbTag(), commitTag, idData);
00623 if (res < 0) {
00624 opserr << "PressureDependMultiYield::recvSelf -- could not recv ID\n";
00625 return res;
00626 }
00627
00628 this->setTag((int)idData(0));
00629 int numOfSurfaces = idData(1);
00630 int loadStage = idData(2);
00631 int ndm = idData(3);
00632 matN = idData(4);
00633
00634 Vector data(23+idData(1)*8);
00635 static Vector temp(6);
00636
00637 res += theChannel.recvVector(this->getDbTag(), commitTag, data);
00638 if (res < 0) {
00639 opserr << "PressureDependMultiYield::recvSelf -- could not recv Vector\n";
00640 return res;
00641 }
00642
00643 double rho = data(0);
00644 double refShearModulus = data(1);
00645 double refBulkModulus = data(2);
00646 double frictionAngle = data(3);
00647 double peakShearStrain = data(4);
00648 double refPressure = data(5);
00649 double cohesion = data(6);
00650 double pressDependCoeff = data(7);
00651 double residualPress = data(8);
00652 e2p = data(9);
00653 committedActiveSurf = data(10);
00654
00655 for(i = 0; i < 6; i++) temp[i] = data(i+11);
00656 currentStress.setData(temp);
00657
00658 for(i = 0; i < 6; i++) temp[i] = data(i+17);
00659 currentStrain.setData(temp);
00660
00661 if (committedSurfaces != 0) {
00662 delete [] committedSurfaces;
00663 delete [] theSurfaces;
00664 }
00665
00666 theSurfaces = new MultiYieldSurface[numOfSurfaces+1];
00667 committedSurfaces = new MultiYieldSurface[numOfSurfaces+1];
00668 for (i=1; i<=numOfSurfaces; i++) {
00669 committedSurfaces[i] = MultiYieldSurface();
00670 }
00671
00672 for(i = 0; i < numOfSurfaces; i++) {
00673 int k = 23 + i*8;
00674 temp(0) = data(k+2);
00675 temp(1) = data(k+3);
00676 temp(2) = data(k+4);
00677 temp(3) = data(k+5);
00678 temp(4) = data(k+6);
00679 temp(5) = data(k+7);
00680 committedSurfaces[i+1].setData(temp, data(k), data(k+1));
00681 }
00682
00683 loadStagex[matN] = loadStage;
00684 ndmx[matN] = ndm;
00685 numOfSurfacesx[matN] = numOfSurfaces;
00686 rhox[matN] = rho;
00687 frictionAnglex[matN] = frictionAngle;
00688 peakShearStrainx[matN] = peakShearStrain;
00689 refPressurex[matN] = refPressure;
00690 cohesionx[matN] = cohesion;
00691 pressDependCoeffx[matN] = pressDependCoeff;
00692 residualPressx[matN] = residualPress;
00693
00694 return res;
00695 }
00696
00697
00698 Response*
00699 PressureIndependMultiYield::setResponse (const char **argv, int argc, Information &matInfo, OPS_Stream &output)
00700 {
00701 if (strcmp(argv[0],"stress") == 0 || strcmp(argv[0],"stresses") == 0)
00702 return new MaterialResponse(this, 1, this->getCommittedStress());
00703
00704 else if (strcmp(argv[0],"strain") == 0 || strcmp(argv[0],"strains") == 0)
00705 return new MaterialResponse(this, 2, this->getCommittedStrain());
00706
00707 else if (strcmp(argv[0],"tangent") == 0)
00708 return new MaterialResponse(this, 3, this->getTangent());
00709
00710 else if (strcmp(argv[0],"backbone") == 0) {
00711 int numOfSurfaces = numOfSurfacesx[matN];
00712 static Matrix curv(numOfSurfaces+1,(argc-1)*2);
00713 for (int i=1; i<argc; i++)
00714 curv(0,(i-1)*2) = atoi(argv[i]);
00715 return new MaterialResponse(this, 4, curv);
00716 }
00717 else
00718 return 0;
00719 }
00720
00721
00722 int PressureIndependMultiYield::getResponse (int responseID, Information &matInfo)
00723 {
00724 switch (responseID) {
00725 case -1:
00726 return -1;
00727 case 1:
00728 if (matInfo.theVector != 0)
00729 *(matInfo.theVector) = getCommittedStress();
00730 return 0;
00731 case 2:
00732 if (matInfo.theVector != 0)
00733 *(matInfo.theVector) = getCommittedStrain();
00734 return 0;
00735 case 3:
00736 if (matInfo.theMatrix != 0)
00737 *(matInfo.theMatrix) = getTangent();
00738 return 0;
00739 case 4:
00740 if (matInfo.theMatrix != 0)
00741 getBackbone(*(matInfo.theMatrix));
00742 return 0;
00743 default:
00744 return -1;
00745 }
00746 }
00747
00748
00749 void PressureIndependMultiYield::getBackbone (Matrix & bb)
00750 {
00751 double residualPress = residualPressx[matN];
00752 double refPressure = refPressurex[matN];
00753 double pressDependCoeff =pressDependCoeffx[matN];
00754 int numOfSurfaces = numOfSurfacesx[matN];
00755
00756 double vol, conHeig, scale, factor, shearModulus, stress1,
00757 stress2, strain1, strain2, plastModulus, elast_plast, gre;
00758
00759 for (int k=0; k<bb.noCols()/2; k++) {
00760 vol = bb(0,k*2);
00761 if (vol<=0.) {
00762 opserr <<k<< "\nNDMaterial " <<this->getTag()
00763 <<": invalid confinement for backbone recorder, " << vol << endln;
00764 continue;
00765 }
00766 conHeig = vol + residualPress;
00767 scale = -conHeig / (refPressure-residualPress);
00768 factor = pow(scale, pressDependCoeff);
00769 shearModulus = factor*refShearModulus;
00770 for (int i=1; i<=numOfSurfaces; i++) {
00771 if (i==1) {
00772 stress2 = committedSurfaces[i].size()*factor/sqrt(3.0);
00773 strain2 = stress2/shearModulus;
00774 bb(1,k*2) = strain2; bb(1,k*2+1) = shearModulus;
00775 } else {
00776 stress1 = stress2; strain1 = strain2;
00777 plastModulus = factor*committedSurfaces[i-1].modulus();
00778 elast_plast = 2*shearModulus*plastModulus/(2*shearModulus+plastModulus);
00779 stress2 = factor*committedSurfaces[i].size()/sqrt(3.0);
00780 strain2 = 2*(stress2-stress1)/elast_plast + strain1;
00781 gre = stress2/strain2;
00782 bb(i,k*2) = strain2; bb(i,k*2+1) = gre;
00783 }
00784 }
00785 }
00786
00787 }
00788
00789 void PressureIndependMultiYield::Print(OPS_Stream &s, int flag )
00790 {
00791 s << "PressureIndependMultiYield" << endln;
00792 }
00793
00794
00795 const Vector & PressureIndependMultiYield::getCommittedStress (void)
00796 {
00797 int ndm = ndmx[matN];
00798 int numOfSurfaces = numOfSurfacesx[matN];
00799
00800 double scale = sqrt(3./2.)*currentStress.deviatorLength()/committedSurfaces[numOfSurfaces].size();
00801 if (loadStagex[matN] != 1) scale = 0.;
00802 if (ndm==3) {
00803 static Vector temp7(7), temp6(6);
00804 temp6 = currentStress.t2Vector();
00805 temp7[0] = temp6[0];
00806 temp7[1] = temp6[1];
00807 temp7[2] = temp6[2];
00808 temp7[3] = temp6[3];
00809 temp7[4] = temp6[4];
00810 temp7[5] = temp6[5];
00811 temp7[6] = scale;
00812 return temp7;
00813 }
00814 else {
00815 static Vector temp5(5), temp6(6);
00816 temp6 = currentStress.t2Vector();
00817 temp5[0] = temp6[0];
00818 temp5[1] = temp6[1];
00819 temp5[2] = temp6[2];
00820 temp5[3] = temp6[3];
00821 temp5[4] = scale;
00822 return temp5;
00823 }
00824 }
00825
00826
00827 const Vector & PressureIndependMultiYield::getCommittedStrain (void)
00828 {
00829 int ndm = ndmx[matN];
00830
00831 if (ndm==3)
00832 return currentStrain.t2Vector(1);
00833 else {
00834 static Vector workV(3), temp6(6);
00835 temp6 = currentStrain.t2Vector(1);
00836 workV[0] = temp6[0];
00837 workV[1] = temp6[1];
00838 workV[2] = temp6[3];
00839 return workV;
00840 }
00841 }
00842
00843
00844
00845 void PressureIndependMultiYield::setUpSurfaces (double * gredu)
00846 {
00847 double residualPress = residualPressx[matN];
00848 double refPressure = refPressurex[matN];
00849 double pressDependCoeff =pressDependCoeffx[matN];
00850 int numOfSurfaces = numOfSurfacesx[matN];
00851 double frictionAngle = frictionAnglex[matN];
00852 double cohesion = cohesionx[matN];
00853 double peakShearStrain = peakShearStrainx[matN];
00854
00855 double stress1, stress2, strain1, strain2, size, elasto_plast_modul, plast_modul;
00856 double pi = 3.14159265358979;
00857 double refStrain, peakShear, coneHeight;
00858
00859 if (gredu == 0) {
00860 if (frictionAngle > 0) {
00861 double sinPhi = sin(frictionAngle * pi/180.);
00862 double Mnys = 6.*sinPhi/(3.-sinPhi);
00863 residualPress = 3.* cohesion / (sqrt(2.) * Mnys);
00864 coneHeight = - (refPressure - residualPress);
00865 peakShear = sqrt(2.) * coneHeight * Mnys / 3.;
00866 refStrain = (peakShearStrain * peakShear)
00867 / (refShearModulus * peakShearStrain - peakShear);
00868 }
00869
00870 else if (frictionAngle == 0.) {
00871 peakShear = 2*sqrt(2.)*cohesion/3;
00872 refStrain = (peakShearStrain * peakShear)
00873 / (refShearModulus * peakShearStrain - peakShear);
00874 residualPress = 0.;
00875 }
00876
00877 double stressInc = peakShear / numOfSurfaces;
00878
00879 for (int ii=1; ii<=numOfSurfaces; ii++){
00880 stress1 = ii * stressInc;
00881 stress2 = stress1 + stressInc;
00882 strain1 = stress1 * refStrain / (refShearModulus * refStrain - stress1);
00883 strain2 = stress2 * refStrain / (refShearModulus * refStrain - stress2);
00884 if (frictionAngle > 0.) size = 3. * stress1 / sqrt(2.) / coneHeight;
00885 else if (frictionAngle == 0.) size = 3. * stress1 / sqrt(2.);
00886
00887 elasto_plast_modul = 2.*(stress2 - stress1)/(strain2 - strain1);
00888
00889 if ( (2.*refShearModulus - elasto_plast_modul) <= 0)
00890 plast_modul = UP_LIMIT;
00891 else
00892 plast_modul = (2.*refShearModulus * elasto_plast_modul)/
00893 (2.*refShearModulus - elasto_plast_modul);
00894 if (plast_modul < 0) plast_modul = 0;
00895 if (plast_modul > UP_LIMIT) plast_modul = UP_LIMIT;
00896 if (ii==numOfSurfaces) plast_modul = 0;
00897
00898 static Vector temp(6);
00899 committedSurfaces[ii] = MultiYieldSurface(temp,size,plast_modul);
00900 }
00901 }
00902 else {
00903 if (frictionAngle > 0) {
00904 int ii = 2*(numOfSurfaces-1);
00905 double tmax = refShearModulus*gredu[ii]*gredu[ii+1];
00906 double Mnys = -(sqrt(3.) * tmax - 2. * cohesion) / refPressure;
00907 if (Mnys <= 0) {
00908 cohesion = sqrt(3.)/2 * tmax;
00909 frictionAngle = 0.;
00910 coneHeight = 1.;
00911 residualPress = 0.;
00912 } else {
00913 double sinPhi = 3*Mnys /(6+Mnys);
00914 if (sinPhi<0. || sinPhi>1.) {
00915 opserr <<"\nNDMaterial " <<this->getTag()<<": Invalid friction angle, please modify ref. pressure or G/Gmax curve."<<endln;
00916 exit(-1);
00917 }
00918 residualPress = 2. * cohesion / Mnys;
00919 if (residualPress < 0.01) residualPress = 0.01;
00920 coneHeight = - (refPressure - residualPress);
00921 frictionAngle = asin(sinPhi)*180/pi;
00922 }
00923 } else if (frictionAngle == 0.) {
00924 int ii = 2*(numOfSurfaces-1);
00925 double tmax = refShearModulus*gredu[ii]*gredu[ii+1];
00926 cohesion = sqrt(3.)/2 * tmax;
00927 coneHeight = 1.;
00928 residualPress = 0.;
00929 }
00930
00931 opserr << "\nNDMaterial " <<this->getTag()<<": Friction angle = "<<frictionAngle
00932 <<", Cohesion = "<<cohesion<<"\n"<<endln;
00933
00934 if (frictionAngle == 0.) pressDependCoeff = 0.;
00935
00936 for (int i=1; i<numOfSurfaces; i++) {
00937 int ii = 2*(i-1);
00938 strain1 = gredu[ii];
00939 stress1 = refShearModulus*gredu[ii+1]*strain1;
00940 strain2 = gredu[ii+2];
00941 stress2 = refShearModulus*gredu[ii+3]*strain2;
00942
00943 size = sqrt(3.) * stress1 / coneHeight;
00944 elasto_plast_modul = 2.*(stress2 - stress1)/(strain2 - strain1);
00945 if ( (2.*refShearModulus - elasto_plast_modul) <= 0)
00946 plast_modul = UP_LIMIT;
00947 else
00948 plast_modul = (2.*refShearModulus * elasto_plast_modul)/
00949 (2.*refShearModulus - elasto_plast_modul);
00950 if (plast_modul <= 0) {
00951 opserr << "\nNDMaterial " <<this->getTag()<<": Surface " << i
00952 << " has plastic modulus < 0.\n Please modify G/Gmax curve.\n"<<endln;
00953 exit(-1);
00954 }
00955 if (plast_modul > UP_LIMIT) plast_modul = UP_LIMIT;
00956
00957 static Vector temp(6);
00958 committedSurfaces[i] = MultiYieldSurface(temp,size,plast_modul);
00959
00960 if (i==(numOfSurfaces-1)) {
00961 plast_modul = 0;
00962 size = sqrt(3.) * stress2 / coneHeight;
00963 committedSurfaces[i+1] = MultiYieldSurface(temp,size,plast_modul);
00964 }
00965 }
00966 }
00967
00968 residualPressx[matN] = residualPress;
00969 frictionAnglex[matN] = frictionAngle;
00970 cohesionx[matN] = cohesion;
00971 }
00972
00973
00974 double PressureIndependMultiYield::yieldFunc(const T2Vector & stress,
00975 const MultiYieldSurface * surfaces, int surfaceNum)
00976 {
00977 static Vector temp(6);
00978
00979 temp = stress.deviator();
00980 temp -= surfaces[surfaceNum].center();
00981
00982 double sz = surfaces[surfaceNum].size();
00983 return 3./2.*(temp && temp) - sz * sz;
00984 }
00985
00986
00987 void PressureIndependMultiYield::deviatorScaling(T2Vector & stress, const MultiYieldSurface * surfaces,
00988 int surfaceNum, int count)
00989 {
00990 count++;
00991 int numOfSurfaces = numOfSurfacesx[matN];
00992
00993 double diff = yieldFunc(stress, surfaces, surfaceNum);
00994
00995 if ( surfaceNum < numOfSurfaces && diff < 0. ) {
00996 double sz = surfaces[surfaceNum].size();
00997 double deviaSz = sqrt(sz*sz + diff);
00998 static Vector devia(6);
00999 devia = stress.deviator();
01000 static Vector temp(6);
01001 temp = devia - surfaces[surfaceNum].center();
01002 double coeff = (sz-deviaSz) / deviaSz;
01003 if (coeff < 1.e-13) coeff = 1.e-13;
01004 devia.addVector(1.0, temp, coeff);
01005 stress.setData(devia, stress.volume());
01006 deviatorScaling(stress, surfaces, surfaceNum, count);
01007 }
01008
01009 if (surfaceNum==numOfSurfaces && fabs(diff) > LOW_LIMIT) {
01010 double sz = surfaces[surfaceNum].size();
01011 static Vector newDevia(6);
01012 newDevia.addVector(0.0, stress.deviator(), sz/sqrt(diff+sz*sz));
01013 stress.setData(newDevia, stress.volume());
01014 }
01015 }
01016
01017
01018 void PressureIndependMultiYield::initSurfaceUpdate()
01019 {
01020 if (committedActiveSurf == 0) return;
01021
01022 int numOfSurfaces = numOfSurfacesx[matN];
01023
01024 static Vector devia(6);
01025 devia = currentStress.deviator();
01026 double Ms = sqrt(3./2.*(devia && devia));
01027 static Vector newCenter(6);
01028
01029 if (committedActiveSurf < numOfSurfaces) {
01030
01031 newCenter.addVector(0.0, devia, 1.0-committedSurfaces[committedActiveSurf].size()/Ms);
01032 committedSurfaces[committedActiveSurf].setCenter(newCenter);
01033 }
01034
01035 for (int i=1; i<committedActiveSurf; i++) {
01036 newCenter = devia * (1. - committedSurfaces[i].size() / Ms);
01037 committedSurfaces[i].setCenter(newCenter);
01038 }
01039 }
01040
01041
01042 void PressureIndependMultiYield::paramScaling(void)
01043 {
01044 int numOfSurfaces = numOfSurfacesx[matN];
01045 double frictionAngle = frictionAnglex[matN];
01046 double residualPress = residualPressx[matN];
01047 double refPressure = refPressurex[matN];
01048 double pressDependCoeff =pressDependCoeffx[matN];
01049
01050 if (frictionAngle == 0.) return;
01051
01052 double conHeig = - (currentStress.volume() - residualPress);
01053 double scale = -conHeig / (refPressure-residualPress);
01054
01055 scale = pow(scale, pressDependCoeff);
01056 refShearModulus *= scale;
01057 refBulkModulus *= scale;
01058
01059 double plastModul, size;
01060 static Vector temp(6);
01061 for (int i=1; i<=numOfSurfaces; i++) {
01062 plastModul = committedSurfaces[i].modulus() * scale;
01063 size = committedSurfaces[i].size() * conHeig;
01064 committedSurfaces[i] = MultiYieldSurface(temp,size,plastModul);
01065 }
01066
01067 }
01068
01069
01070 void PressureIndependMultiYield::setTrialStress(T2Vector & stress)
01071 {
01072 static Vector devia(6);
01073
01074 devia = stress.deviator();
01075 devia.addVector(1.0, subStrainRate.deviator(), 2.*refShearModulus);
01076
01077 trialStress.setData(devia, stress.volume());
01078 }
01079
01080
01081 int PressureIndependMultiYield::setSubStrainRate(void)
01082 {
01083 int numOfSurfaces = numOfSurfacesx[matN];
01084
01085
01086
01087
01088 if (strainRate.isZero()) return 0;
01089
01090 double elast_plast_modulus;
01091 if (activeSurfaceNum==0)
01092 elast_plast_modulus = 2*refShearModulus;
01093 else {
01094 double plast_modulus = theSurfaces[activeSurfaceNum].modulus();
01095 elast_plast_modulus = 2*refShearModulus*plast_modulus
01096 / (2*refShearModulus+plast_modulus);
01097 }
01098 static Vector incre(6);
01099
01100 incre.addVector(0.0, strainRate.deviator(),elast_plast_modulus);
01101
01102 static T2Vector increStress;
01103 increStress.setData(incre, 0);
01104 double singleCross = theSurfaces[numOfSurfaces].size() / numOfSurfaces;
01105 double totalCross = 3.*increStress.octahedralShear() / sqrt(2.);
01106 int numOfSub = totalCross/singleCross + 1;
01107 if (numOfSub > numOfSurfaces) numOfSub = numOfSurfaces;
01108
01109 incre = strainRate.t2Vector();
01110 incre /= numOfSub;
01111 subStrainRate.setData(incre);
01112
01113 return numOfSub;
01114 }
01115
01116
01117 void
01118 PressureIndependMultiYield::getContactStress(T2Vector &contactStress)
01119 {
01120 static Vector center(6);
01121 center = theSurfaces[activeSurfaceNum].center();
01122 static Vector devia(6);
01123
01124 devia = trialStress.deviator();
01125 devia -= center;
01126
01127 double Ms = sqrt(3./2.*(devia && devia));
01128
01129 devia *= theSurfaces[activeSurfaceNum].size() / Ms;
01130 devia += center;
01131
01132 contactStress.setData(devia,trialStress.volume());
01133 }
01134
01135
01136 int PressureIndependMultiYield::isLoadReversal(void)
01137 {
01138 if(activeSurfaceNum == 0) return 0;
01139
01140 static Vector surfaceNormal(6);
01141 getSurfaceNormal(currentStress, surfaceNormal);
01142
01143
01144
01145 static Vector a(6);
01146 a = trialStress.deviator();
01147 a-= currentStress.deviator();
01148 if((a && surfaceNormal) < 0)
01149 return 1;
01150
01151 return 0;
01152 }
01153
01154
01155 void
01156 PressureIndependMultiYield::getSurfaceNormal(const T2Vector & stress, Vector &surfaceNormal)
01157 {
01158
01159
01160
01161 surfaceNormal = stress.deviator();
01162 surfaceNormal -= theSurfaces[activeSurfaceNum].center();
01163 surfaceNormal /= sqrt(surfaceNormal && surfaceNormal);
01164 }
01165
01166
01167 double PressureIndependMultiYield::getLoadingFunc(const T2Vector & contactStress,
01168 const Vector & surfaceNormal, int crossedSurface)
01169 {
01170 double loadingFunc;
01171 double temp1 = 2. * refShearModulus ;
01172 double temp2 = theSurfaces[activeSurfaceNum].modulus();
01173
01174
01175 double temp = temp1 + temp2;
01176
01177 static Vector tmp(6);
01178 tmp =trialStress.deviator();
01179 tmp -= contactStress.deviator();
01180 loadingFunc = (surfaceNormal && tmp)/temp;
01181
01182 if(crossedSurface) {
01183 double temp3 = theSurfaces[activeSurfaceNum-1].modulus();
01184 loadingFunc *= (temp3 - temp2)/temp3;
01185 }
01186
01187 return loadingFunc;
01188 }
01189
01190
01191 void PressureIndependMultiYield::stressCorrection(int crossedSurface)
01192 {
01193 static T2Vector contactStress;
01194 this->getContactStress(contactStress);
01195 static Vector surfaceNormal(6);
01196 this->getSurfaceNormal(contactStress, surfaceNormal);
01197 double loadingFunc = getLoadingFunc(contactStress, surfaceNormal, crossedSurface);
01198 static Vector devia(6);
01199
01200
01201 devia.addVector(0.0, surfaceNormal, -2*refShearModulus*loadingFunc);
01202 devia += trialStress.deviator();
01203
01204 trialStress.setData(devia, trialStress.volume());
01205 deviatorScaling(trialStress, theSurfaces, activeSurfaceNum);
01206
01207 if (isCrossingNextSurface()) {
01208 activeSurfaceNum++;
01209 stressCorrection(1);
01210 }
01211 }
01212
01213
01214 void PressureIndependMultiYield::updateActiveSurface(void)
01215 {
01216 int numOfSurfaces = numOfSurfacesx[matN];
01217
01218 if (activeSurfaceNum == numOfSurfaces) return;
01219
01220 double A, B, C, X;
01221 static T2Vector direction;
01222 static Vector t1(6);
01223 static Vector t2(6);
01224 static Vector temp(6);
01225 static Vector center(6);
01226 center = theSurfaces[activeSurfaceNum].center();
01227 double size = theSurfaces[activeSurfaceNum].size();
01228 static Vector outcenter(6);
01229 outcenter= theSurfaces[activeSurfaceNum+1].center();
01230 double outsize = theSurfaces[activeSurfaceNum+1].size();
01231
01232
01233
01234
01235 t1 = trialStress.deviator();
01236 t1 -= center;
01237 t2 = center;
01238 t2 -= outcenter;
01239
01240 A = t1 && t1;
01241 B = 2. * (t1 && t2);
01242 C = (t2 && t2) - 2./3.* outsize * outsize;
01243 X = secondOrderEqn(A,B,C,0);
01244 if ( fabs(X-1.) < LOW_LIMIT ) X = 1.;
01245 if (X < 1.){
01246 opserr << "FATAL:PressureIndependMultiYield::updateActiveSurface(): error in Direction of surface motion."
01247 << endln;
01248 exit(-1);
01249 }
01250
01251
01252 temp = center;
01253 temp.addVector(1.0, t1, X);
01254 temp *= (1.0 - size/outsize);
01255 t2 = center;
01256 t2.addVector(1.0, outcenter, -size/outsize);
01257 temp -= t2;
01258
01259 direction.setData(temp);
01260
01261 if (direction.deviatorLength() < LOW_LIMIT) return;
01262
01263 temp = direction.deviator();
01264 A = temp && temp;
01265 B = - 2 * (t1 && temp);
01266 if (fabs(B) < LOW_LIMIT) B = 0.;
01267 C = (t1 && t1) - 2./3.* size * size;
01268 if ( fabs(C) < LOW_LIMIT || fabs(C)/(t1 && t1) < LOW_LIMIT ) return;
01269
01270 if (B > 0. || C < 0.) {
01271 opserr << "FATAL:PressureIndependMultiYield::updateActiveSurface(): error in surface motion.\n"
01272 << "A= " <<A <<" B= " <<B <<" C= "<<C <<" (t1&&t1)= "<<(t1&&t1) <<endln;
01273 exit(-1);
01274 }
01275 X = secondOrderEqn(A,B,C,1);
01276
01277
01278 center.addVector(1.0, temp, X);
01279 theSurfaces[activeSurfaceNum].setCenter(center);
01280 }
01281
01282
01283 void PressureIndependMultiYield::updateInnerSurface(void)
01284 {
01285 if (activeSurfaceNum <= 1) return;
01286
01287 static Vector devia(6);
01288 devia = currentStress.deviator();
01289 static Vector center(6);
01290 center = theSurfaces[activeSurfaceNum].center();
01291 double size = theSurfaces[activeSurfaceNum].size();
01292 static Vector newcenter(6);
01293
01294 for (int i=1; i<activeSurfaceNum; i++) {
01295
01296 newcenter = center;
01297 newcenter -= devia;
01298 newcenter *= theSurfaces[i].size()/size;
01299 newcenter += devia;
01300
01301 theSurfaces[i].setCenter(newcenter);
01302 }
01303 }
01304
01305
01306 int PressureIndependMultiYield:: isCrossingNextSurface(void)
01307 {
01308 int numOfSurfaces = numOfSurfacesx[matN];
01309 if (activeSurfaceNum == numOfSurfaces) return 0;
01310
01311 if(yieldFunc(trialStress, theSurfaces, activeSurfaceNum+1) > 0) return 1;
01312
01313 return 0;
01314 }
01315