← Back to team overview

yade-dev team mailing list archive

[svn] r1730 - trunk/extra

 

Author: eudoxos
Date: 2009-03-25 22:30:06 +0100 (Wed, 25 Mar 2009)
New Revision: 1730

Modified:
   trunk/extra/Brefcom.cpp
   trunk/extra/Brefcom.hpp
Log:
1. Add rate-dependent damage to normal and viscoplasticity to shear components of Brefcom (not yet tested, just compiles); other cleanups there.


Modified: trunk/extra/Brefcom.cpp
===================================================================
--- trunk/extra/Brefcom.cpp	2009-03-24 21:02:59 UTC (rev 1729)
+++ trunk/extra/Brefcom.cpp	2009-03-25 21:30:06 UTC (rev 1730)
@@ -110,8 +110,10 @@
 		if(neverDamage) contPhys->neverDamage=true;
 		if(cohesiveThresholdIter<0 || Omega::instance().getCurrentIteration()<cohesiveThresholdIter) contPhys->isCohesive=true;
 		else contPhys->isCohesive=false;
-		contPhys->tau=tau;
-		contPhys->expDmgRate=expDmgRate;
+		contPhys->dmgTau=dmgTau;
+		contPhys->dmgRateExp=plRateExp;
+		contPhys->plTau=plTau;
+		contPhys->plRateExp=plRateExp;
 
 		interaction->interactionPhysics=contPhys;
 	}
@@ -143,6 +145,40 @@
 
 CREATE_LOGGER(ef2_Spheres_Brefcom_BrefcomLaw);
 
+Real BrefcomContact::solveBeta(const Real c, const Real N){
+	const int maxIter=20;
+	const Real maxError=1e-12;
+	Real f, ret=0.;
+	for(int i=0; i<maxIter; i++){
+		Real aux=c*exp(N*ret)+exp(ret);
+		f=log(aux);
+		if(fabs(f)<maxError) return ret;
+		Real df=(c*N*exp(N*ret)+exp(ret))/aux;
+		ret-=f/df;
+	}
+	LOG_FATAL("No convergence, c="<<c<<", ret="<<ret<<", f="<<f);
+	throw runtime_error("ef2_Spheres_Brefcom_BrefcomLaw::solveBeta failed to converge.");
+}
+
+Real BrefcomContact::computeDmgOverstress(Real epsN, Real dt){
+	if(kappaD>=epsN*omega){ // unloading, no viscous stress
+		kappaD=epsN*omega;
+		return 0.0;
+	}
+	Real c=epsCrackOnset*(1-omega)*pow(dmgTau/dt,dmgRateExp)*pow(epsN*omega-kappaD,dmgRateExp-1.);
+	Real beta=solveBeta(c,dmgRateExp);
+	Real deltaDmgStrain=(epsN*omega-kappaD)*exp(beta);
+	kappaD+=deltaDmgStrain;
+	return (epsN*omega-kappaD)*E;
+}
+
+Real BrefcomContact::computeViscoplScalingFactor(Real sigmaTNorm, Real sigmaTYield,Real dt){
+	if(sigmaTNorm<sigmaTYield) return 1.;
+	Real c=/* should this be sigmaT0?? */ sigmaTNorm*pow(plTau/(G*dt),plRateExp)*pow(sigmaTNorm-sigmaTYield,plRateExp-1.);
+	Real beta=solveBeta(c,plRateExp);
+	return 1.-exp(beta)*(1-sigmaTYield/sigmaTNorm);
+}
+
 void ef2_Spheres_Brefcom_BrefcomLaw::go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, MetaBody* rootBody){
 	//timingDeltas->start();
 	SpheresContactGeometry* contGeom=static_cast<SpheresContactGeometry*>(_geom.get());
@@ -155,7 +191,7 @@
 	if(BC->omega>=1.0 && BC->omegaThreshold>=1.0) return;
 
 	// shorthands
-	Real& epsN(BC->epsN); Vector3r& epsT(BC->epsT); Real& kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); const Real& E(BC->E); const Real& undamagedCohesion(BC->undamagedCohesion); const Real& tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& crossSection(BC->crossSection); const Real& tau(BC->tau); const Real& expDmgRate(BC->expDmgRate); const Real& omegaThreshold(BC->omegaThreshold); const Real& epsCrackOnset(BC->epsCrackOnset); Real& relResidualStrength(BC->relResidualStrength); const Real& dt=Omega::instance().getTimeStep();  const Real& epsFracture(BC->epsFracture); const bool& neverDamage(BC->neverDamage);
+	Real& epsN(BC->epsN); Vector3r& epsT(BC->epsT); Real& kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); const Real& E(BC->E); const Real& undamagedCohesion(BC->undamagedCohesion); const Real& tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& crossSection(BC->crossSection); const Real& omegaThreshold(BC->omegaThreshold); const Real& epsCrackOnset(BC->epsCrackOnset); Real& relResidualStrength(BC->relResidualStrength); const Real& dt=Omega::instance().getTimeStep();  const Real& epsFracture(BC->epsFracture); const bool& neverDamage(BC->neverDamage); const Real& dmgTau(BC->dmgTau); const Real& plTau(BC->plTau);
 	/* const Real& transStrainCoeff(BC->transStrainCoeff); const Real& epsTrans(BC->epsTrans); const Real& xiShear(BC->xiShear); */
 	Real& omega(BC->omega); Real& sigmaN(BC->sigmaN);  Vector3r& sigmaT(BC->sigmaT); Real& Fn(BC->Fn); Vector3r& Fs(BC->Fs); // for python access
 
