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
00032
00033
00034 #ifndef NewTemplate3Dep_CPP
00035 #define NewTemplate3Dep_CPP
00036
00037 #include "NewTemplate3Dep.h"
00038
00039 const straintensor NewTemplate3Dep::ZeroStrain;
00040 const stresstensor NewTemplate3Dep::ZeroStress;
00041 const BJtensor NewTemplate3Dep::ZeroI4(4, def_dim_4, 0.0);
00042 const int NewTemplate3Dep::ISMAX = 30;
00043 const int NewTemplate3Dep::ITMAX = 30;
00044 const double NewTemplate3Dep::TOL = 1.0e-7;
00045 const double NewTemplate3Dep::FTOL = 1.0e-8;
00046
00047
00048 Matrix NewTemplate3Dep::D(6,6);
00049 Vector NewTemplate3Dep::sigma(6);
00050 Vector NewTemplate3Dep::epsilon(6);
00051
00052 #include "NewTemplate3Dep.h"
00053
00054
00055
00056 NewTemplate3Dep::NewTemplate3Dep( int tag,
00057 MaterialParameter *pointer_material_parameter_in,
00058 ElasticState *pointer_elastic_state_in,
00059 YieldFunction *pointer_yield_function_in ,
00060 PlasticFlow *pointer_plastic_flow_in,
00061 ScalarEvolution **pointer_scalar_evolution_in,
00062 TensorEvolution **pointer_tensor_evolution_in,
00063 int caseIndex_in)
00064 :NDMaterial(tag, ND_TAG_NewTemplate3Dep), caseIndex(caseIndex_in)
00065 {
00066 if ( pointer_material_parameter_in )
00067 pointer_material_parameter = pointer_material_parameter_in->newObj();
00068 else {
00069 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to construct the input parameters. " << endln;
00070 exit(1);
00071 }
00072
00073 if ( pointer_elastic_state_in )
00074 pointer_elastic_state = pointer_elastic_state_in->newObj();
00075 else{
00076 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to get copy of elastic material. " << endln;
00077 exit(1);
00078 }
00079
00080 if ( pointer_yield_function_in )
00081 pointer_yield_function = pointer_yield_function_in->newObj();
00082 else {
00083 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to construct the yield function. " << endln;
00084 exit(1);
00085 }
00086
00087 if ( pointer_plastic_flow_in )
00088 pointer_plastic_flow = pointer_plastic_flow_in->newObj();
00089 else {
00090 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to construct the plastic flow. " << endln;
00091 exit(1);
00092 }
00093
00094
00095 if ( pointer_material_parameter_in->getNum_Internal_Scalar() > 0 ) {
00096 pointer_scalar_evolution = new ScalarEvolution* [pointer_material_parameter_in->getNum_Internal_Scalar()];
00097 for (int i = 0; i < pointer_material_parameter_in->getNum_Internal_Scalar(); i++)
00098 pointer_scalar_evolution[i] = (pointer_scalar_evolution_in[i])->newObj();
00099 }
00100 else
00101 pointer_scalar_evolution = NULL;
00102
00103
00104 if ( pointer_material_parameter_in->getNum_Internal_Tensor() > 0 ) {
00105 pointer_tensor_evolution = new TensorEvolution* [pointer_material_parameter_in->getNum_Internal_Tensor()];
00106 for (int i = 0; i < pointer_material_parameter_in->getNum_Internal_Tensor(); i++)
00107 pointer_tensor_evolution[i] = (pointer_tensor_evolution_in[i])->newObj();
00108 }
00109 else
00110 pointer_tensor_evolution = NULL;
00111
00112 int err;
00113 err = this->revertToStart();
00114 }
00115
00116
00117
00118 NewTemplate3Dep::NewTemplate3Dep( int tag,
00119 MaterialParameter *pointer_material_parameter_in,
00120 ElasticState *pointer_elastic_state_in,
00121 YieldFunction *pointer_yield_function_in ,
00122 PlasticFlow *pointer_plastic_flow_in,
00123 TensorEvolution **pointer_tensor_evolution_in,
00124 int caseIndex_in)
00125 :NDMaterial(tag, ND_TAG_NewTemplate3Dep), caseIndex(caseIndex_in)
00126 {
00127 if ( pointer_material_parameter_in )
00128 pointer_material_parameter = pointer_material_parameter_in->newObj();
00129 else {
00130 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to construct the input parameters. " << endln;
00131 exit(1);
00132 }
00133
00134 if ( pointer_elastic_state_in )
00135 pointer_elastic_state = pointer_elastic_state_in->newObj();
00136 else{
00137 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to get copy of elastic material. " << endln;
00138 exit(1);
00139 }
00140
00141 if ( pointer_yield_function_in )
00142 pointer_yield_function = pointer_yield_function_in->newObj();
00143 else {
00144 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to construct the yield function. " << endln;
00145 exit(1);
00146 }
00147
00148 if ( pointer_plastic_flow_in )
00149 pointer_plastic_flow = pointer_plastic_flow_in->newObj();
00150 else {
00151 opserr << "NewTemplate3Dep:: NewTemplate3Dep failed to construct the plastic flow. " << endln;
00152 exit(1);
00153 }
00154
00155
00156 pointer_scalar_evolution = NULL;
00157
00158
00159 if ( pointer_material_parameter_in->getNum_Internal_Tensor() > 0 ) {
00160 pointer_tensor_evolution = new TensorEvolution* [pointer_material_parameter_in->getNum_Internal_Tensor()];
00161 for (int i = 0; i < pointer_material_parameter_in->getNum_Internal_Tensor(); i++)
00162 pointer_tensor_evolution[i] = pointer_tensor_evolution_in[i]->newObj();
00163 }
00164 else
00165 pointer_tensor_evolution = NULL;
00166
00167 int err;
00168 err = this->revertToStart();
00169 }
00170
00171
00172
00173 NewTemplate3Dep::NewTemplate3Dep()
00174 : NDMaterial(0, ND_TAG_NewTemplate3Dep),
00175 pointer_material_parameter(NULL),
00176 pointer_elastic_state(NULL),
00177 pointer_yield_function(NULL),
00178 pointer_plastic_flow(NULL),
00179 pointer_scalar_evolution(NULL),
00180 pointer_tensor_evolution(NULL),
00181 caseIndex(0)
00182 {
00183 int err;
00184 err = this->revertToStart();
00185 }
00186
00187
00188
00189 NewTemplate3Dep::~NewTemplate3Dep()
00190 {
00191 if (pointer_elastic_state)
00192 delete pointer_elastic_state;
00193
00194 for (int i = 0; i < pointer_material_parameter->getNum_Internal_Scalar(); i++) {
00195 if (pointer_scalar_evolution[i])
00196 delete pointer_scalar_evolution[i];
00197 }
00198 if (pointer_scalar_evolution)
00199 delete [] pointer_scalar_evolution;
00200
00201 for (int j = 0; j < pointer_material_parameter->getNum_Internal_Tensor(); j++) {
00202 if (pointer_tensor_evolution[j])
00203 delete pointer_tensor_evolution[j];
00204 }
00205 if (pointer_tensor_evolution)
00206 delete [] pointer_tensor_evolution;
00207
00208 if (pointer_yield_function)
00209 delete pointer_yield_function;
00210
00211 if (pointer_plastic_flow)
00212 delete pointer_plastic_flow;
00213
00214 if (pointer_material_parameter)
00215 delete pointer_material_parameter;
00216 }
00217
00218
00219 int NewTemplate3Dep::setTrialStrain (const Vector &v)
00220 {
00221 straintensor temp;
00222
00223 temp.val(1,1) = v(0);
00224 temp.val(2,2) = v(1);
00225 temp.val(3,3) = v(2);
00226 temp.val(1,2) = 0.5 * v(3);
00227 temp.val(2,1) = 0.5 * v(3);
00228 temp.val(3,1) = 0.5 * v(4);
00229 temp.val(1,3) = 0.5 * v(4);
00230 temp.val(2,3) = 0.5 * v(5);
00231 temp.val(3,2) = 0.5 * v(5);
00232
00233 return this->setTrialStrainIncr(temp - getStrainTensor());
00234 }
00235
00236
00237 int NewTemplate3Dep::setTrialStrain (const Vector &v, const Vector &r)
00238 {
00239 return this->setTrialStrainIncr(v);;
00240 }
00241
00242
00243 int NewTemplate3Dep::setTrialStrainIncr (const Vector &v)
00244 {
00245 straintensor temp;
00246
00247 temp.val(1,1) = v(0);
00248 temp.val(2,2) = v(1);
00249 temp.val(3,3) = v(2);
00250 temp.val(1,2) = 0.5 * v(3);
00251 temp.val(2,1) = 0.5 * v(3);
00252 temp.val(3,1) = 0.5 * v(4);
00253 temp.val(1,3) = 0.5 * v(4);
00254 temp.val(2,3) = 0.5 * v(5);
00255 temp.val(3,2) = 0.5 * v(5);
00256
00257 return this->setTrialStrainIncr(temp);
00258 }
00259
00260
00261 int NewTemplate3Dep::setTrialStrainIncr (const Vector &v, const Vector &r)
00262 {
00263 return this->setTrialStrainIncr(v);
00264 }
00265
00266
00267 const Matrix& NewTemplate3Dep::getTangent (void)
00268 {
00269 D(0,0) = Stiffness.cval(1,1,1,1);
00270 D(0,1) = Stiffness.cval(1,1,2,2);
00271 D(0,2) = Stiffness.cval(1,1,3,3);
00272 D(0,3) = Stiffness.cval(1,1,1,2);
00273 D(0,4) = Stiffness.cval(1,1,1,3);
00274 D(0,5) = Stiffness.cval(1,1,2,3);
00275
00276 D(1,0) = Stiffness.cval(2,2,1,1);
00277 D(1,1) = Stiffness.cval(2,2,2,2);
00278 D(1,2) = Stiffness.cval(2,2,3,3);
00279 D(1,3) = Stiffness.cval(2,2,1,2);
00280 D(1,4) = Stiffness.cval(2,2,1,3);
00281 D(1,5) = Stiffness.cval(2,2,2,3);
00282
00283 D(2,0) = Stiffness.cval(3,3,1,1);
00284 D(2,1) = Stiffness.cval(3,3,2,2);
00285 D(2,2) = Stiffness.cval(3,3,3,3);
00286 D(2,3) = Stiffness.cval(3,3,1,2);
00287 D(2,4) = Stiffness.cval(3,3,1,3);
00288 D(2,5) = Stiffness.cval(3,3,2,3);
00289
00290 D(3,0) = Stiffness.cval(1,2,1,1);
00291 D(3,1) = Stiffness.cval(1,2,2,2);
00292 D(3,2) = Stiffness.cval(1,2,3,3);
00293 D(3,3) = Stiffness.cval(1,2,1,2);
00294 D(3,4) = Stiffness.cval(1,2,1,3);
00295 D(3,5) = Stiffness.cval(1,2,2,3);
00296
00297 D(4,0) = Stiffness.cval(1,3,1,1);
00298 D(4,1) = Stiffness.cval(1,3,2,2);
00299 D(4,2) = Stiffness.cval(1,3,3,3);
00300 D(4,3) = Stiffness.cval(1,3,1,2);
00301 D(4,4) = Stiffness.cval(1,3,1,3);
00302 D(4,5) = Stiffness.cval(1,3,2,3);
00303
00304 D(5,0) = Stiffness.cval(2,3,1,1);
00305 D(5,1) = Stiffness.cval(2,3,2,2);
00306 D(5,2) = Stiffness.cval(2,3,3,3);
00307 D(5,3) = Stiffness.cval(2,3,1,2);
00308 D(5,4) = Stiffness.cval(2,3,1,3);
00309 D(5,5) = Stiffness.cval(2,3,2,3);
00310
00311 return D;
00312 }
00313
00314
00315 const Vector& NewTemplate3Dep::getStress (void)
00316 {
00317 sigma(0) = TrialStress.cval(1,1);
00318 sigma(1) = TrialStress.cval(2,2);
00319 sigma(2) = TrialStress.cval(3,3);
00320 sigma(3) = TrialStress.cval(1,2);
00321 sigma(4) = TrialStress.cval(1,3);
00322 sigma(5) = TrialStress.cval(2,3);
00323
00324 return sigma;
00325 }
00326
00327
00328 const Vector& NewTemplate3Dep::getStrain (void)
00329 {
00330 epsilon(0) = TrialStrain.cval(1,1);
00331 epsilon(1) = TrialStrain.cval(2,2);
00332 epsilon(2) = TrialStrain.cval(3,3);
00333 epsilon(3) = TrialStrain.cval(1,2) + TrialStrain.cval(2,1);
00334 epsilon(4) = TrialStrain.cval(1,3) + TrialStrain.cval(3,1);
00335 epsilon(5) = TrialStrain.cval(2,3) + TrialStrain.cval(3,2);
00336
00337 return epsilon;
00338 }
00339
00340
00341 int NewTemplate3Dep::setTrialStrain(const Tensor& v)
00342 {
00343 return setTrialStrainIncr( v - getStrainTensor() );
00344 }
00345
00346
00347
00348 int NewTemplate3Dep::setTrialStrain(const Tensor& v, const Tensor& r)
00349 {
00350 return setTrialStrainIncr( v - getStrainTensor() );
00351 }
00352
00353
00354 int NewTemplate3Dep::setTrialStrainIncr(const Tensor& v)
00355 {
00356 TrialStrain = v + getStrainTensor();
00357
00358 switch(caseIndex) {
00359
00360 case (0):
00361 return ForwardEuler(v);
00362
00363 case (1):
00364 return SemiImplicit(v);
00365
00366 case (2):
00367 return BackwardEuler(v);
00368
00369 default:
00370 return 1;
00371 }
00372 }
00373
00374
00375 int NewTemplate3Dep::setTrialStrainIncr(const Tensor& v, const Tensor& r)
00376 {
00377 return setTrialStrainIncr(v);
00378 }
00379
00380
00381 double NewTemplate3Dep::getRho(void)
00382 {
00383 double rho = 0.0;
00384 if (pointer_material_parameter->getNum_Material_Parameter() > 0)
00385 rho = pointer_material_parameter->getMaterial_Parameter(0);
00386 else {
00387 opserr << "Error!! NewTemplate3Dep:: number of input parameter for material constants less than 1. " << endln;
00388 opserr << "Remind: NewTemplate3Dep:: the 1st material constant is the density. " << endln;
00389 exit(1);
00390 }
00391
00392 return rho;
00393 }
00394
00395
00396 const BJtensor& NewTemplate3Dep::getTangentTensor(void)
00397 {
00398 return Stiffness;
00399 }
00400
00401
00402 const stresstensor& NewTemplate3Dep::getStressTensor(void)
00403 {
00404 return TrialStress;
00405 }
00406
00407
00408
00409 const straintensor& NewTemplate3Dep::getStrainTensor(void)
00410 {
00411 return TrialStrain;
00412 }
00413
00414
00415 const straintensor& NewTemplate3Dep::getPlasticStrainTensor(void)
00416 {
00417 return TrialPlastic_Strain;
00418 }
00419
00420
00421
00422 int NewTemplate3Dep::commitState(void)
00423 {
00424 int err = 0;
00425
00426
00427
00428 CommitStress.Initialize(TrialStress);
00429 CommitStrain.Initialize(TrialStrain);
00430
00431 CommitPlastic_Strain.Initialize(TrialPlastic_Strain);
00432
00433 return err;
00434 }
00435
00436
00437 int NewTemplate3Dep::revertToLastCommit(void)
00438 {
00439 int err = 0;
00440
00441 TrialStress.Initialize(CommitStress);
00442 TrialStrain.Initialize(CommitStrain);
00443
00444 TrialPlastic_Strain.Initialize(CommitPlastic_Strain);
00445
00446 return err;
00447 }
00448
00449
00450 int NewTemplate3Dep::revertToStart(void)
00451 {
00452 int err = 0;
00453
00454 CommitStress = pointer_elastic_state->getStress();
00455 CommitStrain = pointer_elastic_state->getStrain();
00456
00457 CommitPlastic_Strain.Initialize(ZeroStrain);
00458
00459 TrialStress.Initialize(CommitStress);
00460 TrialStrain.Initialize(CommitStrain);
00461
00462 TrialPlastic_Strain.Initialize(ZeroStrain);
00463
00464 Stiffness = pointer_elastic_state->getElasticStiffness(*pointer_material_parameter);
00465
00466 return err;
00467 }
00468
00469
00470 NDMaterial * NewTemplate3Dep::getCopy(void)
00471 {
00472 NDMaterial* tmp = new NewTemplate3Dep(this->getTag(),
00473 this->pointer_material_parameter,
00474 this->pointer_elastic_state,
00475 this->pointer_yield_function,
00476 this->pointer_plastic_flow,
00477 this->pointer_scalar_evolution,
00478 this->pointer_tensor_evolution,
00479 this->caseIndex );
00480 return tmp;
00481 }
00482
00483
00484
00485 NDMaterial * NewTemplate3Dep::getCopy(const char *code)
00486 {
00487 if (strcmp(code,"ThreeDimensional") == 0) {
00488 NewTemplate3Dep* tmp = new NewTemplate3Dep( this->getTag(),
00489 this->pointer_material_parameter,
00490 this->pointer_elastic_state,
00491 this->pointer_yield_function,
00492 this->pointer_plastic_flow,
00493 this->pointer_scalar_evolution,
00494 this->pointer_tensor_evolution,
00495 this->caseIndex );
00496 return tmp;
00497 }
00498 else {
00499 opserr << "NewTemplate3Dep::getCopy failed to get model: " << code << endln;
00500 exit(1);
00501 }
00502 return 0;
00503 }
00504
00505
00506 const char *NewTemplate3Dep::getType(void) const
00507 {
00508 return "ThreeDimensional";
00509 }
00510
00511
00512 int NewTemplate3Dep::sendSelf(int commitTag, Channel &theChannel)
00513 {
00514
00515 return 0;
00516 }
00517
00518
00519 int NewTemplate3Dep::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00520 {
00521
00522 return 0;
00523 }
00524
00525
00526 void NewTemplate3Dep::Print(OPS_Stream& s, int flag)
00527 {
00528 s << (*this);
00529 }
00530
00531
00532 int NewTemplate3Dep::ForwardEuler(const straintensor& strain_incr)
00533 {
00534 straintensor start_strain;
00535 stresstensor start_stress;
00536 stresstensor stress_incr;
00537 stresstensor Intersection_strain;
00538 stresstensor Intersection_stress;
00539 stresstensor elastic_predictor_stress;
00540 BJtensor Ee;
00541 straintensor incr_strain;
00542 int err = 0;
00543
00544 double f_start = 0.0;
00545 double f_pred = 0.0;
00546
00547 double intersection_factor = 0.0;
00548
00549 Ee = pointer_elastic_state->getElasticStiffness(*pointer_material_parameter);
00550
00551 start_stress = getStressTensor();
00552 start_strain = getStrainTensor();
00553
00554 Intersection_stress.Initialize(start_stress);
00555
00556
00557 incr_strain.Initialize(strain_incr);
00558 stress_incr = Ee("ijpq") * incr_strain("pq");
00559 stress_incr.null_indices();
00560
00561 elastic_predictor_stress = start_stress + stress_incr;
00562
00563 f_start = pointer_yield_function->YieldFunctionValue( start_stress, *pointer_material_parameter );
00564 f_pred = pointer_yield_function->YieldFunctionValue( elastic_predictor_stress, *pointer_material_parameter );
00565
00566
00567 if ( (f_start <= 0.0 && f_pred <= FTOL) || f_start > f_pred ) {
00568
00569 TrialStress.Initialize(elastic_predictor_stress);
00570
00571 Stiffness = Ee;
00572
00573
00574 err += pointer_elastic_state->setStress(TrialStress);
00575 err += pointer_elastic_state->setStrain(TrialStrain);
00576
00577 return err;
00578 }
00579
00580
00581 if ( f_start < 0.0 ) {
00582
00583 intersection_factor = zbrentstress( start_stress, elastic_predictor_stress, 0.0, 1.0, TOL );
00584
00585 Intersection_stress = yield_surface_cross( start_stress, elastic_predictor_stress, intersection_factor );
00586 Intersection_strain = start_strain + (incr_strain * intersection_factor);
00587
00588 stress_incr = elastic_predictor_stress - Intersection_stress;
00589
00590
00591 err += pointer_elastic_state->setStress(Intersection_stress);
00592 err += pointer_elastic_state->setStrain(Intersection_strain);
00593
00594 Ee = pointer_elastic_state->getElasticStiffness(*pointer_material_parameter);
00595 }
00596
00597
00598 {
00599 double lower = 0.0;
00600 double Delta_lambda = 0.0;
00601 double hardMod = 0.0;
00602 double h_s = 0.0;
00603 double xi_s = 0.0;
00604 stresstensor dFods;
00605 straintensor dQods;
00606 BJtensor Hq;
00607 BJtensor Hf;
00608 BJtensor Ep;
00609
00610 stresstensor h_t;
00611 stresstensor xi_t;
00612
00613 straintensor plastic_strain_incr;
00614 stresstensor ep_stress;
00615
00616
00617
00618
00619 dFods = pointer_yield_function->StressDerivative( Intersection_stress, *pointer_material_parameter );
00620 dQods = pointer_plastic_flow->PlasticFlowTensor( Intersection_stress, Intersection_strain, *pointer_material_parameter );
00621
00622
00623 Hq = Ee("ijkl") * dQods("kl");
00624 Hq.null_indices();
00625
00626
00627 Hf = dFods("ij") * Ee("ijkl");
00628 Hf.null_indices();
00629
00630
00631 lower = ( Hf("ij") * dQods("ij") ).trace();
00632 int i;
00633
00634 double Num_internal_scalar_in_yield_function = pointer_yield_function->getNumInternalScalar();
00635 for (i = 0; i < Num_internal_scalar_in_yield_function; i++) {
00636 h_s = pointer_scalar_evolution[i]->H( dQods, Intersection_stress, Intersection_strain, *pointer_material_parameter);
00637 xi_s = pointer_yield_function->InScalarDerivative( Intersection_stress, *pointer_material_parameter, i+1);
00638 hardMod += h_s * xi_s;
00639 }
00640
00641
00642 double Num_internal_tensor_in_yield_function = pointer_yield_function->getNumInternalTensor();
00643 for (i = 0; i < Num_internal_tensor_in_yield_function; i++) {
00644 h_t = pointer_tensor_evolution[i]->Hij( dQods, Intersection_stress, Intersection_strain, *pointer_material_parameter);
00645 xi_t = pointer_yield_function->InTensorDerivative( Intersection_stress, *pointer_material_parameter, i+1);
00646 hardMod += ( h_t("mn") * xi_t("mn") ).trace();
00647 }
00648
00649 lower -= hardMod;
00650
00651
00652 Delta_lambda = ( dFods("ij") * stress_incr("ij") ).trace();
00653
00654 if (lower != 0.0)
00655 Delta_lambda /= lower;
00656
00657 if (Delta_lambda < 0.0)
00658 Delta_lambda = 0.0;
00659
00660
00661 plastic_strain_incr = dQods * Delta_lambda;
00662 ep_stress = elastic_predictor_stress - (Hq * Delta_lambda);
00663
00664 TrialPlastic_Strain = this->getPlasticStrainTensor() + plastic_strain_incr;
00665 TrialStress = ep_stress;
00666
00667
00668 Ep = Hq("pq") * Hf("mn");
00669 Ep.null_indices();
00670
00671 Ep = Ep * (1.0/lower);
00672 if ( Delta_lambda > 0.0 )
00673 Stiffness = Ee - Ep;
00674 else
00675 Stiffness = Ee;
00676
00677
00678 double dS= 0.0;
00679 double S = 0.0;
00680 int Num_internal_scalar = pointer_material_parameter->getNum_Internal_Scalar();
00681 for (i = 0; i < Num_internal_scalar; i++) {
00682 dS = ( pointer_scalar_evolution[i]->H(dQods, Intersection_stress, Intersection_strain, *pointer_material_parameter) ) *Delta_lambda;
00683 S = pointer_material_parameter->getInternal_Scalar(i);
00684 err += pointer_material_parameter->setInternal_Scalar(i, S + dS );
00685 }
00686
00687
00688 stresstensor dT;
00689 stresstensor T;
00690 int Num_internal_tensor = pointer_material_parameter->getNum_Internal_Tensor();
00691 for (i = 0; i < Num_internal_tensor; i++) {
00692 dT = pointer_tensor_evolution[i]->Hij(dQods, Intersection_stress, Intersection_strain, *pointer_material_parameter) *Delta_lambda;
00693 T = pointer_material_parameter->getInternal_Tensor(i);
00694 err += pointer_material_parameter->setInternal_Tensor(i, T + dT );
00695 }
00696
00697
00698 err += pointer_elastic_state->setStrain(TrialStrain);
00699 err += pointer_elastic_state->setStress(TrialStress);
00700 }
00701
00702 return err;
00703 }
00704
00705
00706 int NewTemplate3Dep::SemiImplicit(const straintensor& strain_incr)
00707 {
00708 double YieldFun = 0.0;
00709
00710 straintensor start_strain;
00711 stresstensor start_stress;
00712 stresstensor stress_incr;
00713 BJtensor Ee;
00714
00715 int err = 0;
00716
00717 Ee = pointer_elastic_state->getElasticStiffness(*pointer_material_parameter);
00718
00719 start_stress = getStressTensor();
00720 start_strain = getStrainTensor();
00721
00722
00723 straintensor incr_strain = strain_incr;
00724 stress_incr = Ee("ijpq") * incr_strain("pq");
00725 stress_incr.null_indices();
00726
00727 TrialPlastic_Strain = this->getPlasticStrainTensor();
00728 TrialStress = start_stress + stress_incr;
00729
00730 YieldFun = pointer_yield_function->YieldFunctionValue(TrialStress, *pointer_material_parameter);
00731
00732
00733
00734 if ( YieldFun <= FTOL ) {
00735 err += pointer_elastic_state->setStress(TrialStress);
00736 err += pointer_elastic_state->setStrain(TrialStrain);
00737 Stiffness = Ee;
00738 }
00739 else {
00740 double Delta_lambda = 0.0;
00741 double d2_lambda = 0.0;
00742 int iter_counter = 0;
00743 double lower = 0.0;
00744 double hardMod = 0.0;
00745 double h_s = 0.0;
00746 double xi_s = 0.0;
00747 stresstensor dFods;
00748 straintensor dQods;
00749 BJtensor Hf;
00750 BJtensor Hq;
00751 BJtensor Ep;
00752
00753 stresstensor h_t;
00754 stresstensor xi_t;
00755
00756 dQods = pointer_plastic_flow->PlasticFlowTensor( start_stress, start_strain, *pointer_material_parameter );
00757
00758 Hq = Ee("ijkl") * dQods("kl");
00759 Hq.null_indices();
00760 int i;
00761
00762 double Num_internal_scalar_in_yield_function = pointer_yield_function->getNumInternalScalar();
00763 for (i = 0; i < Num_internal_scalar_in_yield_function; i++) {
00764 h_s = pointer_scalar_evolution[i]->H( dQods, start_stress, start_strain, *pointer_material_parameter);
00765 xi_s = pointer_yield_function->InScalarDerivative( TrialStress, *pointer_material_parameter, i+1);
00766 hardMod += h_s * xi_s;
00767 }
00768
00769 double Num_internal_tensor_in_yield_function = pointer_yield_function->getNumInternalTensor();
00770 for (i = 0; i < Num_internal_tensor_in_yield_function; i++) {
00771 h_t = pointer_tensor_evolution[i]->Hij( dQods, start_stress, start_strain, *pointer_material_parameter);
00772 xi_t = pointer_yield_function->InTensorDerivative( TrialStress, *pointer_material_parameter, i+1);
00773 hardMod += ( h_t("mn") * xi_t("mn") ).trace();
00774 }
00775
00776
00777 do {
00778 dFods = pointer_yield_function->StressDerivative( TrialStress, *pointer_material_parameter );
00779
00780 Hf = dFods("ij") * Ee("ijkl");
00781 Hf.null_indices();
00782
00783 lower = ( Hf("ij") * dQods("ij") ).trace();
00784 lower = lower - hardMod;
00785
00786 d2_lambda = YieldFun / lower;
00787
00788
00789 TrialStress -= (Hq *d2_lambda);
00790
00791
00792 double dS= 0.0;
00793 double S = 0.0;
00794 int i;
00795 int Num_internal_scalar = pointer_material_parameter->getNum_Internal_Scalar();
00796 for (i = 0; i < Num_internal_scalar; i++) {
00797 dS = ( pointer_scalar_evolution[i]->H(dQods, start_stress, start_strain, *pointer_material_parameter) ) *d2_lambda;
00798 S = pointer_material_parameter->getInternal_Scalar(i);
00799 err += pointer_material_parameter->setInternal_Scalar(i, S + dS );
00800 }
00801
00802 stresstensor dT;
00803 stresstensor T;
00804 int Num_internal_tensor = pointer_material_parameter->getNum_Internal_Tensor();
00805 for (i = 0; i < Num_internal_tensor; i++) {
00806 dT = pointer_tensor_evolution[i]->Hij(dQods, start_stress, start_strain, *pointer_material_parameter) *d2_lambda;
00807 T = pointer_material_parameter->getInternal_Tensor(i);
00808 err += pointer_material_parameter->setInternal_Tensor(i, T + dT );
00809 }
00810
00811
00812 err += pointer_elastic_state->setStress(TrialStress);
00813
00814
00815 Delta_lambda += d2_lambda;
00816
00817
00818 iter_counter++;
00819
00820
00821 YieldFun = pointer_yield_function->YieldFunctionValue(TrialStress, *pointer_material_parameter);
00822
00823
00824
00825
00826
00827 } while (YieldFun > FTOL && iter_counter < ITMAX);
00828
00829
00830 if (Delta_lambda < 0.0)
00831 Delta_lambda = 0.0;
00832
00833
00834 Ep = Hq("pq") * Hf("mn");
00835 Ep.null_indices();
00836 Ep = Ep * (1.0/lower);
00837 if ( Delta_lambda > 0.0 )
00838 Stiffness = Ee - Ep;
00839 else
00840 Stiffness = Ee;
00841
00842 TrialPlastic_Strain += (dQods *Delta_lambda);
00843
00844 err += pointer_elastic_state->setStrain(TrialStrain);
00845 }
00846
00847 return err;
00848 }
00849
00850
00851 int NewTemplate3Dep::BackwardEuler(const straintensor& strain_incr)
00852 {
00853
00854 opserr << "BackwardEuler is not yet implemented!" << endln;
00855 return 0;
00856 }
00857
00858
00859
00860
00861
00862 stresstensor NewTemplate3Dep::yield_surface_cross(const stresstensor & start_stress,
00863 const stresstensor & end_stress, double a)
00864 {
00865
00866
00867 stresstensor delta_stress = end_stress - start_stress;
00868 stresstensor intersection_stress = start_stress + delta_stress * a;
00869
00870 return intersection_stress;
00871 }
00872
00873
00874
00875 double NewTemplate3Dep::zbrentstress(const stresstensor& start_stress,
00876 const stresstensor& end_stress,
00877 double x1, double x2, double tol) const
00878 {
00879 double EPS = d_macheps();
00880
00881 int iter;
00882 double a = x1;
00883 double b = x2;
00884 double c = 0.0;
00885 double d = 0.0;
00886 double e = 0.0;
00887 double min1 = 0.0;
00888 double min2 = 0.0;
00889 double fc = 0.0;
00890 double p = 0.0;
00891 double q = 0.0;
00892 double r = 0.0;
00893 double s = 0.0;
00894 double tol1 = 0.0;
00895 double xm = 0.0;
00896
00897 double fa = func(start_stress, end_stress, *pointer_material_parameter, a);
00898 double fb = func(start_stress, end_stress, *pointer_material_parameter, b);
00899
00900 if ( (fb * fa) > 0.0) {
00901 opserr << "\a\n Root must be bracketed in ZBRENTstress " << endln;
00902 exit(1);
00903 }
00904
00905 fc = fb;
00906 for ( iter = 1; iter <= ISMAX; iter++ ) {
00907 if ( (fb * fc) > 0.0) {
00908 c = a;
00909 fc = fa;
00910 e = d = b - a;
00911 }
00912 if ( fabs(fc) < fabs(fb) ) {
00913 a = b;
00914 b = c;
00915 c = a;
00916 fa = fb;
00917 fb = fc;
00918 fc = fa;
00919 }
00920 tol1 = 2.0 * EPS * fabs(b) + 0.5 * tol;
00921 xm = 0.5 * (c - b);
00922 if ( fabs(xm) <= tol1 || fb == 0.0 )
00923 return b;
00924
00925 if ( fabs(e) >= tol1 && fabs(fa) > fabs(fb) ) {
00926 s = fb / fa;
00927 if (a == c) {
00928 p = 2.0 * xm * s;
00929 q = 1.0 - s;
00930 }
00931 else {
00932 q = fa / fc;
00933 r = fb / fc;
00934 p = s * ( 2.0 * xm * q * (q - r) - (b - a) * (r - 1.0) );
00935 q = (q - 1.0) * (r - 1.0) * (s - 1.0);
00936 }
00937 if (p > 0.0)
00938 q = -q;
00939 p = fabs(p);
00940 min1 = 3.0 * xm * q - fabs(tol1*q);
00941 min2 = fabs(e*q);
00942 if (2.0*p < (min1 < min2 ? min1 : min2)) {
00943 e = d;
00944 d = p/q;
00945 }
00946 else {
00947 d = xm;
00948 e = d;
00949 }
00950 }
00951 else {
00952 d = xm;
00953 e = d;
00954 }
00955 a = b;
00956 fa = fb;
00957 if (fabs(d) > tol1)
00958 b += d;
00959 else
00960 b += (xm > 0.0 ? fabs(tol1) : -fabs(tol1));
00961 fb = func(start_stress, end_stress, *pointer_material_parameter, b);
00962 }
00963
00964 return 0.0;
00965 }
00966
00967
00968 double NewTemplate3Dep::func(const stresstensor& start_stress,
00969 const stresstensor& end_stress,
00970 const MaterialParameter& pointer_material_parameter,
00971 double alfa ) const
00972 {
00973 stresstensor alfa_stress = ( start_stress * (1.0 - alfa) ) + ( end_stress * alfa );
00974
00975 double f = pointer_yield_function->YieldFunctionValue( alfa_stress, pointer_material_parameter );
00976
00977 return f;
00978 }
00979
00980 #endif
00981