NewTemplate3Dep.cpp

Go to the documentation of this file.
00001 
00002 //   COPYLEFT (C): Woody's viral GPL-like license (by BJ):
00003 //                 ``This    source  code is Copyrighted in
00004 //                 U.S.,  for  an  indefinite  period,  and anybody
00005 //                 caught  using it without our permission, will be
00006 //                 mighty good friends of ourn, cause we don't give
00007 //                 a  darn.  Hack it. Compile it. Debug it. Run it.
00008 //                 Yodel  it.  Enjoy it. We wrote it, that's all we
00009 //                 wanted to do.''
00010 //
00011 //
00012 // COPYRIGHT (C):     :-))
00013 // PROJECT:           Object Oriented Finite Element Program
00014 // FILE:              
00015 // CLASS:             
00016 // MEMBER FUNCTIONS:
00017 //
00018 // MEMBER VARIABLES
00019 //
00020 // PURPOSE:           
00021 //
00022 // RETURN:
00023 // VERSION:
00024 // LANGUAGE:          C++
00025 // TARGET OS:         
00026 // DESIGNER:          Zhao Cheng, Boris Jeremic
00027 // PROGRAMMER:        Zhao Cheng, 
00028 // DATE:              Fall 2005
00029 // UPDATE HISTORY:    06/2006, add functions for matrix based elements, CZ
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 // For Matrix based elements
00048 Matrix NewTemplate3Dep::D(6,6);
00049 Vector NewTemplate3Dep::sigma(6);
00050 Vector NewTemplate3Dep::epsilon(6);
00051 
00052 #include "NewTemplate3Dep.h"
00053 
00054 // Constructor
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     // Scalar (isotropic) Evolution
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     // Tensor (kinematic) Evolution
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 // Constructor
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     // Scalar (isotropic) Evolution
00156     pointer_scalar_evolution = NULL;
00157     
00158     // Tensor (kenimatic) Evolution
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 // Constructor
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 // Destructor
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 // For Matrix based elements
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 // For Matrix based elements
00237 int NewTemplate3Dep::setTrialStrain (const Vector &v, const Vector &r)
00238 {
00239         return this->setTrialStrainIncr(v);;
00240 }
00241 
00242 // For Matrix based elements
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 // For Matrix based elements
00261 int NewTemplate3Dep::setTrialStrainIncr (const Vector &v, const Vector &r)
00262 {
00263         return this->setTrialStrainIncr(v);
00264 }
00265 
00266 // For Matrix based elements
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 // For Matrix based elements
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 // For Matrix based elements
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     //err += pointer_elastic_state->commitState();
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     // Not yet implemented
00515     return 0;
00516 }
00517 
00518 //================================================================================
00519 int NewTemplate3Dep::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00520 {
00521     // Not yet implemented
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     // I had to use the one line incr_strain = strain_incr; Problem of BJTensor;
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     // If Elastic
00567     if ( (f_start <= 0.0 && f_pred <= FTOL) || f_start > f_pred ) {
00568         //TrialStrain = start_strain + strain_incr;
00569         TrialStress.Initialize(elastic_predictor_stress);
00570 
00571         Stiffness = Ee;
00572                
00573         // update elastic part
00574         err += pointer_elastic_state->setStress(TrialStress);
00575         err += pointer_elastic_state->setStrain(TrialStrain);       
00576                 
00577         return err;
00578     }
00579     
00580     // If Elastic and then Elastic-Plastic
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         // Update elastic part
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     // If E-P Response,
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         // For better numerical performance
00617         //Intersection_stress = Intersection_stress *(1.0 - TOL);
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         // E_ijkl * R_kl
00623         Hq = Ee("ijkl") * dQods("kl");
00624         Hq.null_indices();
00625         
00626         // L_ij * E_ijkl
00627         Hf = dFods("ij") * Ee("ijkl");
00628         Hf.null_indices();
00629         
00630         // L_ij * E_ijkl * R_kl
00631         lower = ( Hf("ij") * dQods("ij") ).trace(); 
00632         int i;  
00633         // Evolution of scalar (isotropic) internal variables in yield function
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         // Evolution of tensor (kinematic) internal variables in yield function
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         // L_ij * E_ijkl * d e_kl ( true ep strain increment)
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         // Plastic strain increment
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         // To obtain Eep
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         // Update internal scalar variables
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         // Update internal tensor variables
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         // Update elastic part
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     // I had to use the one line incr_strain = strain_incr; Problem of BJTensor;
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     //opserr << "YieldFun = " << YieldFun << endln;
00733     
00734     if ( YieldFun <= FTOL ) {      // If Elastic
00735         err += pointer_elastic_state->setStress(TrialStress);
00736         err += pointer_elastic_state->setStrain(TrialStrain);       
00737         Stiffness = Ee;
00738     }
00739     else {      // If Elastic-Plastic
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         // Evolution of scalar (isotropic) internal variables in yield function
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         // Evolution of tensor (kinematic) internal variables in yield function
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         // ################## Beginning of do-while ########################
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           // Update stress
00789           TrialStress -= (Hq *d2_lambda);
00790 
00791           // Update internal scalar variables
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           // Update internal tensor variables
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           // Update elastic part
00812           err += pointer_elastic_state->setStress(TrialStress);
00813 
00814           // Update Delta_lambda
00815           Delta_lambda += d2_lambda;
00816 
00817           // Update iter_counter
00818           iter_counter++;
00819           
00820           // Update Yield Function
00821           YieldFun = pointer_yield_function->YieldFunctionValue(TrialStress, *pointer_material_parameter);
00822           //opserr << "F = " << YieldFun << endln;
00823 
00824           //if (iter_counter == ITMAX)
00825           //  opserr << "Warning! The iteration number in the semi-implicit algorithm reaches to " << ITMAX << endln;
00826 
00827         } while (YieldFun > FTOL && iter_counter < ITMAX);
00828         // ################## End of do-while ########################
00829         
00830         if (Delta_lambda < 0.0)
00831           Delta_lambda = 0.0;
00832        
00833         // Return algorithmic stiffness tensor
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         // Need Work Here!
00854     opserr << "BackwardEuler is not yet implemented!" << endln;
00855         return 0;
00856 }
00857 
00858 
00859 // Trying to find intersection point according to M. Crisfield's book
00860 // "Non-linear Finite Element Analysis of Solids and Structures "  Chp 6.6.1 pp168.
00861 //================================================================================
00862 stresstensor NewTemplate3Dep::yield_surface_cross(const stresstensor & start_stress,
00863                                                   const stresstensor & end_stress, double a)
00864 {
00865     //double a = zbrentstress( start_stress, end_stress, 0.0, 1.0, TOL );
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 // Routine used by yield_surface_cross to find the stresstensor at cross point
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 

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