@@ -198,71 +234,11 @@
 
 void BrefcomLaw::action(MetaBody* _rootBody){
 	rootBody=_rootBody;
-	if(useFunctor){ // testing the functor
-		if(!functor) functor=shared_ptr<ef2_Spheres_Brefcom_BrefcomLaw>(new ef2_Spheres_Brefcom_BrefcomLaw);
-		functor->logStrain=logStrain;
-		FOREACH(const shared_ptr<Interaction>& I, *rootBody->interactions){
-			if(!I->isReal) continue;
-			functor->go(I->interactionGeometry, I->interactionPhysics, I.get(), rootBody);
-		}
-		return;
-	}
-	
+	if(!functor) functor=shared_ptr<ef2_Spheres_Brefcom_BrefcomLaw>(new ef2_Spheres_Brefcom_BrefcomLaw);
+	functor->logStrain=logStrain;
 	FOREACH(const shared_ptr<Interaction>& I, *rootBody->interactions){
 		if(!I->isReal) continue;
-		BC=YADE_PTR_CAST<BrefcomContact>(I->interactionPhysics);
-		contGeom=YADE_PTR_CAST<SpheresContactGeometry>(I->interactionGeometry);
-		assert(BC); assert(contGeom);
-		/* kept fully damaged contacts; note that normally the contact is deleted _after_ the BREFCOM_MATERIAL_MODEL,
-		 * i.e. if it is 1.0 here, omegaThreshold is >= 1.0 for sure.
-		 * &&'ing that just to make sure anyway ...
-		 */
-		if(BC->omega>=1.0 && BC->omegaThreshold>=1.0) continue;
-
-		// shorthands
-		Real& epsN(BC->epsN); Vector3r& epsT(BC->epsT); Real& kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); /* const Real& xiShear(BC->xiShear);*/ const Real& E(BC->E); const Real& undamagedCohesion(BC->undamagedCohesion); const Real& tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& crossSection(BC->crossSection); const Real& tau(BC->tau); const Real& expDmgRate(BC->expDmgRate); const Real& omegaThreshold(BC->omegaThreshold); /* const Real& transStrainCoeff(BC->transStrainCoeff); const Real& epsTrans(BC->epsTrans); */ const Real& epsCrackOnset(BC->epsCrackOnset); Real& relResidualStrength(BC->relResidualStrength); const Real& epsFracture(BC->epsFracture); const bool& neverDamage(BC->neverDamage);
-		// for python access
-		Real& omega(BC->omega); Real& sigmaN(BC->sigmaN);  Vector3r& sigmaT(BC->sigmaT); Real& Fn(BC->Fn); Vector3r& Fs(BC->Fs);
-		// for rate-dependence
-		const Real& dt=Omega::instance().getTimeStep();
-
-		assert(contGeom->hasShear);
-
-		epsN=contGeom->epsN();
-		epsT=contGeom->epsT();
-
-		contGeom->relocateContactPoints(); // allow very large mutual rotations
-
-		if(logStrain && epsN<0){
-			Real epsN0=epsN;
-			epsN=log(epsN0+1);
-			epsT*=epsN/epsN0;
-		}
-
-		#ifdef BREFCOM_MATERIAL_MODEL
-			BREFCOM_MATERIAL_MODEL
-		#else
-			sigmaN=E*epsN;
-			sigmaT=G*epsT;
-		#endif
-
-		if(omega>omegaThreshold){
-			I->isReal=false;
-			const shared_ptr<Body>& body1=Body::byId(I->getId1(),_rootBody), body2=Body::byId(I->getId2(),_rootBody); assert(body1); assert(body2);
-			const shared_ptr<BrefcomPhysParams>& rbp1=YADE_PTR_CAST<BrefcomPhysParams>(body1->physicalParameters), rbp2=YADE_PTR_CAST<BrefcomPhysParams>(body2->physicalParameters);
-			if(BC->isCohesive){rbp1->numBrokenCohesive+=1; rbp2->numBrokenCohesive+=1; rbp1->epsPlBroken+=epsPlSum; rbp2->epsPlBroken+=epsPlSum;}
-			LOG_DEBUG("Contact #"<<I->getId1()<<"=#"<<I->getId2()<<" is damaged over thershold ("<<omega<<">"<<omegaThreshold<<") and has been deleted (isReal="<<I->isReal<<")");
-			continue;
-		}
-
-		#define NNAN(a) assert(!isnan(a));
-		#define NNANV(v) assert(!isnan(v[0])); assert(!isnan(v[1])); assert(!isnan(v[2]));
-		// store Fn (and Fs?), for use with GlobalStiffnessCounter?
-		NNAN(sigmaN); NNANV(sigmaT);
-		NNAN(crossSection);
-		Fn=sigmaN*crossSection; BC->normalForce=Fn*contGeom->normal;
-		Fs=sigmaT*crossSection; BC->shearForce=Fs;
-		applyForce(crossSection*(contGeom->normal*sigmaN + sigmaT),I->getId1(),I->getId2()); /* this is the force applied on the _first_ body; inverted applied to the second */
+		functor->go(I->interactionGeometry, I->interactionPhysics, I.get(), rootBody);
 	}
 }
 

