Beispiel #1
0
/* Take increments in strain and calculate new Particle: strains, rotation strain, plastic strain,
		stresses, strain energy, plastic energy, dissipated energy, angle
	dvij are (gradient rates X time increment) to give deformation gradient change
	For Axisymmetry: x->R, y->Z, z->theta, np==AXISYMMETRIC_MPM, otherwise dvzz=0
	This material tracks pressure and stores deviatoric stress only in particle stress tensor
*/
void Viscoelastic::MPMConstitutiveLaw(MPMBase *mptr,Matrix3 du,double delTime,int np,void *properties,ResidualStrains *res) const
{
    // Effective strain by deducting thermal strain (no shear thermal strain because isotropic)
	double eres=CTE*res->dT;
	if(DiffusionTask::active)
		eres+=CME*res->dC;
	
	// update pressure
	double delV = du.trace() - 3.*eres;
	UpdatePressure(mptr,delV,res,eres);
	
	// deviatoric strains increment
	// Actually find 2*de to avoid many multiples by two
	Tensor de;
	double dV = du.trace()/3.;
	de.xx = 2.*(du(0,0) - dV);
	de.yy = 2.*(du(1,1) - dV);
	de.zz = 2.*(du(2,2) - dV);
	de.xy = du(0,1)+du(1,0);
	if(np==THREED_MPM)
	{	de.xz = du(0,2)+du(2,0);
		de.yz = du(1,2)+du(2,1);
	}
	
	// Find initial 2*e(t) in ed
	Tensor *ep=mptr->GetStrainTensor();
	Tensor ed = *ep;
	double thirdV = (ed.xx+ed.yy+ed.zz)/3.;
	ed.xx = 2.*(ed.xx-thirdV);
	ed.yy = 2.*(ed.yy-thirdV);
	ed.zz = 2.*(ed.zz-thirdV);
							 
	// Increment total strains on the particle
    ep->xx += du(0,0);
    ep->yy += du(1,1);
	ep->zz += du(2,2);
    ep->xy += de.xy;
	if(np==THREED_MPM)
	{	ep->xz += de.xz;
		ep->yz += de.yz;
	}
	
	// get internal variable increments and update them too
	Tensor dak;
    double **ak =(double **)(mptr->GetHistoryPtr());
	int k;
    for(k=0;k<ntaus;k++)
    {   double tmp = exp(-delTime/tauk[k]);
		double tmpm1 = tmp-1.;
		double tmpp1 = tmp+1.;
		double arg = 0.25*delTime/tauk[k];					// 0.25 because e's have factor of 2
		dak.xx = tmpm1*ak[XX_HISTORY][k] + arg*(tmpp1*ed.xx + de.xx);
		dak.yy = tmpm1*ak[YY_HISTORY][k] + arg*(tmpp1*ed.yy + de.yy);
		dak.xy = tmpm1*ak[XY_HISTORY][k] + arg*(tmpp1*ed.xy + de.xy);
		dak.zz = tmpm1*ak[ZZ_HISTORY][k] + arg*(tmpp1*ed.zz + de.zz);
		ak[XX_HISTORY][k] += dak.xx;
		ak[YY_HISTORY][k] += dak.yy;
		ak[ZZ_HISTORY][k] += dak.zz;
		ak[XY_HISTORY][k] += dak.xy;
		
		if(np==THREED_MPM)
		{	dak.xz = tmpm1*ak[XZ_HISTORY][k] + arg*(tmpp1*ed.xz + de.xz);
			dak.yz = tmpm1*ak[YZ_HISTORY][k] + arg*(tmpp1*ed.yz + de.yz);
			ak[XZ_HISTORY][k] += dak.xz;
			ak[YZ_HISTORY][k] += dak.yz;
		}
    }
	
	// increment particle deviatoric stresses
	double dsig[6];
	dsig[XX] = Gered*de.xx;
	dsig[YY] = Gered*de.yy;
	dsig[ZZ] = Gered*de.zz;
	dsig[XY] = Gered*de.xy;
	if(np==THREED_MPM)
	{	dsig[XZ] = Gered*de.xz;
		dsig[YZ] = Gered*de.yz;
	}
    for(k=0;k<ntaus;k++)
	{	dsig[XX] -= TwoGkred[k]*dak.xx;
		dsig[YY] -= TwoGkred[k]*dak.yy;
		dsig[ZZ] -= TwoGkred[k]*dak.zz;
		dsig[XY] -= TwoGkred[k]*dak.xy;
		if(np==THREED_MPM)
		{	dsig[XZ] -= TwoGkred[k]*dak.xz;
			dsig[YZ] -= TwoGkred[k]*dak.yz;
		}
	}
	
	// Hypoelastic increment of particle deviatoric stresses
	Tensor *sp=mptr->GetStressTensor();
	Tensor st0 = *sp;
	double dwrotxy = du(1,0)-du(0,1);
	if(np==THREED_MPM)
	{	double dwrotxz = du(2,0)-du(0,2);
		double dwrotyz = du(2,1)-du(1,2);
		Hypo3DCalculations(mptr,dwrotxy,dwrotxz,dwrotyz,dsig);
	}
	else
	{	Hypo2DCalculations(mptr,-dwrotxy,dsig[XX],dsig[YY],dsig[XY]);
		sp->zz += dsig[ZZ];
	}
	
	// incremental work energy = shear energy (dilation and residual energy done in update pressure)
    double shearEnergy = 0.5*((sp->xx+st0.xx)*du(0,0) + (sp->yy+st0.yy)*du(1,1) + (sp->zz+st0.zz)*du(2,2)+
							  (sp->xy+st0.xy)*de.xy);
    if(np==THREED_MPM)
    {   shearEnergy += 0.5*((sp->xz+st0.xz)*de.xz + (sp->yz+st0.yz)*de.yz);
    }
    mptr->AddWorkEnergyAndResidualEnergy(shearEnergy,0.);
	
    // disispated energy per unit mass (dPhi/(rho0 V0)) (uJ/g)
    double dispEnergy = 0.;
    for(k=0;k<ntaus;k++)
	{	dispEnergy += TwoGkred[k]*(dak.xx*(0.5*(ed.xx+0.5*de.xx)-ak[XX_HISTORY][k]+0.5*dak.xx)
						+ dak.yy*(0.5*(ed.yy+0.5*de.yy)-ak[YY_HISTORY][k]+0.5*dak.yy)
						+ dak.zz*(0.5*(ed.zz+0.5*de.zz)-ak[ZZ_HISTORY][k]+0.5*dak.zz)
						+ dak.xy*(0.5*(ed.xy+0.5*de.xy)-ak[XY_HISTORY][k]+0.5*dak.xy));
		if(np==THREED_MPM)
		{	dispEnergy += TwoGkred[k]*(dak.xz*(0.5*(ed.xz+0.5*de.xz)-ak[XZ_HISTORY][k]+0.5*dak.xz)
							+ dak.yz*(0.5*(ed.yz+0.5*de.yz)-ak[YZ_HISTORY][k]+0.5*dak.yz));
		}
	}
    mptr->AddPlastEnergy(dispEnergy);
    
    // heat energy is Cv dT - 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 was done in update pressure
    IncrementHeatEnergy(mptr,0.,0.,dispEnergy);
}
Beispiel #2
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);
}
Beispiel #3
0
/* For 3D MPM analysis, take increments in strain and calculate new
    Particle: strains, rotation strain, stresses, strain energy, angle
    dvij are (gradient rates X time increment) to give deformation gradient change
    Assumes linear elastic, uses hypoelastic correction
*/
void Elastic::MPMConstLaw(MPMBase *mptr,double dvxx,double dvyy,double dvzz,double dvxy,double dvyx,
        double dvxz,double dvzx,double dvyz,double dvzy,double delTime,int np,void *properties,ResidualStrains *res) const
{
	// cast pointer to material-specific data
	ElasticProperties *p = (ElasticProperties *)properties;
	
	// Add to total strain
	Tensor *ep = mptr->GetStrainTensor();
    ep->xx += dvxx;
    ep->yy += dvyy;
    ep->zz += dvzz;
    double dgamxy = dvxy+dvyx;
    ep->xy += dgamxy;
    double dgamxz = dvxz+dvzx;
    ep->xz += dgamxz;
    double dgamyz = dvyz+dvzy;
    ep->yz += dgamyz;
	
	// rotational strain increments (particle updated by Hypo3D)
	double dwrotxy = dvyx-dvxy;
	double dwrotxz = dvzx-dvxz;
	double dwrotyz = dvzy-dvyz;
	
    // residual strains (thermal and moisture) (isotropic only)
	double exxr = p->alpha[0]*res->dT;
	double eyyr = p->alpha[1]*res->dT;
	double ezzr = p->alpha[2]*res->dT;
	double eyzr = p->alpha[3]*res->dT;
	double exzr = p->alpha[4]*res->dT;
	double exyr = p->alpha[5]*res->dT;
	if(DiffusionTask::active)
	{	exxr += p->beta[0]*res->dC;
		eyyr += p->beta[1]*res->dC;
		ezzr += p->beta[2]*res->dC;
		eyzr += p->beta[3]*res->dC;
		exzr += p->beta[4]*res->dC;
		exyr += p->beta[5]*res->dC;
	}
	
	// effective strains
	double dvxxeff = dvxx-exxr;
	double dvyyeff = dvyy-eyyr;
	double dvzzeff = dvzz-ezzr;
	double dgamyzeff = dgamyz-eyzr;
	double dgamxzeff = dgamxz-exzr;
	double dgamxyeff = dgamxy-exyr;
	
    // save initial stresses
	Tensor *sp=mptr->GetStressTensor();
    Tensor st0=*sp;
	
	// stress increments
	double delsp[6];
	int i;
	for(i=0;i<6;i++)
    {   delsp[i] = p->C[i][0]*dvxxeff + p->C[i][1]*dvyyeff + p->C[i][2]*dvzzeff
                    + p->C[i][3]*dgamyzeff + p->C[i][4]*dgamxzeff + p->C[i][5]*dgamxyeff;
    }
	
	// update stress (need to make hypoelastic)
	Hypo3DCalculations(mptr,dwrotxy,dwrotxz,dwrotyz,delsp);
	
	// work energy increment per unit mass (dU/(rho0 V0))
    mptr->AddWorkEnergyAndResidualEnergy(
						0.5*((st0.xx+sp->xx)*dvxx + (st0.yy+sp->yy)*dvyy
                            + (st0.zz+sp->zz)*dvzz  + (st0.yz+sp->yz)*dgamyz
                            + (st0.xz+sp->xz)*dgamxz + (st0.xy+sp->xy)*dgamxy),
						0.5*((st0.xx+sp->xx)*exxr + (st0.yy+sp->yy)*eyyr
							 + (st0.zz+sp->zz)*ezzr  + (st0.yz+sp->yz)*eyzr
							 + (st0.xz+sp->xz)*exzr + (st0.xy+sp->xy)*exyr));
    
    // track heat energy
    IncrementHeatEnergy(mptr,res->dT,0.,0.);

}