void Ip2_FrictViscoMat_FrictViscoMat_FrictViscoPhys::go(const shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const shared_ptr<Interaction>& interaction){ LOG_TRACE( "Ip2_FrictViscoMat_FrictViscoMat_FrictViscoPhys::go - contact law" ); if(interaction->phys) return; const shared_ptr<FrictViscoMat>& mat1 = YADE_PTR_CAST<FrictViscoMat>(b1); const shared_ptr<FrictViscoMat>& mat2 = YADE_PTR_CAST<FrictViscoMat>(b2); interaction->phys = shared_ptr<FrictViscoPhys>(new FrictViscoPhys()); const shared_ptr<FrictViscoPhys>& contactPhysics = YADE_PTR_CAST<FrictViscoPhys>(interaction->phys); Real Ea = mat1->young; Real Eb = mat2->young; Real Va = mat1->poisson; Real Vb = mat2->poisson; Real Ra,Rb; assert(dynamic_cast<GenericSpheresContact*>(interaction->geom.get()));//only in debug mode GenericSpheresContact* sphCont=YADE_CAST<GenericSpheresContact*>(interaction->geom.get()); Ra=sphCont->refR1>0?sphCont->refR1:sphCont->refR2; Rb=sphCont->refR2>0?sphCont->refR2:sphCont->refR1; // calculate stiffness from MatchMaker or use harmonic avarage as usual if not given Real Kn = (kn) ? (*kn)(mat1->id,mat2->id) : 2.*Ea*Ra*Eb*Rb/(Ea*Ra+Eb*Rb); Real Ks = (kRatio) ? (*kRatio)(mat1->id,mat2->id)*Kn : 2.*Ea*Ra*Va*Eb*Rb*Vb/(Ea*Ra*Va+Eb*Rb*Vb); Real frictionAngle = (!frictAngle) ? std::min(mat1->frictionAngle,mat2->frictionAngle) : (*frictAngle)(mat1->id,mat2->id,mat1->frictionAngle,mat2->frictionAngle); contactPhysics->tangensOfFrictionAngle = std::tan(frictionAngle); contactPhysics->kn = Kn; contactPhysics->ks = Ks; /************************/ /* DAMPING COEFFICIENTS */ /************************/ Real betana = mat1->betan; Real betanb = mat2->betan; // inclusion of local viscous damping if (betana!=0 || betanb!=0){ Body::id_t ida = interaction->getId1(); // get id body 1 Body::id_t idb = interaction->getId2(); // get id body 2 State* dea = Body::byId(ida,scene)->state.get(); State* deb = Body::byId(idb,scene)->state.get(); const shared_ptr<Body>& ba=Body::byId(ida,scene); const shared_ptr<Body>& bb=Body::byId(idb,scene); Real mbar = (!ba->isDynamic() && bb->isDynamic()) ? deb->mass : ((!bb->isDynamic() && ba->isDynamic()) ? dea->mass : (dea->mass*deb->mass / (dea->mass + deb->mass))); // get equivalent mass if both bodies are dynamic, if not set it equal to the one of the dynamic body TRVAR2(Kn,mbar); contactPhysics->cn_crit = 2.*sqrt(mbar*Kn); // Critical damping coefficient (normal direction) contactPhysics->cn = contactPhysics->cn_crit * ( (betana!=0 && betanb!=0) ? ((betana+betanb)/2.) : ( (betanb==0) ? betana : betanb )); // Damping normal coefficient } else contactPhysics->cn=0.; TRVAR1(contactPhysics->cn); }
void TriaxialStressController::controlExternalStress(int wall, Vector3r resultantForce, State* p, Real wall_max_vel) { scene->forces.sync(); Real translation=normal[wall].dot(getForce(scene,wall_id[wall])-resultantForce); const bool log=false; if(log) LOG_DEBUG("wall="<<wall<<" actualForce="<<getForce(scene,wall_id[wall])<<", resultantForce="<<resultantForce<<", translation="<<translation); if (translation!=0) { if (stiffness[wall]!=0) { translation /= stiffness[wall]; if(log) TRVAR2(translation,wall_max_vel*scene->dt) translation = std::min( std::abs(translation), wall_max_vel*scene->dt ) * Mathr::Sign(translation); } else translation = wall_max_vel * Mathr::Sign(translation)*scene->dt; } previousTranslation[wall] = (1-stressDamping)*translation*normal[wall] + 0.8*previousTranslation[wall];// formula for "steady-flow" evolution with fluctuations //Don't update position since Newton is doing that starting from bzr2612 //p->se3.position += previousTranslation[wall]; externalWork += previousTranslation[wall].dot(getForce(scene,wall_id[wall])); //this is important is using VelocityBins. Otherwise the motion is never detected. Related to https://bugs.launchpad.net/yade/+bug/398089 p->vel=previousTranslation[wall]/scene->dt; //if(log)TRVAR2(previousTranslation,p->se3.position); }