Modified: trunk/extra/Brefcom.hpp
===================================================================
--- trunk/extra/Brefcom.hpp	2009-03-24 21:02:59 UTC (rev 1729)
+++ trunk/extra/Brefcom.hpp	2009-03-25 21:30:06 UTC (rev 1730)
@@ -70,10 +70,14 @@
 			omegaThreshold,
 			//! weight coefficient for shear strain when computing the strain semi-norm kappaD
 			xiShear,
-			//! characteristic time (if non-positive, the law without rate-dependence is used)
-			tau,
+			//! characteristic time for damage (if non-positive, the law without rate-dependence is used)
+			dmgTau,
 			//! exponent in the rate-dependent damage evolution
-			expDmgRate,
+			dmgRateExp,
+			//! characteristic time for viscoplasticity (if non-positive, no rate-dependence for shear)
+			plTau,
+			//! exponent in the rate-dependent viscoplasticity
+			plRateExp,
 			//! coefficient that takes transversal strain into accound when calculating kappaDReduced
 			transStrainCoeff;
 		/*! Up to now maximum normal strain (semi-norm), non-decreasing in time. */
@@ -91,7 +95,14 @@
 		// FIXME: Fn and Fs are stored as Vector3r normalForce, shearForce in NormalShearInteraction 
 		Real omega, Fn, sigmaN, epsN, relResidualStrength; Vector3r epsT, sigmaT, Fs;
 
