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)
                );


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp
_______________________________________________
yade-dev mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/yade-dev

Reply via email to