Esempio n. 1
0
// To allow some subclasses to support large deformations, the initial calculation for incremental
// deformation gradient (the dvij), volume change (delV) and relative volume (Jnew) can be
// handled first by the subclass. This mtehod then finishes the constitutive law
void IsoPlasticity::PlasticityConstLaw(MPMBase *mptr,double dvxx,double dvyy,double dvzz,double dvxy,double dvyx,
        double dvxz,double dvzx,double dvyz,double dvzy,double delTime,int np,double delV,double Jnew,double eres,
									   PlasticProperties *p,ResidualStrains *res) const
{
	// here dvij is total strain increment, dexxr is relative strain by subtracting off eres
    double dexxr=dvxx-eres;  
    double deyyr=dvyy-eres;
	double dezzr=dvzz-eres;				// use in plane strain only
    double dgxy=dvxy+dvyx;
    double dgxz=dvxz+dvzx;
	double dgyz=dvyz+dvzy;
	
	// rotational strain increments (particle updated by Hypo3D)
	double dwrotxy=dvyx-dvxy;
	double dwrotxz=dvzx-dvxz;
	double dwrotyz=dvzy-dvyz;
	
	// allow arbitrary equation of state for pressure
	UpdatePressure(mptr,delV,Jnew,np,p,res,eres);
	
    // Elastic deviatoric stress increment
	Tensor *ep=mptr->GetStrainTensor();
	Tensor *sp=mptr->GetStressTensor();
    Tensor stk,st0=*sp;
	double dsig[6];
    double thirdDelV = delV/3.;
	dsig[XX] = 2.*p->Gred*(dexxr-thirdDelV);
	dsig[YY] = 2.*p->Gred*(deyyr-thirdDelV);
	dsig[ZZ] = 2.*p->Gred*(dezzr-thirdDelV);
	dsig[YZ] = p->Gred*dgyz;
	dsig[XZ] = p->Gred*dgxz;
	dsig[XY] = p->Gred*dgxy;
    stk.xx = st0.xx + dsig[XX];
    stk.yy = st0.yy + dsig[YY];
	stk.zz = st0.zz + dsig[ZZ];
    stk.yz = st0.yz + dsig[YZ];
    stk.xz = st0.xz + dsig[XZ];
    stk.xy = st0.xy + dsig[XY];
  
    // Calculate plastic potential f = ||s|| - sqrt(2/3)*sy(alpha,rate,...)
	HardeningAlpha alpha;
	plasticLaw->UpdateTrialAlpha(mptr,np,&alpha);			// initialize to last value
	double strial = GetMagnitudeSFromDev(&stk,np);
    double ftrial = strial - SQRT_TWOTHIRDS*plasticLaw->GetYield(mptr,np,delTime,&alpha,p->hardProps);
	if(ftrial<0.)
	{	// elastic, update stress and strain energy as usual
	
		// Add to total strain
		ep->xx+=dvxx;
		ep->yy+=dvyy;
		ep->zz+=dvzz;
		ep->xy+=dgxy;
		ep->xz+=dgxz;
		ep->yz+=dgyz;
		
		// update stress (need to make hypoelastic)
		Hypo3DCalculations(mptr,dwrotxy,dwrotxz,dwrotyz,dsig);
		
		// work energy increment per unit mass (dU/(rho0 V0)) (uJ/g)
		mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dvxx
								+ (st0.yy+sp->yy)*dvyy
								+ (st0.zz+sp->zz)*dvzz
								+ (st0.yz+sp->yz)*dgyz
								+ (st0.xz+sp->xz)*dgxz
								+ (st0.xy+sp->xy)*dgxy));
								
        // heat energy is Cv(dT-dTq0) - dPhi, but dPhi is zero here
        // and Cv(dT-dTq0) was done in Update Pressure
        
		// give material chance to update history variables that change in elastic updates
		ElasticUpdateFinished(mptr,np,delTime);
		
		return;
	}
	
	// Find direction of plastic strain and lambda for this plastic state
	// Base class finds it numerically, subclass can override if solvable by more efficient meethods
	Tensor dfds;
	GetDfDsigma(strial,&stk,np,&dfds);
	double lambdak = plasticLaw->SolveForLambdaBracketed(mptr,np,strial,&stk,p->Gred,1.,1.,delTime,&alpha,p->hardProps);
	
	// Now have lambda, finish update on this particle
        
    // Plastic strain increments on particle
    double dexxp = lambdak*dfds.xx;
    double deyyp = lambdak*dfds.yy;
	double dezzp = lambdak*dfds.zz;
    double dgxyp = 2.*lambdak*dfds.xy;     // 2 for engineering plastic shear strain
    double dgxzp = 2.*lambdak*dfds.xz;     // 2 for engineering plastic shear strain
    double dgyzp = 2.*lambdak*dfds.yz;     // 2 for engineering plastic shear strain
	Tensor *eplast=mptr->GetPlasticStrainTensor();
	eplast->xx += dexxp;
    eplast->yy += deyyp;
	eplast->zz += dezzp;
    eplast->xy += dgxyp;
	eplast->xz += dgxzp;
    eplast->yz += dgyzp;
   
    // Elastic strain increments on particle
    ep->xx += (dvxx-dexxp);
    ep->yy += (dvyy-deyyp);
    ep->zz += (dvzz-dezzp);
    dgxy -= dgxyp;
    ep->xy += dgxy;
    dgxz -= dgxzp;
    ep->xz += dgxz;
    dgyz -= dgyzp;
	ep->yz += dgyz;
	
    // Elastic strain increment minus the residual terms by now subtracting plastic parts
    dexxr -= dexxp;
    deyyr -= deyyp;
	dezzr -= dezzp;				// plain strain only
	//dgxy, dgxz, dgyz done above

	// increment particle deviatoric stresses
	dsig[XX] -= 2.*p->Gred*dexxp;
	dsig[YY] -= 2.*p->Gred*deyyp;
	dsig[ZZ] -= 2.*p->Gred*dezzp;
	dsig[YZ] -= p->Gred*dgyzp;
	dsig[XZ] -= p->Gred*dgxzp;
	dsig[XY] -= p->Gred*dgxyp;
	Hypo3DCalculations(mptr,dwrotxy,dwrotxz,dwrotyz,dsig);
	
    // work energy increment per unit mass (dU/(rho0 V0)) (uJ/g)
	double workEnergy = 0.5*((st0.xx+sp->xx)*dvxx + (st0.yy+sp->yy)*dvzz
                               + (st0.zz+sp->zz)*dvzz + (st0.yz+sp->yz)*dgyz
                               + (st0.xz+sp->xz)*dgxz + (st0.xy+sp->xy)*dgxy);
    
    // plastic strain work
    double plastEnergy = lambdak*(sp->xx*dfds.xx + sp->yy*dfds.yy + sp->zz*dfds.zz
                                  + 2.*sp->xy*dfds.xy + 2.*sp->xz*dfds.xz + 2.*sp->yz*dfds.yz);
    
    // total work
    mptr->AddWorkEnergy(plastEnergy + workEnergy);
    
    // disispated energy per unit mass (dPhi/(rho0 V0)) (uJ/g)
    double qdalphaTerm = lambdak*SQRT_TWOTHIRDS*plasticLaw->GetYieldIncrement(mptr,np,delTime,&alpha,p->hardProps);
    double dispEnergy = plastEnergy - qdalphaTerm;
    
    // heat energy is Cv(dT-dTq0) - dPhi
    // The dPhi is subtracted here because it will show up in next
    //		time step within Cv dT (if adiabatic heating occurs)
    // The Cv(dT-dTq0) was done already in update pressure
    IncrementHeatEnergy(mptr,0.,0.,dispEnergy);
    
	// The cumulative dissipated energy is tracked in plastic energy
    // Setting the disp energy allows heating if mechanical energy is on
    mptr->AddPlastEnergy(dispEnergy);
    
	// update internal variables
	plasticLaw->UpdatePlasticInternal(mptr,np,&alpha);
}
Esempio n. 2
0
// To allow some subclasses to support large deformations, the initial calculation for incremental
// deformation gradient (the dvij), volume change (delV) can be
// handled first by the subclass. This mtehod then finishes the constitutive law
void IsoPlasticity::LRPlasticityConstLaw(MPMBase *mptr,double dexx,double deyy,double dezz,double dgxy,
									   double dgxz,double dgyz,double delTime,int np,double delV,double eres,
									   PlasticProperties *p,ResidualStrains *res,Matrix3 *dR) const
{
	// here dvij is total strain increment, dexxr is relative strain by subtracting off eres
    double dexxr=dexx-eres;
    double deyyr=deyy-eres;
	double dezzr=dezz-eres;
	
	// allow arbitrary equation of state for pressure
	double dTq0 = 0.,dispEnergy = 0.;
	UpdatePressure(mptr,delV,np,p,res,eres,dTq0,dispEnergy);
	
    // Elastic deviatoric stress increment
	Tensor *sp=mptr->GetStressTensor();
    Tensor stk;
	//Tensor st0=*sp;
	double dsig[6];
    double thirdDelV = delV/3.;
	dsig[XX] = 2.*p->Gred*(dexxr-thirdDelV);
	dsig[YY] = 2.*p->Gred*(deyyr-thirdDelV);
	dsig[ZZ] = 2.*p->Gred*(dezzr-thirdDelV);
	dsig[YZ] = p->Gred*dgyz;
	dsig[XZ] = p->Gred*dgxz;
	dsig[XY] = p->Gred*dgxy;
	
	// incremental rotate of prior strain
	Tensor *eplast=mptr->GetAltStrainTensor();
	Matrix3 etn(eplast->xx,0.5*eplast->xy,0.5*eplast->xz,0.5*eplast->xy,eplast->yy,0.5*eplast->yz,
				0.5*eplast->xz,0.5*eplast->yz,eplast->zz);
	Matrix3 etr = etn.RMRT(*dR);
	Matrix3 stn(sp->xx,sp->xy,sp->xz,sp->xy,sp->yy,sp->yz,sp->xz,sp->yz,sp->zz);
	Matrix3 str = stn.RMRT(*dR);
	
    // trial deviatoric stress
    stk.xx = str(0,0) + dsig[XX];
    stk.yy = str(1,1) + dsig[YY];
	stk.zz = str(2,2) + dsig[ZZ];
    stk.yz = str(1,2) + dsig[YZ];
    stk.xz = str(0,2) + dsig[XZ];
    stk.xy = str(0,1) + dsig[XY];
	
    // Calculate plastic potential f = ||s|| - sqrt(2/3)*sy(alpha,rate,...)
	HardeningAlpha alpha;
	plasticLaw->UpdateTrialAlpha(mptr,np,&alpha,0);			// initialize to last value
	double strial = GetMagnitudeSFromDev(&stk,np);
    double ftrial = strial - SQRT_TWOTHIRDS*plasticLaw->GetYield(mptr,np,delTime,&alpha,p->hardProps);
	if(ftrial<0.)
	{	// elastic, update stress and strain energy as usual
		
		// set in-plane deviatoric stress
		*sp = stk;

		// rotate plastic strain
		eplast->xx = etr(0,0);
		eplast->yy = etr(1,1);
		eplast->zz = etr(2,2);
		eplast->xy = 2.*etr(0,1);
		eplast->xz = 2.*etr(0,2);
		eplast->yz = 2.*etr(1,2);
		
		// work energy increment per unit mass (dU/(rho0 V0)) (nJ/g)
		mptr->AddWorkEnergy(sp->xx*dexx + sp->yy*deyy + sp->zz*dezz
								 + sp->yz*dgyz + sp->xz*dgxz + sp->xy*dgxy);
		//mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dexx + (st0.yy+sp->yy)*deyy + (st0.zz+sp->zz)*dezz
		//						 + (st0.yz+sp->yz)*dgyz + (st0.xz+sp->xz)*dgxz + (st0.xy+sp->xy)*dgxy));
		
		// give material chance to update history variables that change in elastic updates
		plasticLaw->ElasticUpdateFinished(mptr,np,delTime,0);
		
		// heat energy from pressure and any pressure method items
		IncrementHeatEnergy(mptr,res->dT,dTq0,dispEnergy);
		
		return;
	}
	
	// Find direction of plastic strain and lambda for this plastic state
	// Base class finds it numerically, subclass can override if solvable by more efficient meethods
	Tensor dfds;
	GetDfDsigma(strial,&stk,np,&dfds);
	double lambdak = plasticLaw->SolveForLambdaBracketed(mptr,np,strial,&stk,p->Gred,1.,1.,delTime,&alpha,p->hardProps,0);
	
	// Now have lambda, finish update on this particle
	
    // Plastic strain increments on particle
    double dexxp = lambdak*dfds.xx;
    double deyyp = lambdak*dfds.yy;
	double dezzp = lambdak*dfds.zz;
    double dgxyp = 2.*lambdak*dfds.xy;     // 2 for engineering plastic shear strain
    double dgxzp = 2.*lambdak*dfds.xz;     // 2 for engineering plastic shear strain
    double dgyzp = 2.*lambdak*dfds.yz;     // 2 for engineering plastic shear strain
	
	// incremental plastic strain
	eplast->xx = etr(0,0) + dexxp;
    eplast->yy = etr(1,1) + deyyp;
	eplast->zz = etr(2,2) + dezzp;
    eplast->xy = 2.*etr(0,1) + dgxyp;
	eplast->xz = 2.*etr(0,2) + dgxzp;
    eplast->yz = 2.*etr(1,2) + dgyzp;
	
	// increment particle deviatoric stresses
	sp->xx = stk.xx - 2.*p->Gred*dexxp;
	sp->yy = stk.yy - 2.*p->Gred*deyyp;
	sp->zz = stk.zz - 2.*p->Gred*dezzp;
	sp->yz = stk.yz - p->Gred*dgyzp;
	sp->xz = stk.xz - p->Gred*dgxzp;
	sp->xy = stk.xy - p->Gred*dgxyp;
	
    // work energy increment per unit mass (dU/(rho0 V0)) (nJ/g)
	double workEnergy = sp->xx*dexx + sp->yy*dezz + sp->zz*dezz + sp->yz*dgyz + sp->xz*dgxz + sp->xy*dgxy;
 	//double workEnergy = 0.5*((st0.xx+sp->xx)*dexx + (st0.yy+sp->yy)*dezz + (st0.zz+sp->zz)*dezz
	//						 + (st0.yz+sp->yz)*dgyz + (st0.xz+sp->xz)*dgxz + (st0.xy+sp->xy)*dgxy);
   
    // total work
    mptr->AddWorkEnergy(workEnergy);
    
    // plastic strain work
    double plastEnergy = lambdak*(sp->xx*dfds.xx + sp->yy*dfds.yy + sp->zz*dfds.zz
                                  + 2.*sp->xy*dfds.xy + 2.*sp->xz*dfds.xz + 2.*sp->yz*dfds.yz);
    
    // and subtrace q dalpa disispated energy per unit mass (dPhi/(rho0 V0)) (nJ/g)
    double qdalphaTerm = lambdak*SQRT_TWOTHIRDS*plasticLaw->GetYieldIncrement(mptr,np,delTime,&alpha,p->hardProps);
    dispEnergy += plastEnergy - qdalphaTerm;
    
	// The cumulative dissipated energy is tracked in plastic energy
    // Setting the disp energy allows heating if mechanical energy is on
    mptr->AddPlastEnergy(dispEnergy);
    
    // heat energy is Cv(dT-dTq0) - dPhi
    // The dPhi is subtracted here because it will show up in next
    //		time step within Cv dT (if adiabatic heating occurs)
    // The Cv(dT-dTq0) was done already in update pressure
    IncrementHeatEnergy(mptr,res->dT,dTq0,dispEnergy);
    
	// update internal variables
	plasticLaw->UpdatePlasticInternal(mptr,np,&alpha,0);
}
Esempio n. 3
0
// To allow some subclasses to support large deformations, the initial calculation for incremental
// deformation gradient (the dvij), volume change (delV) and relative volume (Jnew) can be
// handled first by the subclass. This mtehod then finishes the constitutive law
void IsoPlasticity::PlasticityConstLaw(MPMBase *mptr,double dvxx,double dvyy,double dvxy,double dvyx,
                                double dvzz,double delTime,int np,double delV,double Jnew,double eres,
									   PlasticProperties *p,ResidualStrains *res) const
{
	// here dvij is total strain increment, dexxr is relative strain by subtracting off eres
    double dexxr = dvxx-eres;			// trial dexx=dvxx
    double deyyr = dvyy-eres;			// trial deyy=dvyy
	double dezzr = dvzz-eres;			// In plane strain trial dezz=0, dvzz=0 except in axisymmetric
    double dgxy = dvxy+dvyx;			// no need to substract residual strain
    double dwrotxy = dvyx-dvxy;

	// allow arbitrary equation of state for pressure
    double P0 = mptr->GetPressure();
	UpdatePressure(mptr,delV,Jnew,np,p,res,eres);
    double Pfinal = mptr->GetPressure();
	
    // Deviatoric stress increment
	Tensor *ep=mptr->GetStrainTensor();
	Tensor *sp=mptr->GetStressTensor();
    Tensor dels,stk,st0=*sp;
    double thirdDelV = delV/3.;
	dels.xx = 2.*p->Gred*(dexxr-thirdDelV);
	dels.yy = 2.*p->Gred*(deyyr-thirdDelV);
	if(np==PLANE_STRESS_MPM)
		dels.zz = Pfinal-P0;
	else
		dels.zz = 2.*p->Gred*(dezzr-thirdDelV);
	dels.xy = p->Gred*dgxy;
    
    // trial deviatoric stress
    stk.xx = st0.xx + dels.xx;
    stk.yy = st0.yy + dels.yy;
	stk.zz = st0.zz + dels.zz;
    stk.xy = st0.xy + dels.xy;
  
    // Calculate plastic potential f = ||s|| - sqrt(2/3)*sy(alpha,rate,...)
	HardeningAlpha alpha;
	plasticLaw->UpdateTrialAlpha(mptr,np,&alpha);			// initialize to last value and zero plastic strain rate
	double strial = GetMagnitudeSFromDev(&stk,np);
    double ftrial = strial - SQRT_TWOTHIRDS*plasticLaw->GetYield(mptr,np,delTime,&alpha,p->hardProps);
	if(ftrial<0.)
	{	// elastic, update stress and strain energy as usual
	
		// Add input strain increment to elastic strain on particle
		ep->xx += dvxx;
		ep->yy += dvyy;
		ep->xy += dgxy;
				
		// increment deviatoric stress (Units N/m^2  cm^3/g) (pressure not needed here)
		Hypo2DCalculations(mptr,-dwrotxy,dels.xx,dels.yy,dels.xy);
		
		// work energy increment per unit mass (dU/(rho0 V0)) (by midpoint rule) (uJ/g)
        // energy units are also Pa cm^3/g, i.e., same as stress units
        sp->zz = stk.zz;
        if(np==AXISYMMETRIC_MPM)
		{	ep->zz += dvzz;
			mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dvxx + (st0.yy+sp->yy)*dvyy
									   + (st0.xy+sp->xy)*dgxy + (st0.zz+sp->zz)*dvzz));
		}
		else
        {   mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dvxx + (st0.yy+sp->yy)*dvyy
									   + (st0.xy+sp->xy)*dgxy));
		}
		
        // heat energy is Cv(dT-dTq0) - dPhi, but dPhi is zero here
        // and Cv(dT-dTq0) was done in Update pressure
        
		// give subclass material chance to update history variables that change in elastic updates
		ElasticUpdateFinished(mptr,np,delTime);
		
		return;
    }
    
	// Find  lambda for this plastic state
	// Base class finds it numerically, subclass can override if solvable by more efficient methods
    double lambdak = plasticLaw->SolveForLambdaBracketed(mptr,np,strial,&stk,p->Gred,p->psKred,Pfinal,delTime,&alpha,p->hardProps);
	
	// Now have lambda, finish update on this particle
	Tensor dfds;
	if(np==PLANE_STRESS_MPM)
    {   // get final stress state
        double d1 = (1 + p->psKred*lambdak);
		double d2 = (1.+2.*p->Gred*lambdak);
		double n1 = (stk.xx+stk.yy-2.*Pfinal)/d1;
		double n2 = (-stk.xx+stk.yy)/d2;
		double sxx = (n1-n2)/2.;
		double syy = (n1+n2)/2.;
		double txy = stk.xy/d2;
        
        // find increment in deviatoric stress
		dels.xx = sxx+Pfinal-st0.xx;
		dels.yy = syy+Pfinal-st0.yy;
		dels.xy = txy-st0.xy;
        
        // get final direction
        dfds.xx = (2.*sxx-syy)/3.;
        dfds.yy = (2.*syy-sxx)/3.;
        dfds.zz = -(dfds.xx+dfds.yy);
        dfds.xy = txy;				// tensorial shear strain
		
		// If fully plastic, the increment in deviatoric stress should be zero
		// sxx = sigmaxx+Pfinal = st0.xx, syy = sigmayy+Pfinal = st0.yy, szz = Pfinal
		// But first two must be wrong because trace is no longer zero?
		//
		// This is probably wrong
		// i.e.:	n1 + 2*Pfinal = st0.xx+st0.yy
		//			(stk.xx+stk.yy)/d1 - 2*Pfinal*(1/d1-1) = st0.xx+st0.yy
		// But (stk.xx+stk.yy) = (st0.xx+st0.yy) + 2.*Gred*(dexxr+deyyr-2*thirdDelV)
		//			(st0.xx+st0.yy)(1/d1-1) - 2*Pfinal*(1/d1-1) = -2.*Gred*(dexxr+deyyr-2*thirdDelV)/d1
		//			(st0.xx+st0.yy-2*Pfinal)*(1-d1) = -2.*Gred*(dexxr+deyyr-2*thirdDelV)
		//			B*Kred*lam = 2.*Gred*A    or    lam = 2.*Gred*A/(B*Kred)
		// where B = st0.xx+st0.yy-2*Pfinal, and A = (dexxr+deyyr-2*thirdDelV)
		// Then  d1 = 1+2*Gred*A/B, n1 = ((st0.xx+st0.yy) + 2*Gred*A - 2*Pfinal)/d1 = (B+2*Gred*A)*B/(B+2*Gred*A) = B
		//
		// Also expect syy-sxx = sigmayy-sigmaxx = st0.yy-st0.xx = n2
		//			(stk.yy-stk.xx)/d2 = st0.yy-st0.xx
		//			(st0.yy-st0.xx)/d2 + 2*Gred*(deyyr-dexxr)/d2 = (st0.yy-st0.xx)
		//			(st0.yy-st0.xx)(d2-1) = - 2*Gred*(deyyr-dexxr)
		//          lam = (deyyr-dexxr)/(st0.yy-st0.xx)
		// Then n2 = (st0.yy-st0.xx + 2*Gred*(deyyr-dexxr))/(1+2*Gred*(deyyr-dexxr)/(st0.yy-st0.xx)) = st0.yy-st0.xx
		//
		// But these to lam's seem to differ?
		// We can write 
	}
    else
    {   // get final direction
        GetDfDsigma(strial,&stk,np,&dfds);
    }
         
    // Plastic strain increments on particle
    double dexxp = lambdak*dfds.xx;
    double deyyp = lambdak*dfds.yy;
	double dezzp = lambdak*dfds.zz;
    double dgxyp = 2.*lambdak*dfds.xy;     // 2 for engineering plastic shear strain
	Tensor *eplast=mptr->GetPlasticStrainTensor();
    eplast->xx += dexxp;
    eplast->yy += deyyp;
    eplast->xy += dgxyp;
	eplast->zz += dezzp;
    
    // Elastic strain increments on particle
    ep->xx += (dvxx-dexxp);
    ep->yy += (dvyy-deyyp);
    dgxy -= dgxyp;
    ep->xy += dgxy;
	if(np==PLANE_STRESS_MPM)
		ep->zz += eres - p->psLr2G*(dexxr+deyyr+dezzp);
	else
	{	// plain strain and axisymmetric when plastic increments is dezzp
		// In plain strain, dvzz=0 elastic increment is -dezzp to zz strain total is zero
		// Axisymmetry can have non-zero hoop strain
		ep->zz += (dvzz-dezzp);
		dezzr -= dezzp; 
	}
	
    // Elastic strain increment minus the residual terms by now subtracting plastic parts
    dexxr -= dexxp;
    deyyr -= deyyp;
	//dgxy -= dgxyp;			// done above
	//dezzr -= dezzp;			// plane strain and axisymmetry done above, plain stress not needed

	// increment particle deviatoric stresses (plane stress increments found above)
	if(np!=PLANE_STRESS_MPM)
	{	dels.xx -= 2.*p->Gred*dexxp;
		dels.yy -= 2.*p->Gred*deyyp;
		dels.xy -= p->Gred*dgxyp;
		dels.zz -= 2.*p->Gred*dezzp;
		sp->zz += dels.zz;
	}
    else
        sp->zz = Pfinal;          // now equal to Pfinal
        
	Hypo2DCalculations(mptr,-dwrotxy,dels.xx,dels.yy,dels.xy);
	
    // Elastic work increment per unit mass (dU/(rho0 V0)) (uJ/g)
    double workEnergy = 0.5*((st0.xx+sp->xx)*dvxx
                               + (st0.yy+sp->yy)*dvyy
                               + (st0.xy+sp->xy)*dgxy);
	if(np==AXISYMMETRIC_MPM)
    {	workEnergy += 0.5*(st0.zz+sp->zz)*dvzz;
	}
    
    // plastic strain work
    double plastEnergy = lambdak*(sp->xx*dfds.xx + sp->yy*dfds.yy + sp->zz*dfds.zz + 2.*sp->xy*dfds.xy);
    
    // total work
    mptr->AddWorkEnergy(plastEnergy + workEnergy);
    
    // disispated energy per unit mass (dPhi/(rho0 V0)) (uJ/g)
    double qdalphaTerm = lambdak*SQRT_TWOTHIRDS*plasticLaw->GetYieldIncrement(mptr,np,delTime,&alpha,p->hardProps);
    double dispEnergy = plastEnergy - qdalphaTerm;
    
    // heat energy is Cv(dT-dTq0) - dPhi
    // The dPhi is subtracted here because it will show up in next
    //		time step within Cv dT (if adibatic heating occurs)
    // The Cv(dT-dTq0) was done in update pressure
    IncrementHeatEnergy(mptr,0.,0.,dispEnergy);
    
	// The cumulative dissipated energy is tracked in plastic energy
    mptr->AddPlastEnergy(dispEnergy);
    
	// update internal variables
	plasticLaw->UpdatePlasticInternal(mptr,np,&alpha);
}
Esempio n. 4
0
// To allow some subclasses to support large deformations, the initial calculation for incremental
// deformation gradient (the dvij), volume change (delV)
// handled first by the subclass. This method then finishes the constitutive law
void IsoPlasticity::LRPlasticityConstLaw(MPMBase *mptr,double dexx,double deyy,double dgxy,
									   double dezz,double delTime,int np,double delV,double eres,
									   PlasticProperties *p,ResidualStrains *res,Matrix3 *dR) const
{
	// here deij is total strain increment, dexxr is relative strain by subtracting off eres
    double dexxr = dexx-eres;
    double deyyr = deyy-eres;
	double dezzr = dezz-eres;			// In plane strain trial dezz=0, but not in axisymmetric
	
	// allow arbitrary equation of state for pressure
    double P0 = mptr->GetPressure();
	double dTq0 = 0.,dispEnergy = 0.;
	UpdatePressure(mptr,delV,np,p,res,eres,dTq0,dispEnergy);
    double Pfinal = mptr->GetPressure();
	
    // Deviatoric stress increment
	Tensor *sp=mptr->GetStressTensor();
    Tensor dels,stk;
	//Tensor st0=*sp;
    double thirdDelV = delV/3.;
	dels.xx = 2.*p->Gred*(dexxr-thirdDelV);
	dels.yy = 2.*p->Gred*(deyyr-thirdDelV);
	if(np==PLANE_STRESS_MPM)
		dels.zz = Pfinal-P0;
	else
		dels.zz = 2.*p->Gred*(dezzr-thirdDelV);
	dels.xy = p->Gred*dgxy;
	
	// incremental rotate of plastic strain
	Tensor *eplast=mptr->GetAltStrainTensor();
	Matrix3 etn(eplast->xx,0.5*eplast->xy,0.5*eplast->xy,eplast->yy,eplast->zz);
	Matrix3 etr = etn.RMRT(*dR);
	eplast->xx = etr(0,0);
	eplast->yy = etr(1,1);
	eplast->xy = 2.*etr(0,1);
	
	// incremental rotation of stress
	Matrix3 stn(sp->xx,sp->xy,sp->xy,sp->yy,sp->zz);
	Matrix3 str = stn.RMRT(*dR);
	
    // trial deviatoric stress
    stk.xx = str(0,0) + dels.xx;
    stk.yy = str(1,1) + dels.yy;
	stk.zz = str(2,2) + dels.zz;
    stk.xy = str(0,1) + dels.xy;
	
    // Calculate plastic potential f = ||s|| - sqrt(2/3)*sy(alpha,rate,...)
	HardeningAlpha alpha;
	plasticLaw->UpdateTrialAlpha(mptr,np,&alpha,0);			// initialize to last value and zero plastic strain rate
	double strial = GetMagnitudeSFromDev(&stk,np);
    double ftrial = strial - SQRT_TWOTHIRDS*plasticLaw->GetYield(mptr,np,delTime,&alpha,p->hardProps);
	if(ftrial<0.)
	{	// elastic, update stress and strain energy as usual
		
		// set in plane deviatoric stress
		sp->xx = stk.xx;
		sp->xy = stk.xy;
		sp->yy = stk.yy;
        sp->zz = stk.zz;
		
		// work energy increment per unit mass (dU/(rho0 V0)) (by midpoint rule) (nJ/g)
        // energy units are also Pa mm^3/g, i.e., same as stress units
        if(np==AXISYMMETRIC_MPM)
		{	mptr->AddWorkEnergy(sp->xx*dexx + sp->yy*deyy + sp->xy*dgxy + sp->zz*dezz);
			//mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dexx + (st0.yy+sp->yy)*deyy + (st0.xy+sp->xy)*dgxy + (st0.zz+sp->zz)*dezz));
		}
		else if(np==PLANE_STRESS_MPM)
		{	// zz deformation
			mptr->IncrementDeformationGradientZZ(-p->psLr2G*(dexxr+deyyr) + eres);
			mptr->AddWorkEnergy(sp->xx*dexx + sp->yy*deyy + sp->xy*dgxy);
			//mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dexx + (st0.yy+sp->yy)*deyy + (st0.xy+sp->xy)*dgxy));
		}
		else
        {   mptr->AddWorkEnergy(sp->xx*dexx + sp->yy*deyy + sp->xy*dgxy);
			//mptr->AddWorkEnergy(0.5*((st0.xx+sp->xx)*dexx + (st0.yy+sp->yy)*deyy + (st0.xy+sp->xy)*dgxy));
		}
		
		// give subclass material chance to update history variables that change in elastic updates
		plasticLaw->ElasticUpdateFinished(mptr,np,delTime,0);
		
		// heat energy from pressure and any pressure method items
		IncrementHeatEnergy(mptr,res->dT,dTq0,dispEnergy);
		
		return;
    }
    
	// Find  lambda for this plastic state
	// Base class finds it numerically, subclass can override if solvable by more efficient methods
    double lambdak = plasticLaw->SolveForLambdaBracketed(mptr,np,strial,&stk,p->Gred,p->psKred,Pfinal,delTime,&alpha,p->hardProps,0);
	
	// Now have lambda, finish update on this particle
	Tensor dfds;
	if(np==PLANE_STRESS_MPM)
    {   // get final stress state
        double d1 = (1 + p->psKred*lambdak);
		double d2 = (1.+2.*p->Gred*lambdak);
		double n1 = (stk.xx+stk.yy-2.*Pfinal)/d1;
		double n2 = (-stk.xx+stk.yy)/d2;
		double sxx = (n1-n2)/2.;
		double syy = (n1+n2)/2.;
		double txy = stk.xy/d2;
        
        // find increment in deviatoric stress
		dels.xx = sxx+Pfinal-sp->xx;
		dels.yy = syy+Pfinal-sp->yy;
		dels.xy = txy-sp->xy;
        
        // get final direction
        dfds.xx = (2.*sxx-syy)/3.;
        dfds.yy = (2.*syy-sxx)/3.;
        dfds.zz = -(dfds.xx+dfds.yy);
        dfds.xy = txy;				// tensorial shear strain
		
		// zz deformation
		mptr->IncrementDeformationGradientZZ(-p->psLr2G*(dexxr+deyyr - lambdak*(dfds.xx+dfds.yy)) + eres + lambdak*dfds.zz);
		
		// If fully plastic, the increment in deviatoric stress should be zero
		// sxx = sigmaxx+Pfinal = st0.xx, syy = sigmayy+Pfinal = st0.yy, szz = Pfinal
		// But first two must be wrong because trace is no longer zero?
		//
		// This is probably wrong
		// i.e.:	n1 + 2*Pfinal = st0.xx+st0.yy
		//			(stk.xx+stk.yy)/d1 - 2*Pfinal*(1/d1-1) = st0.xx+st0.yy
		// But (stk.xx+stk.yy) = (st0.xx+st0.yy) + 2.*Gred*(dexxr+deyyr-2*thirdDelV)
		//			(st0.xx+st0.yy)(1/d1-1) - 2*Pfinal*(1/d1-1) = -2.*Gred*(dexxr+deyyr-2*thirdDelV)/d1
		//			(st0.xx+st0.yy-2*Pfinal)*(1-d1) = -2.*Gred*(dexxr+deyyr-2*thirdDelV)
		//			B*Kred*lam = 2.*Gred*A    or    lam = 2.*Gred*A/(B*Kred)
		// where B = st0.xx+st0.yy-2*Pfinal, and A = (dexxr+deyyr-2*thirdDelV)
		// Then  d1 = 1+2*Gred*A/B, n1 = ((st0.xx+st0.yy) + 2*Gred*A - 2*Pfinal)/d1 = (B+2*Gred*A)*B/(B+2*Gred*A) = B
		//
		// Also expect syy-sxx = sigmayy-sigmaxx = st0.yy-st0.xx = n2
		//			(stk.yy-stk.xx)/d2 = st0.yy-st0.xx
		//			(st0.yy-st0.xx)/d2 + 2*Gred*(deyyr-dexxr)/d2 = (st0.yy-st0.xx)
		//			(st0.yy-st0.xx)(d2-1) = - 2*Gred*(deyyr-dexxr)
		//          lam = (deyyr-dexxr)/(st0.yy-st0.xx)
		// Then n2 = (st0.yy-st0.xx + 2*Gred*(deyyr-dexxr))/(1+2*Gred*(deyyr-dexxr)/(st0.yy-st0.xx)) = st0.yy-st0.xx
		//
		// But these two lam's seem to differ?
		// We can write
	}
    else
    {   // get final direction
        GetDfDsigma(strial,&stk,np,&dfds);
    }
	
    // Plastic strain increments on particle
    double dexxp = lambdak*dfds.xx;
    double deyyp = lambdak*dfds.yy;
	double dezzp = lambdak*dfds.zz;
    double dgxyp = 2.*lambdak*dfds.xy;     // 2 for engineering plastic shear strain
	
	eplast->xx += dexxp;
    eplast->yy += deyyp;
	eplast->zz += dezzp;
    eplast->xy += dgxyp;
	
	// increment particle deviatoric stresses (plane stress increments found above)
	if(np!=PLANE_STRESS_MPM)
	{	dels.xx -= 2.*p->Gred*dexxp;
		dels.yy -= 2.*p->Gred*deyyp;
		dels.xy -= p->Gred*dgxyp;
		dels.zz -= 2.*p->Gred*dezzp;
		sp->zz += dels.zz;
	}
    else
        sp->zz = Pfinal;          // now equal to Pfinal
	
	// update in-plane stressees
	sp->xx = str(0,0) + dels.xx;
	sp->yy = str(1,1) + dels.yy;
	sp->xy = str(0,1) + dels.xy;
	
    // Elastic work increment per unit mass (dU/(rho0 V0)) (nJ/g)
	double workEnergy = sp->xx*dexx + sp->yy*deyy + sp->xy*dgxy;
	//double workEnergy = 0.5*((st0.xx+sp->xx)*dexx + (st0.yy+sp->yy)*deyy + (st0.xy+sp->xy)*dgxy);
	if(np==AXISYMMETRIC_MPM)
    {	workEnergy += sp->zz*dezz;
		//workEnergy += 0.5*(st0.zz+sp->zz)*dezz;
	}
    
    // total work
    mptr->AddWorkEnergy(workEnergy);
    
    // plastic strain work
    double plastEnergy = lambdak*(sp->xx*dfds.xx + sp->yy*dfds.yy + sp->zz*dfds.zz + 2.*sp->xy*dfds.xy);
    
    // dand subtract q dalpha to get isispated energy per unit mass (dPhi/(rho0 V0)) (nJ/g)
    double qdalphaTerm = lambdak*SQRT_TWOTHIRDS*plasticLaw->GetYieldIncrement(mptr,np,delTime,&alpha,p->hardProps);
    dispEnergy += plastEnergy - qdalphaTerm;
    
	// The cumulative dissipated energy is tracked in plastic energy
    mptr->AddPlastEnergy(dispEnergy);
    
    // heat energy is Cv(dT-dTq0) - dPhi
    // The dPhi is subtracted here because it will show up in next
    //		time step within Cv dT (if adibatic heating occurs)
    IncrementHeatEnergy(mptr,res->dT,dTq0,dispEnergy);
    
	// update internal variables
	plasticLaw->UpdatePlasticInternal(mptr,np,&alpha,0);
}