-		BrefcomContact(): NormalShearInteraction(),E(0), G(0), tanFrictionAngle(0), undamagedCohesion(0), crossSection(0), xiShear(0), tau(0), expDmgRate(0), epsPlSum(0.) { createIndex(); epsT=Vector3r::ZERO; kappaD=0; isCohesive=false; neverDamage=false; omega=0; Fn=0; Fs=Vector3r::ZERO; epsPlSum=0; }
+
+		static Real solveBeta(const Real c, const Real N);
+		Real computeDmgOverstress(Real epsN,Real dt);
+		Real computeViscoplScalingFactor(Real sigmaTNorm, Real sigmaTYield,Real dt);
+
+
+
+		BrefcomContact(): NormalShearInteraction(),E(0), G(0), tanFrictionAngle(0), undamagedCohesion(0), crossSection(0), xiShear(0), dmgTau(-1), dmgRateExp(0), plTau(-1), plRateExp(0), epsPlSum(0.) { createIndex(); epsT=Vector3r::ZERO; kappaD=0; isCohesive=false; neverDamage=false; omega=0; Fn=0; Fs=Vector3r::ZERO; epsPlSum=0; }
 		//	BrefcomContact(Real _E, Real _G, Real _tanFrictionAngle, Real _undamagedCohesion, Real _equilibriumDist, Real _crossSection, Real _epsCrackOnset, Real _epsFracture, Real _expBending, Real _xiShear, Real _tau=0, Real _expDmgRate=1): InteractionPhysics(), E(_E), G(_G), tanFrictionAngle(_tanFrictionAngle), undamagedCohesion(_undamagedCohesion), equilibriumDist(_equilibriumDist), crossSection(_crossSection), epsCrackOnset(_epsCrackOnset), epsFracture(_epsFracture), expBending(_expBending), xiShear(_xiShear), tau(_tau), expDmgRate(_expDmgRate) { epsT=Vector3r::ZERO; kappaD=0; isCohesive=false; neverDamage=false; omega=0; Fn=0; Fs=Vector3r::ZERO; /*TRVAR5(epsCrackOnset,epsFracture,Kn,crossSection,equilibriumDist); */ }
 		virtual ~BrefcomContact();
 
@@ -105,8 +116,10 @@
 			(epsFracture)
 			(omegaThreshold)
 			(xiShear)
-			(tau)
-			(expDmgRate)
+			(dmgTau)
+			(dmgRateExp)
+			(plTau)
+			(plRateExp)
 			(transStrainCoeff)
 
 			(kappaD)
