Esempio n. 1
0
int XmlGspInterface::readFile(const QString &fileName)
{
	if(XMLQtInterface::readFile(fileName) == 0)
		return 0;

	QFileInfo fi(fileName);
	QString path = (fi.path().length() > 3) ? QString(fi.path() + "/") : fi.path();

	QDomDocument doc("OGS-PROJECT-DOM");
	doc.setContent(_fileData);
	QDomElement docElement = doc.documentElement(); //OpenGeoSysProject
	if (docElement.nodeName().compare("OpenGeoSysProject"))
	{
		ERR("XmlGspInterface::readFile(): Unexpected XML root.");
		return 0;
	}

	QDomNodeList fileList = docElement.childNodes();

	for(int i = 0; i < fileList.count(); i++)
	{
		const QString file_node(fileList.at(i).nodeName());
		if (file_node.compare("geo") == 0)
		{
			XmlGmlInterface gml(*(_project.getGEOObjects()));
			const QDomNodeList childList = fileList.at(i).childNodes();
			for(int j = 0; j < childList.count(); j++)
			{
				const QDomNode child_node (childList.at(j));
				if (child_node.nodeName().compare("file") == 0)
				{
					DBUG("XmlGspInterface::readFile(): path: \"%s\".",
					     path.data());
					DBUG("XmlGspInterface::readFile(): file name: \"%s\".",
					     (child_node.toElement().text()).data());
					gml.readFile(QString(path + child_node.toElement().text()));
				}
			}
		}
		else if (file_node.compare("stn") == 0)
		{
			XmlStnInterface stn(*(_project.getGEOObjects()));
			const QDomNodeList childList = fileList.at(i).childNodes();
			for(int j = 0; j < childList.count(); j++)
				if (childList.at(j).nodeName().compare("file") == 0)
					stn.readFile(QString(path +
					                     childList.at(j).toElement().text()));
		}
		else if (file_node.compare("msh") == 0)
		{
			const std::string msh_name = path.toStdString() +
			                             fileList.at(i).toElement().text().toStdString();
			MeshLib::Mesh* msh = FileIO::readMeshFromFile(msh_name);
			if (msh)
				_project.addMesh(msh);
		}
	}

	return 1;
}
Esempio n. 2
0
bool XmlGspInterface::write()
{
	GeoLib::GEOObjects* geoObjects = _project.getGEOObjects();
	QFileInfo fi(QString::fromStdString(_filename));
	std::string path((fi.absolutePath()).toStdString() + "/");

	_out << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"; // xml definition
	_out << "<?xml-stylesheet type=\"text/xsl\" href=\"OpenGeoSysProject.xsl\"?>\n\n"; // stylefile definition

	QDomDocument doc("OGS-PROJECT-DOM");
	QDomElement root = doc.createElement("OpenGeoSysProject");
	root.setAttribute( "xmlns:ogs", "http://www.opengeosys.org" );
	root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
	root.setAttribute( "xsi:noNamespaceSchemaLocation",
	                   "http://www.opengeosys.org/images/xsd/OpenGeoSysProject.xsd" );

	doc.appendChild(root);

	// GML
	std::vector<std::string> geoNames;
	geoObjects->getGeometryNames(geoNames);
	for (std::vector<std::string>::const_iterator it(geoNames.begin()); it != geoNames.end(); ++it)
	{
		// write GLI file
		XmlGmlInterface gml(*geoObjects);
		std::string name(*it);
		gml.setNameForExport(name);
		if (gml.writeToFile(std::string(path + name + ".gml")))
		{
			// write entry in project file
			QDomElement geoTag = doc.createElement("geo");
			root.appendChild(geoTag);
			QDomElement fileNameTag = doc.createElement("file");
			geoTag.appendChild(fileNameTag);
			QDomText fileNameText =
			        doc.createTextNode(QString::fromStdString(name + ".gml"));
			fileNameTag.appendChild(fileNameText);
		}
	}

	// MSH
	const std::vector<MeshLib::Mesh*> msh_vec = _project.getMeshObjects();
	for (std::vector<MeshLib::Mesh*>::const_iterator it(msh_vec.begin()); it != msh_vec.end(); ++it)
	{
		// write mesh file
		Legacy::MeshIO meshIO;
		meshIO.setMesh(*it);
		std::string fileName(path + (*it)->getName());
		meshIO.writeToFile(fileName);

		// write entry in project file
		QDomElement mshTag = doc.createElement("msh");
		root.appendChild(mshTag);
		QDomElement fileNameTag = doc.createElement("file");
		mshTag.appendChild(fileNameTag);
		QDomText fileNameText = doc.createTextNode(QString::fromStdString((*it)->getName()));
		fileNameTag.appendChild(fileNameText);
	}

	// STN
	std::vector<std::string> stnNames;
	geoObjects->getStationVectorNames(stnNames);
	for (std::vector<std::string>::const_iterator it(stnNames.begin()); it != stnNames.end(); ++it)
	{
		// write STN file
		XmlStnInterface stn(*geoObjects);
		std::string name(*it);
		stn.setNameForExport(name);

		if (stn.writeToFile(path + name + ".stn"))
		{
			// write entry in project file
			QDomElement geoTag = doc.createElement("stn");
			root.appendChild(geoTag);
			QDomElement fileNameTag = doc.createElement("file");
			geoTag.appendChild(fileNameTag);
			QDomText fileNameText =
			        doc.createTextNode(QString::fromStdString(name + ".stn"));
			fileNameTag.appendChild(fileNameText);
		}
		else
			ERR("XmlGspInterface::writeFile(): Error writing stn-file \"%s\".", name.c_str());
	}

	std::string xml = doc.toString().toStdString();
	_out << xml;
	return true;
}
Esempio n. 3
0
int XmlGspInterface::readFile(const QString &fileName)
{
	QFile* file = new QFile(fileName);
	QFileInfo fi(fileName);
	QString path = (fi.path().length() > 3) ? QString(fi.path() + "/") : fi.path();

	QFileInfo si(QString::fromStdString(_schemaName));
	QString schemaPath(si.absolutePath() + "/");

	if (!file->open(QIODevice::ReadOnly | QIODevice::Text))
	{
		std::cout << "XmlGspInterface::readFile() - Can't open xml-file " <<
		fileName.toStdString() << "." << std::endl;
		delete file;
		return 0;
	}
	if (!checkHash(fileName))
	{
		delete file;
		return 0;
	}

	QDomDocument doc("OGS-PROJECT-DOM");
	doc.setContent(file);
	QDomElement docElement = doc.documentElement(); //OpenGeoSysProject
	if (docElement.nodeName().compare("OpenGeoSysProject"))
	{
		std::cout << "XmlGspInterface::readFile() - Unexpected XML root." << std::endl;
		delete file;
		return 0;
	}

	QDomNodeList fileList = docElement.childNodes();

	for(int i = 0; i < fileList.count(); i++)
	{
		const QString file_node(fileList.at(i).nodeName());
		if (file_node.compare("geo") == 0)
		{
			XmlGmlInterface gml(_project, schemaPath.toStdString() + "OpenGeoSysGLI.xsd");
			const QDomNodeList childList = fileList.at(i).childNodes();
			for(int j = 0; j < childList.count(); j++)
			{
				const QDomNode child_node (childList.at(j));
				if (child_node.nodeName().compare("file") == 0)
				{
					std::cout << "path: " << path.toStdString() << "#" << std::endl;
					std::cout << "file name: " << (child_node.toElement().text()).toStdString() << "#" << std::endl;
					gml.readFile(QString(path + child_node.toElement().text()));
				}
			}
		}
		else if (file_node.compare("stn") == 0)
		{
			XmlStnInterface stn(_project, schemaPath.toStdString() + "OpenGeoSysSTN.xsd");
			const QDomNodeList childList = fileList.at(i).childNodes();
			for(int j = 0; j < childList.count(); j++)
				if (childList.at(j).nodeName().compare("file") == 0)
					stn.readFile(QString(path + childList.at(j).toElement().text()));
		}
		else if (file_node.compare("msh") == 0)
		{
			const std::string msh_name = path.toStdString() +
			                       fileList.at(i).toElement().text().toStdString();
			FileIO::MeshIO meshIO;
			MeshLib::Mesh* msh = meshIO.loadMeshFromFile(msh_name);
			_project->addMesh(msh);
		}
	}

	return 1;
}
Esempio n. 4
0
/* Take increments in strain and calculate new Particle: strains, rotation strain,
	stresses, strain energy,
	du 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,int historyOffset) const
{
	// current previous deformation gradient and stretch
	Matrix3 pFnm1 = mptr->GetDeformationGradientMatrix();
	
    // get incremental deformation gradient and decompose it
	const Matrix3 dF = du.Exponential(incrementalDefGradTerms);
    Matrix3 dR;
    Matrix3 dVstretch = dF.LeftDecompose(&dR,NULL);
	
	// decompose to get previous stretch
	Matrix3 Vnm1 = pFnm1.LeftDecompose(NULL,NULL);
	
	// get strain increments de = (dV-I) dR Vnma dRT
	dVstretch(0,0) -= 1.;
	dVstretch(1,1) -= 1.;
	dVstretch(2,2) -= 1.;
	Matrix3 Vrot = Vnm1.RMRT(dR);
	Matrix3 detot = dVstretch*Vrot;
	
	// Update total deformation gradient
	Matrix3 pF = dF*pFnm1;
	mptr->SetDeformationGradientMatrix(pF);
	
    // 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 dTq0 = 0.,dispEnergy = 0.;
	double traceDe = detot.trace();
	double delV = traceDe - 3.*eres;
#ifdef USE_KIRCHOFF_STRESS
	// tracking J
	double detdF = dF.determinant();
	double **h =(double **)(mptr->GetHistoryPtr(0));
	double J = detdF*h[mptrHistory][MGJ_HISTORY];
	h[mptrHistory][MGJ_HISTORY] = J;
	UpdatePressure(mptr,delV,res,eres,detdF,J,delTime,dTq0,dispEnergy);
#else
	UpdatePressure(mptr,delV,res,eres,&dF,delTime,dTq0,dispEnergy);
#endif
	
	// deviatoric strains increment in de
	// Actually de is finding 2*(dev e) to avoid many multiplies by two
	Tensor de;
	double dV = traceDe/3.;
	de.xx = 2.*(detot(0,0) - dV);
	de.yy = 2.*(detot(1,1) - dV);
	de.zz = 2.*(detot(2,2) - dV);
	de.xy = 2.*detot(0,1);
	if(np==THREED_MPM)
	{	de.xz = 2.*detot(0,2);
		de.yz = 2.*detot(1,2);
	}
	
	// Find initial 2*e(t) (deviatoric strain) in ed
	Tensor ed;
	double thirdV = Vrot.trace()/3.;
	ed.xx = 2.*(Vrot(0,0)-thirdV);
	ed.yy = 2.*(Vrot(1,1)-thirdV);
	ed.zz = 2.*(Vrot(2,2)-thirdV);
	ed.xy = 2.*Vrot(0,1);
	if(np==THREED_MPM)
	{	ed.xz = 2.*Vrot(0,2);
		ed.yz = 2.*Vrot(1,2);
	}
	
	// increment particle deviatoric stresses - elastic part
	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;
	}
	
	// get internal variable increments, update them, add to incremental stress, and get dissipated energy6
	Tensor dak;
    double **ak =(double **)(mptr->GetHistoryPtr(0));
	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;
		
		// add to stress increments
		dsig[XX] -= TwoGkred[k]*dak.xx;
		dsig[YY] -= TwoGkred[k]*dak.yy;
		dsig[ZZ] -= TwoGkred[k]*dak.zz;
		dsig[XY] -= TwoGkred[k]*dak.xy;
		
		// dissipation
		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));
		
		// extra terms for 3D
		if(np==THREED_MPM)
		{	// internal variables
			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;
			
			// stresses
			dsig[XZ] -= TwoGkred[k]*dak.xz;
			dsig[YZ] -= TwoGkred[k]*dak.yz;
			
			// dissipation
			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));
		}
	}
	
	// Update particle deviatoric stresses
	Tensor *sp=mptr->GetStressTensor();
	//Tensor st0 = *sp;
	if(np==THREED_MPM)
	{	// incremental rotate of prior stress
		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);

#ifdef USE_KIRCHOFF_STRESS
		// convert sigma(n)/rho(n) to sigma(n)/rho(n+1) and add dsigma/rho(n+1)
		sp->xx = detdF*str(0,0)+J*dsig[XX];
		sp->yy = detdF*str(1,1)+J*dsig[YY];
		sp->xy = detdF*str(0,1)+J*dsig[XY];
		sp->zz = detdF*str(2,2)+J*dsig[ZZ];
		sp->yz = detdF*str(1,2)+J*dsig[YZ];
		sp->xz = detdF*str(0,2)+J*dsig[XZ];
#else
		sp->xx = str(0,0)+dsig[XX];
		sp->yy = str(1,1)+dsig[YY];
		sp->xy = str(0,1)+dsig[XY];
		sp->zz = str(2,2)+dsig[ZZ];
		sp->yz = str(1,2)+dsig[YZ];
		sp->xz = str(0,2)+dsig[XZ];
#endif
	}
	else
	{	// incremental rotate of prior stress
		Matrix3 stn(sp->xx,sp->xy,sp->xy,sp->yy,sp->zz);
		Matrix3 str = stn.RMRT(dR);
		
#ifdef USE_KIRCHOFF_STRESS
		// convert sigma(n)/rho(n) to sigma(n)/rho(n+1) and add dsigma/rho(n+1)
		sp->xx = detdF*str(0,0)+J*dsig[XX];
		sp->yy = detdF*str(1,1)+J*dsig[YY];
		sp->xy = detdF*str(0,1)+J*dsig[XY];
		sp->zz = detdF*sp->zz+J*dsig[ZZ];
#else
		sp->xx = str(0,0)+dsig[XX];
		sp->yy = str(1,1)+dsig[YY];
		sp->xy = str(0,1)+dsig[XY];
		sp->zz += dsig[ZZ];
#endif
	}
	
	// incremental work energy = shear energy (dilation and residual energy done in update pressure)
    double shearEnergy = sp->xx*detot(0,0) + sp->yy*detot(1,1) + sp->zz*detot(2,2) + sp->xy*de.xy;
    if(np==THREED_MPM)
    {   shearEnergy += sp->xz*de.xz + sp->yz*de.yz;
    }
    mptr->AddWorkEnergyAndResidualEnergy(shearEnergy,0.);
	
    // disispated energy per unit mass (dPhi/(rho0 V0)) (nJ/g)
    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,res->dT,dTq0,dispEnergy);
}
Esempio n. 5
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. 6
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);
}
Esempio n. 7
0
// Once stress deformation has been decomposed, finish calculations in the material axis system
// When stress are found, they are rotated back to the global axes (using Rtot and dR)
// Similar, strain increments are rotated back to find work energy (done in global system)
void Elastic::LRElasticConstitutiveLaw(MPMBase *mptr,Matrix3 de,Matrix3 er,Matrix3 Rtot,Matrix3 dR,
									   Matrix3 *Rnmatot,int np,void *properties,ResidualStrains *res) const
{
	// effective strains
	double dvxxeff = de(0,0)-er(0,0);
	double dvyyeff = de(1,1)-er(1,1);
	double dvzzeff = de(2,2)-er(2,2);
	double dgamxy = 2.*de(0,1);
	
    // save initial stresses
	Tensor *sp=mptr->GetStressTensor();
    //Tensor st0=*sp;
	
	// stress increments
	// cast pointer to material-specific data
	ElasticProperties *p = GetElasticPropertiesPointer(properties);
	if(np==THREED_MPM)
	{	double dgamyz = 2.*de(1,2);
		double dgamxz = 2.*de(0,2);
		
		// update sigma = dR signm1 dRT + Rtot dsigma RtotT
		double dsigyz = p->C[3][3]*dgamyz;
		double dsigxz = p->C[4][4]*dgamxz;
		double dsigxy = p->C[5][5]*dgamxy;
		Matrix3 dsig(p->C[0][0]*dvxxeff + p->C[0][1]*dvyyeff + p->C[0][2]*dvzzeff, dsigxy, dsigxz,
					 dsigxy, p->C[1][0]*dvxxeff + p->C[1][1]*dvyyeff + p->C[1][2]*dvzzeff, dsigyz,
					 dsigxz, dsigyz, p->C[2][0]*dvxxeff + p->C[2][1]*dvyyeff + p->C[2][2]*dvzzeff);
		Matrix3 dsigrot = dsig.RMRT(Rtot);
		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);
		sp->xx = str(0,0) + dsigrot(0,0);
		sp->yy = str(1,1) + dsigrot(1,1);
		sp->zz = str(2,2) + dsigrot(2,2);
		sp->xy = str(0,1) + dsigrot(0,1);
		sp->xz = str(0,2) + dsigrot(0,2);
		sp->yz = str(1,2) + dsigrot(1,2);
		
		// stresses are in global coordinates so need to rotate strain and residual
		// strain to get work energy increment per unit mass (dU/(rho0 V0))
		Matrix3 derot = de.RMRT(Rtot);
		Matrix3 errot = er.RMRT(Rtot);
		mptr->AddWorkEnergyAndResidualEnergy(sp->xx*derot(0,0) + sp->yy*derot(1,1) + sp->zz*derot(2,2)
											  + 2.*(sp->yz*derot(1,2) + sp->xz*derot(0,2) + sp->xy*derot(0,1)),
											 sp->xx*errot(0,0) + sp->yy*errot(1,1) + sp->zz*errot(2,2)
											  + 2.*(sp->yz*errot(1,2) + sp->xz*errot(0,2) + sp->xy*errot(0,1)) );
		//mptr->AddWorkEnergyAndResidualEnergy(0.5*((st0.xx+sp->xx)*derot(0,0) + (st0.yy+sp->yy)*derot(1,1)
		//										  + (st0.zz+sp->zz)*derot(2,2)) + (st0.yz+sp->yz)*derot(1,2)
		//										  + (st0.xz+sp->xz)*derot(0,2) + (st0.xy+sp->xy)*derot(0,1),
		//									 0.5*((st0.xx+sp->xx)*errot(0,0) + (st0.yy+sp->yy)*errot(1,1)
		//										  + (st0.zz+sp->zz)*errot(2,2)) + (st0.yz+sp->yz)*errot(1,2)
		//										  + (st0.xz+sp->xz)*errot(0,2) + (st0.xy+sp->xy)*errot(0,1));
	}
	else
	{	// find stress increment
		// this does xx, yy, and xy only. zz done later if needed
		double dsxx,dsyy;
		if(np==AXISYMMETRIC_MPM)
		{	dsxx = p->C[1][1]*dvxxeff + p->C[1][2]*dvyyeff + p->C[4][1]*dvzzeff ;
			dsyy = p->C[1][2]*dvxxeff + p->C[2][2]*dvyyeff + p->C[4][2]*dvzzeff;
		}
		else
		{	dsxx = p->C[1][1]*dvxxeff + p->C[1][2]*dvyyeff;
			dsyy = p->C[1][2]*dvxxeff + p->C[2][2]*dvyyeff;
		}
		double dsxy = p->C[3][3]*dgamxy;
		
		// update sigma = dR signm1 dRT + Rtot dsigma RtotT
		Matrix3 dsig(dsxx,dsxy,dsxy,dsyy,0.);
		Matrix3 dsigrot = dsig.RMRT(Rtot);
		Matrix3 stn(sp->xx,sp->xy,sp->xy,sp->yy,sp->zz);
		Matrix3 str = stn.RMRT(dR);
		sp->xx = str(0,0) + dsigrot(0,0);
		sp->yy = str(1,1) + dsigrot(1,1);
		sp->xy = str(0,1) + dsigrot(0,1);
		
		// stresses are in global coordinate so need to rotate strain and residual
		// strain to get work energy increment per unit mass (dU/(rho0 V0))
		double ezzr = er(2,2);
		Matrix3 derot = de.RMRT(Rtot);
		Matrix3 errot = er.RMRT(Rtot);
		
		// work and residual strain energy increments and sigma or F in z direction
		double workEnergy = sp->xx*derot(0,0) + sp->yy*derot(1,1) + 2.0*sp->xy*derot(0,1);
		double resEnergy = sp->xx*errot(0,0) + sp->yy*errot(1,1) + 2.*sp->xy*errot(0,1);
		//double workEnergy = 0.5*((st0.xx+sp->xx)*derot(0,0) + (st0.yy+sp->yy)*derot(1,1)) + (st0.xy+sp->xy)*derot(0,1);
		//double resEnergy = 0.5*((st0.xx+sp->xx)*errot(0,0) + (st0.yy+sp->yy)*errot(1,1)) + (st0.xy+sp->xy)*errot(0,1);
		if(np==PLANE_STRAIN_MPM)
		{	// need to add back terms to get from reduced cte to actual cte
			sp->zz += p->C[4][1]*(dvxxeff+p->alpha[5]*ezzr) + p->C[4][2]*(dvyyeff+p->alpha[6]*ezzr) - p->C[4][4]*ezzr;
			
			// extra residual energy increment per unit mass (dU/(rho0 V0)) (by midpoint rule) (nJ/g)
			resEnergy += sp->zz*ezzr;
			//resEnergy += 0.5*(st0.zz+sp->zz)*ezzr;
		}
		else if(np==PLANE_STRESS_MPM)
		{	// zz deformation
			mptr->IncrementDeformationGradientZZ(p->C[4][1]*dvxxeff + p->C[4][2]*dvyyeff + ezzr);
		}
		else
		{	// axisymmetric hoop stress
			sp->zz += p->C[4][1]*dvxxeff + p->C[4][2]*dvyyeff + p->C[4][4]*dvzzeff;
			
			// extra work and residual energy increment per unit mass (dU/(rho0 V0)) (by midpoint rule) (nJ/g)
			workEnergy += sp->zz*de(2,2);
			resEnergy += sp->zz*ezzr;
			//workEnergy += 0.5*(st0.zz+sp->zz)*de(2,2);
			//resEnergy += 0.5*(st0.zz+sp->zz)*ezzr;
		}
		mptr->AddWorkEnergyAndResidualEnergy(workEnergy, resEnergy);
		
	}
    
    // track heat energy
    IncrementHeatEnergy(mptr,res->dT,0.,0.);
}