00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <OPS_Globals.h>
00040 #include <DrainMaterial.h>
00041 #include <Vector.h>
00042 #include <ID.h>
00043 #include <Channel.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 #include <float.h>
00047
00048 DrainMaterial::DrainMaterial(int tag, int classTag, int nhv, int ndata, double b)
00049 :UniaxialMaterial(tag,classTag), data(0), hstv(0),
00050 numData(ndata), numHstv(nhv), epsilonP(0.0), sigmaP(0.0), tangentP(0.0), beto(b),
00051 epsilon(0.0), epsilonDot(0.0), sigma(0.0), tangent(0.0)
00052 {
00053 if (numHstv < 0)
00054 numHstv = 0;
00055
00056 if (numHstv > 0) {
00057
00058 hstv = new double[2*numHstv];
00059 if (hstv == 0) {
00060 opserr << "DrainMaterial::DrainMaterial -- failed to allocate history array -- type : " <<
00061 this->getClassTag() << endln;
00062 exit(-1);
00063 }
00064
00065
00066
00067 for (int i = 0; i < 2*numHstv; i++)
00068 hstv[i] = 0.0;
00069 }
00070
00071 if (numData < 0)
00072 numData = 0;
00073
00074 if (numData > 0) {
00075
00076 data = new double[numData];
00077 if (data == 0) {
00078 opserr << "DrainMaterial::DrainMaterial -- failed to allocate data array -- type: " <<
00079 this->getClassTag() << endln;
00080 exit(-1);
00081 }
00082
00083
00084 for (int i = 0; i < numData; i++)
00085 data[i] = 0.0;
00086 }
00087
00088
00089 this->invokeSubroutine();
00090 initialTangent = tangent;
00091 }
00092
00093 DrainMaterial::~DrainMaterial()
00094 {
00095 if (hstv != 0)
00096 delete [] hstv;
00097
00098 if (data != 0)
00099 delete [] data;
00100 }
00101
00102 int
00103 DrainMaterial::setTrialStrain(double strain, double strainRate)
00104 {
00105
00106 epsilon = strain;
00107 epsilonDot = strainRate;
00108
00109
00110 return this->invokeSubroutine();
00111 }
00112
00113 int
00114 DrainMaterial::setTrial(double strain, double &stress, double &stiff, double strainRate)
00115 {
00116
00117 epsilon = strain;
00118 epsilonDot = strainRate;
00119
00120
00121 int res = this->invokeSubroutine();
00122
00123 stress = sigma;
00124 stiff = tangent;
00125
00126 return res;
00127 }
00128
00129 double
00130 DrainMaterial::getStrain(void)
00131 {
00132 return epsilon;
00133 }
00134
00135 double
00136 DrainMaterial::getStrainRate(void)
00137 {
00138 return epsilonDot;
00139 }
00140
00141 double
00142 DrainMaterial::getStress(void)
00143 {
00144 return sigma;
00145 }
00146
00147 double
00148 DrainMaterial::getTangent(void)
00149 {
00150 return tangent;
00151 }
00152
00153 double
00154 DrainMaterial::getInitialTangent(void)
00155 {
00156 return initialTangent;
00157 }
00158
00159 double
00160 DrainMaterial::getDampTangent(void)
00161 {
00162
00163
00164 return beto*tangentP;
00165 }
00166
00167 int
00168 DrainMaterial::commitState(void)
00169 {
00170
00171 for (int i = 0; i < numHstv; i++)
00172 hstv[i] = hstv[i+numHstv];
00173
00174 epsilonP = epsilon;
00175 sigmaP = sigma;
00176 tangentP = tangent;
00177
00178 return 0;
00179 }
00180
00181 int
00182 DrainMaterial::revertToLastCommit(void)
00183 {
00184
00185 for (int i = 0; i < numHstv; i++)
00186 hstv[i+numHstv] = hstv[i];
00187
00188 epsilon = epsilonP;
00189 sigma = sigmaP;
00190 tangent = tangentP;
00191
00192 return 0;
00193 }
00194
00195 int
00196 DrainMaterial::revertToStart(void)
00197 {
00198
00199 for (int i = 0; i < 2*numHstv; i++)
00200 hstv[i] = 0.0;
00201
00202 epsilonP = 0.0;
00203 sigmaP = 0.0;
00204 tangentP = 0.0;
00205
00206 return 0;
00207 }
00208
00209
00210
00211 UniaxialMaterial*
00212 DrainMaterial::getCopy(void)
00213 {
00214 DrainMaterial *theCopy =
00215 new DrainMaterial(this->getTag(), this->getClassTag(), numHstv, numData, beto);
00216
00217 int i;
00218 for (i = 0; i < 2*numHstv; i++)
00219 theCopy->hstv[i] = hstv[i];
00220
00221 for (i = 0; i < numData; i++)
00222 theCopy->data[i] = data[i];
00223
00224 theCopy->epsilonP = epsilonP;
00225 theCopy->sigmaP = sigmaP;
00226 theCopy->tangentP = tangentP;
00227
00228 return theCopy;
00229 }
00230
00231 int
00232 DrainMaterial::sendSelf(int commitTag, Channel &theChannel)
00233 {
00234 int res = 0;
00235
00236 Vector vecData(numHstv+numData+5);
00237
00238 int i, j;
00239
00240 for (i = 0; i < numHstv; i++)
00241 vecData(i) = hstv[i];
00242
00243
00244 for (i = 0, j = numHstv; i < numData; i++, j++)
00245 vecData(j) = data[i];
00246
00247 vecData(j++) = epsilonP;
00248 vecData(j++) = sigmaP;
00249 vecData(j++) = tangentP;
00250 vecData(j++) = beto;
00251 vecData(j++) = this->getTag();
00252
00253 res += theChannel.sendVector(this->getDbTag(), commitTag, vecData);
00254 if (res < 0)
00255 opserr << "DrainMaterial::sendSelf() - failed to send Vector data\n";
00256
00257 return res;
00258 }
00259
00260 int
00261 DrainMaterial::recvSelf(int commitTag, Channel &theChannel,
00262 FEM_ObjectBroker &theBroker)
00263 {
00264 int res = 0;
00265
00266 Vector vecData(numHstv+numData+5);
00267
00268 res += theChannel.recvVector(this->getDbTag(), commitTag, vecData);
00269 if (res < 0) {
00270 opserr << "DrainMaterial::recvSelf() - failed to receive Vector data\n";
00271 return res;
00272 }
00273
00274 int i, j;
00275
00276 for (i = 0; i < numHstv; i++) {
00277 hstv[i] = vecData(i);
00278 hstv[i+numHstv] = vecData(i);
00279 }
00280
00281
00282 for (i = 0, j = numHstv; i < numData; i++, j++)
00283 data[i] = vecData(j);
00284
00285 epsilonP = vecData(j++);
00286 sigmaP = vecData(j++);
00287 tangentP = vecData(j++);
00288 beto = vecData(j++);
00289
00290 this->setTag((int)vecData(j));
00291
00292 epsilon = epsilonP;
00293 sigma = sigmaP;
00294 tangent = tangentP;
00295
00296 return res;
00297 }
00298
00299 void
00300 DrainMaterial::Print(OPS_Stream &s, int flag)
00301 {
00302 s << "DrainMaterial, type: ";
00303
00304 switch (this->getClassTag()) {
00305 case MAT_TAG_DrainHardening:
00306 s << "Hardening" << endln;
00307 break;
00308 case MAT_TAG_DrainBilinear:
00309 s << "Bilinear" << endln;
00310 break;
00311 case MAT_TAG_DrainClough1:
00312 s << "Clough1" << endln;
00313 break;
00314 case MAT_TAG_DrainClough2:
00315 s << "Clough2" << endln;
00316 break;
00317 case MAT_TAG_DrainPinch1:
00318 s << "Pinch1" << endln;
00319 break;
00320
00321
00322 default:
00323 s << "Material identifier = " << this->getClassTag() << endln;
00324 break;
00325 }
00326 }
00327
00328 #ifdef _WIN32
00329
00330
00331 extern "C" int FILL00(double *data, double *hstv, double *stateP);
00332 extern "C" int RESP00(int *kresis, int *ksave, int *kgem, int *kstep,
00333 int *ndof, int *kst, int *kenr,
00334 double *ener, double *ened, double *enso, double *beto,
00335 double *relas, double *rdamp, double *rinit,
00336 double *ddise, double *dise, double *vele);
00337 extern "C" int STIF00(int *kstt, int *ktype, int *ndof, double *fk);
00338 extern "C" int GET00(double *hstv);
00339
00340 #define fill00_ FILL00
00341 #define resp00_ RESP00
00342 #define stif00_ STIF00
00343 #define get00_ GET00
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 #else
00417
00418
00419 extern "C" int fill00_(double *data, double *hstv, double *stateP);
00420 extern "C" int resp00_(int *kresis, int *ksave, int *kgem, int *kstep,
00421 int *ndof, int *kst, int *kenr,
00422 double *ener, double *ened, double *enso, double *beto,
00423 double *relas, double *rdamp, double *rinit,
00424 double *ddise, double *dise, double *vele);
00425 extern "C" int stif00_(int *kstt, int *ktype, int *ndof, double *fk);
00426 extern "C" int get00_(double *hstv);
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 #endif
00480
00481 int
00482 DrainMaterial::invokeSubroutine(void)
00483 {
00484
00485 static const int NDOF = 2;
00486
00487
00488 int kresis = 2;
00489 int ksave = 0;
00490 int kgem = 0;
00491 int kstep = 1;
00492 int ndof = NDOF;
00493 int kst = 1;
00494 int kenr = 2;
00495
00496
00497 double ener = 0.0;
00498 double ened = 0.0;
00499 double enso = 0.0;
00500
00501
00502 static double relas[NDOF];
00503 static double rdamp[NDOF];
00504 static double rinit[NDOF];
00505
00506
00507 static double dise[NDOF];
00508 dise[0] = 0.0;
00509 dise[1] = epsilon;
00510
00511
00512 static double ddise[NDOF];
00513 ddise[0] = 0.0;
00514 ddise[1] = epsilon-epsilonP;
00515
00516
00517 static double vele[NDOF];
00518 vele[0] = 0.0;
00519 vele[1] = epsilonDot;
00520
00521
00522 static double stateP[3];
00523 stateP[0] = epsilonP;
00524 stateP[1] = sigmaP;
00525 stateP[2] = tangentP;
00526
00527
00528 int kstt = 1;
00529 int ktype = 1;
00530
00531
00532 static double fk[NDOF*NDOF];
00533
00534 switch (this->getClassTag()) {
00535 case MAT_TAG_DrainHardening:
00536
00537 fill00_(data, hstv, stateP);
00538
00539
00540 resp00_(&kresis, &ksave, &kgem, &kstep, &ndof, &kst, &kenr,
00541 &ener, &ened, &enso, &beto, relas, rdamp, rinit, ddise, dise, vele);
00542
00543
00544 stif00_(&kstt, &ktype, &ndof, fk);
00545
00546
00547 get00_(&hstv[numHstv]);
00548 break;
00549
00550 case MAT_TAG_DrainBilinear:
00551
00552 opserr << "DrainMaterial::invokeSubroutine -- Bilinear subroutine not yet linked\n"; exit(-1);
00553
00554
00555
00556
00557
00558
00559
00560 break;
00561
00562 case MAT_TAG_DrainClough1:
00563
00564 opserr << "DrainMaterial::invokeSubroutine -- Clough1 subroutine not yet linked\n"; exit(-1);
00565
00566
00567
00568
00569
00570
00571 break;
00572
00573 case MAT_TAG_DrainClough2:
00574
00575 opserr << "DrainMaterial::invokeSubroutine -- Clough2 subroutine not yet linked\n"; exit(-1);
00576
00577
00578
00579
00580
00581
00582 break;
00583
00584 case MAT_TAG_DrainPinch1:
00585
00586 opserr << "DrainMaterial::invokeSubroutine -- Pinch1 subroutine not yet linked\n"; exit(-1);
00587
00588
00589
00590
00591
00592
00593 break;
00594
00595
00596
00597 default:
00598 opserr << "DrainMaterial::invokeSubroutine -- unknown material type\n"; exit(-1);
00599 return -1;
00600 }
00601
00602
00603 sigma = relas[1] + rdamp[1];
00604
00605
00606 tangent = fk[0];
00607
00608 return 0;
00609 }