@@ -153,14 +166,14 @@
 REGISTER_SERIALIZABLE(BrefcomPhysParams);
 
 class ef2_Spheres_Brefcom_BrefcomLaw: public ConstitutiveLaw{
+	public:
 	/*! Cohesion evolution law (it is 1-funcH here) */
 	Real funcH(const Real& kappaD, const Real& epsCrackOnset, const Real& epsFracture, const bool& neverDamage) const{ return 1-funcG(kappaD,epsCrackOnset,epsFracture,neverDamage); }
 	/*! Damage evolution law */
-	inline Real funcG(const Real& kappaD, const Real& epsCrackOnset, const Real& epsFracture, const bool& neverDamage) const{
+	static Real funcG(const Real& kappaD, const Real& epsCrackOnset, const Real& epsFracture, const bool& neverDamage) {
 		if(kappaD<epsCrackOnset || neverDamage) return 0;
 		return 1.-(epsCrackOnset/kappaD)*exp(-(kappaD-epsCrackOnset)/epsFracture);
 	}
-	public:
 		bool logStrain;
 		ef2_Spheres_Brefcom_BrefcomLaw(): logStrain(false){ /*timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);*/ }
 		void go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, MetaBody* rootBody);
@@ -183,20 +196,16 @@
 		/*! Cohesion evolution law (it is 1-funcH here) */
 		Real funcH(const Real& kappaD, const Real& epsCrackOnset, const Real& epsFracture, const bool& neverDamage) const{ return 1-funcG(kappaD,epsCrackOnset,epsFracture,neverDamage); }
 		/*! Damage evolution law */
-		inline Real funcG(const Real& kappaD, const Real& epsCrackOnset, const Real& epsFracture, const bool& neverDamage) const{
-			if(kappaD<epsCrackOnset || neverDamage) return 0;
-			return 1.-(epsCrackOnset/kappaD)*exp(-(kappaD-epsCrackOnset)/epsFracture);
-		}
+		Real funcG(const Real& kappaD, const Real& epsCrackOnset, const Real& epsFracture, const bool& neverDamage) const{ return ef2_Spheres_Brefcom_BrefcomLaw::funcG(kappaD,epsCrackOnset,epsFracture,neverDamage); }
 		
 	public:
 		bool logStrain;
-		bool useFunctor;
-		BrefcomLaw(): logStrain(false),useFunctor(false) { Shop::Bex::initCache(); };
+		BrefcomLaw(): logStrain(false) { Shop::Bex::initCache(); };
 		void action(MetaBody*);
 	protected: 
 	NEEDS_BEX("Force","Momentum");
 	REGISTER_CLASS_AND_BASE(BrefcomLaw,InteractionSolver);
-	REGISTER_ATTRIBUTES(InteractionSolver,(logStrain)(useFunctor));
+	REGISTER_ATTRIBUTES(InteractionSolver,(logStrain));
 	DECLARE_LOGGER;
 };
 REGISTER_SERIALIZABLE(BrefcomLaw);
@@ -216,7 +225,7 @@
 		expBending is positive if the damage evolution function is concave after fracture onset;
 		reasonable value seems like 4.
 		*/
-		Real sigmaT, expBending, xiShear, epsCrackOnset, relDuctility, G_over_E, tau, expDmgRate, omegaThreshold, transStrainCoeff;
+		Real sigmaT, expBending, xiShear, epsCrackOnset, relDuctility, G_over_E, tau, expDmgRate, omegaThreshold, transStrainCoeff, dmgTau, dmgRateExp, plTau, plRateExp;
 		//! Should new contacts be cohesive? They will before this iter#, they will not be afterwards. If 0, they will never be. If negative, they will always be created as cohesive.
 		long cohesiveThresholdIter;
 		//! Create contacts that don't receive any damage (BrefcomContact::neverDamage=true); defaults to false
@@ -228,8 +237,8 @@
 			xiShear=0;
 			neverDamage=false;
 			cohesiveThresholdIter=-1;
-			tau=-1; expDmgRate=0;
-			omegaThreshold=0.98;
+			dmgTau=-1; dmgRateExp=0; plTau=-1; plRateExp=-1;
+			omegaThreshold=0.999;
 		}
 
 		virtual void go(const shared_ptr<PhysicalParameters>& pp1, const shared_ptr<PhysicalParameters>& pp2, const shared_ptr<Interaction>& interaction);
@@ -242,8 +251,10 @@
 			(neverDamage)
 			(epsCrackOnset)
 			(relDuctility)
-			(tau)
-			(expDmgRate)
+			(dmgTau)
+			(dmgRateExp)
+			(plTau)
+			(plRateExp)
 			(omegaThreshold)
 			(transStrainCoeff)
 		);