yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #05953
[Branch ~yade-dev/yade/trunk] Rev 2508: Viscoelastic basic particle model: move mass of particles from material to interaction
------------------------------------------------------------
revno: 2508
committer: Sergei D. <sega@think>
branch nick: trunk
timestamp: Fri 2010-10-22 18:30:53 +0400
message:
Viscoelastic basic particle model: move mass of particles from material to interaction
modified:
pkg/dem/Shop.cpp
pkg/dem/Shop.hpp
pkg/dem/ViscoelasticPM.cpp
py/_utils.cpp
--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription
=== modified file 'pkg/dem/Shop.cpp'
--- pkg/dem/Shop.cpp 2010-10-19 14:57:27 +0000
+++ pkg/dem/Shop.cpp 2010-10-22 14:30:53 +0000
@@ -1158,12 +1158,12 @@
return v0+((v2-v0)*(v1-v0).norm()+(v1-v0)*(v2-v0).norm())/((v1-v0).norm()+(v2-v1).norm()+(v0-v2).norm());
}
-void Shop::getViscoelasticFromSpheresInteraction( Real m, Real tc, Real en, Real es, shared_ptr<ViscElMat> b)
+void Shop::getViscoelasticFromSpheresInteraction( Real tc, Real en, Real es, shared_ptr<ViscElMat> b)
{
- b->kn = m/tc/tc * ( Mathr::PI*Mathr::PI + pow(log(en),2) );
- b->cn = -2.0*m/tc * log(en);
- b->ks = 2.0/7.0 * m/tc/tc * ( Mathr::PI*Mathr::PI + pow(log(es),2) );
- b->cs = -2.0/7.0 * m/tc * log(es);
+ b->kn = 1/tc/tc * ( Mathr::PI*Mathr::PI + pow(log(en),2) );
+ b->cn = -2.0 /tc * log(en);
+ b->ks = 2.0/7.0 /tc/tc * ( Mathr::PI*Mathr::PI + pow(log(es),2) );
+ b->cs = -2.0/7.0 /tc * log(es);
if (abs(b->cn) <= Mathr::ZERO_TOLERANCE ) b->cn=0;
if (abs(b->cs) <= Mathr::ZERO_TOLERANCE ) b->cs=0;
=== modified file 'pkg/dem/Shop.hpp'
--- pkg/dem/Shop.hpp 2010-10-13 16:23:08 +0000
+++ pkg/dem/Shop.hpp 2010-10-22 14:30:53 +0000
@@ -94,9 +94,9 @@
static Vector3r inscribedCircleCenter(const Vector3r& v0, const Vector3r& v1, const Vector3r& v2);
/// Get viscoelastic parameters kn,cn,ks,cs from analytical solution of
- /// a problem of interaction of pair spheres with mass m, collision
+ /// a problem of interaction of pair spheres with mass 1, collision
/// time tc and restitution coefficients en,es.
- static void getViscoelasticFromSpheresInteraction(Real m, Real tc, Real en, Real es, shared_ptr<ViscElMat> b);
+ static void getViscoelasticFromSpheresInteraction(Real tc, Real en, Real es, shared_ptr<ViscElMat> b);
//! Get unbalanced force of the whole simulation
static Real unbalancedForce(bool useMaxForce=false, Scene* _rb=NULL);
=== modified file 'pkg/dem/ViscoelasticPM.cpp'
--- pkg/dem/ViscoelasticPM.cpp 2010-10-13 16:23:08 +0000
+++ pkg/dem/ViscoelasticPM.cpp 2010-10-22 14:30:53 +0000
@@ -15,17 +15,22 @@
/* Ip2_ViscElMat_ViscElMat_ViscElPhys */
void Ip2_ViscElMat_ViscElMat_ViscElPhys::go(const shared_ptr<Material>& b1, const shared_ptr<Material>& b2, const shared_ptr<Interaction>& interaction) {
+ // no updates of an existing contact
if(interaction->phys) return;
- ViscElMat* sdec1 = static_cast<ViscElMat*>(b1.get());
- ViscElMat* sdec2 = static_cast<ViscElMat*>(b2.get());
+ ViscElMat* mat1 = static_cast<ViscElMat*>(b1.get());
+ ViscElMat* mat2 = static_cast<ViscElMat*>(b2.get());
+ const Real mass1 = Body::byId(interaction->getId1())->state->mass;
+ const Real mass2 = Body::byId(interaction->getId2())->state->mass;
+ const Real kn1 = mat1->kn*mass1; const Real cn1 = mat1->cn*mass1;
+ const Real ks1 = mat1->ks*mass1; const Real cs1 = mat1->cs*mass1;
+ const Real kn2 = mat2->kn*mass2; const Real cn2 = mat2->cn*mass2;
+ const Real ks2 = mat2->ks*mass2; const Real cs2 = mat2->cs*mass2;
ViscElPhys* phys = new ViscElPhys();
- phys->kn = sdec1->kn * sdec2->kn / (sdec1->kn + sdec2->kn);
- phys->ks = sdec1->ks * sdec2->ks / (sdec1->ks + sdec2->ks);
- phys->cn = ( (sdec1->cn==0) ? 0 : 1/sdec1->cn ) + ( (sdec2->cn==0) ? 0 : 1/sdec2->cn );
- phys->cs = ( (sdec1->cs==0) ? 0 : 1/sdec1->cs ) + ( (sdec2->cs==0) ? 0 : 1/sdec2->cs );
- if (phys->cn) phys->cn = 1/phys->cn;
- if (phys->cs) phys->cs = 1/phys->cs;
- phys->tangensOfFrictionAngle = std::tan(std::min(sdec1->frictionAngle, sdec2->frictionAngle));
+ phys->kn = 1/(kn1?1/kn1:0 + kn2?1/kn2:0);
+ phys->ks = 1/(ks1?1/ks1:0 + ks2?1/ks2:0);
+ phys->cn = cn1?1/cn1:0 + cn2?1/cn2:0; phys->cn = phys->cn?1/phys->cn:0;
+ phys->cs = cs1?1/cs1:0 + cs2?1/cs2:0; phys->cs = phys->cs?1/phys->cs:0;
+ phys->tangensOfFrictionAngle = std::tan(std::min(mat1->frictionAngle, mat2->frictionAngle));
phys->shearForce = Vector3r(0,0,0);
phys->prevNormal = Vector3r(0,0,0);
interaction->phys = shared_ptr<ViscElPhys>(phys);
=== modified file 'py/_utils.cpp'
--- py/_utils.cpp 2010-10-01 22:30:00 +0000
+++ py/_utils.cpp 2010-10-22 14:30:53 +0000
@@ -168,10 +168,10 @@
{
return Shop::inscribedCircleCenter(v0,v1,v2);
}
-py::dict getViscoelasticFromSpheresInteraction(Real m, Real tc, Real en, Real es)
+py::dict getViscoelasticFromSpheresInteraction(Real tc, Real en, Real es)
{
shared_ptr<ViscElMat> b = shared_ptr<ViscElMat>(new ViscElMat());
- Shop::getViscoelasticFromSpheresInteraction(m,tc,en,es,b);
+ Shop::getViscoelasticFromSpheresInteraction(tc,en,es,b);
py::dict d;
d["kn"]=b->kn;
d["cn"]=b->cn;
@@ -465,7 +465,7 @@
py::def("wireNone",wireNone,"Set :yref:`Shape::wire` on all bodies to False, rendering them as solids.");
py::def("wireNoSpheres",wireNoSpheres,"Set :yref:`Shape::wire` to True on non-spherical bodies (:yref:`Facets<Facet>`, :yref:`Walls<Wall>`).");
py::def("flipCell",&Shop::flipCell,(py::arg("flip")=Matrix3r(Matrix3r::Zero())),"Flip periodic cell so that angles between $R^3$ axes and transformed axes are as small as possible. This function relies on the fact that periodic cell defines by repetition or its corners regular grid of points in $R^3$; however, all cells generating identical grid are equivalent and can be flipped one over another. This necessiatates adjustment of :yref:`Interaction.cellDist` for interactions that cross boundary and didn't before (or vice versa), and re-initialization of collider. The *flip* argument can be used to specify desired flip: integers, each column for one axis; if zero matrix, best fit (minimizing the angles) is computed automatically.\n\nIn c++, this function is accessible as ``Shop::flipCell``.\n\n.. warning::\n\t This function is currently broken and should not be used.");
- py::def("getViscoelasticFromSpheresInteraction",getViscoelasticFromSpheresInteraction,(py::arg("m"),py::arg("tc"),py::arg("en"),py::arg("es")),"Get viscoelastic interaction parameters from analytical solution of a pair spheres collision problem. \n\n:Parameters:\n\t`m` : float\n\t\tsphere mass\n\t`tc` : float\n\t\tcollision time\n\t`en` : float\n\t\tnormal restitution coefficient\n\t`es` : float\n\t\ttangential restitution coefficient.\n\n\n:return: \n\tdict with keys:\n\n\tkn : float\n\t\tnormal elastic coefficient computed as:\n\n.. math:: k_n=\\frac{m}{t_c^2}\\left(\\pi^2+(\\ln e_n)^2\\right)\n\n\tcn : float\n\t\tnormal viscous coefficient computed as:\n\n.. math:: c_n=-\\frac{2m}{t_c}\\ln e_n\n\n\n\tkt : float\n\t\ttangential elastic coefficient computed as:\n\n.. math:: k_t=\\frac27\\frac{m}{t_c^2}\\left(\\pi^2+(\\ln e_t)^2\\right)\n\n\tct : float\n\t\ttangential viscous coefficient computed as:\n\n.. math:: c_t=-\\frac27\\frac{m}{t_c}\\ln e_t.\n\n\nFor details see [Pournin2001]_. ");
+ py::def("getViscoelasticFromSpheresInteraction",getViscoelasticFromSpheresInteraction,(py::arg("tc"),py::arg("en"),py::arg("es")),"Get viscoelastic interaction parameters from analytical solution of a pair spheres collision problem. \n\n:Parameters:\n\t`m` : float\n\t\tsphere mass\n\t`tc` : float\n\t\tcollision time\n\t`en` : float\n\t\tnormal restitution coefficient\n\t`es` : float\n\t\ttangential restitution coefficient.\n\n\n:return: \n\tdict with keys:\n\n\tkn : float\n\t\tnormal elastic coefficient computed as:\n\n.. math:: k_n=\\frac{m}{t_c^2}\\left(\\pi^2+(\\ln e_n)^2\\right)\n\n\tcn : float\n\t\tnormal viscous coefficient computed as:\n\n.. math:: c_n=-\\frac{2m}{t_c}\\ln e_n\n\n\n\tkt : float\n\t\ttangential elastic coefficient computed as:\n\n.. math:: k_t=\\frac27\\frac{m}{t_c^2}\\left(\\pi^2+(\\ln e_t)^2\\right)\n\n\tct : float\n\t\ttangential viscous coefficient computed as:\n\n.. math:: c_t=-\\frac27\\frac{m}{t_c}\\ln e_t.\n\n\nFor details see [Pournin2001]_. ");
py::def("stressTensorOfPeriodicCell",Shop__stressTensorOfPeriodicCell,(py::args("smallStrains")=false),"Compute overall (macroscopic) stress of periodic cell using equation published in [Kuhl2001]_:\n\n.. math:: \\vec{\\sigma}=\\frac{1}{V}\\sum_cl^c[\\vec{N}^cf_N^c+\\vec{T}^{cT}\\cdot\\vec{f}^c_T],\n\nwhere $V$ is volume of the cell, $l^c$ length of interaction $c$, $f^c_N$ normal force and $\\vec{f}^c_T$ shear force. Sumed are values over all interactions $c$. $\\vec{N}^c$ and $\\vec{T}^{cT}$ are projection tensors (see the original publication for more details):\n\n.. math:: \\vec{N}=\\vec{n}\\otimes\\vec{n}\\rightarrow N_{ij}=n_in_j\n\n.. math:: \\vec{T}^T=\\vec{I}_{sym}\\cdot\\vec{n}-\\vec{n}\\otimes\\vec{n}\\otimes\\vec{n}\\rightarrow T^T_{ijk}=\\frac{1}{2}(\\delta_{ik}\\delta_{jl}+\\delta_{il}\\delta_{jk})n_l-n_in_jn_k\n\n.. math:: \\vec{T}^T\\cdot\\vec{f}_T\\equiv T^T_{ijk}f_k=(\\delta_{ik}n_j/2+\\delta_{jk}n_i/2-n_in_jn_k)f_k=n_jf_i/2+n_if_j/2-n_in_jn_kf_k,\n\nwhere $n$ is unit vector oriented along the interaction (:yref:`normal<GenericSpheresContact::normal>`) and $\\delta$ is Kronecker's delta. As $\\vec{n}$ and $\\vec{f}_T$ are perpendicular (therfore $n_if_i=0$) we can write\n\n.. math:: \\sigma_{ij}=\\frac{1}{V}\\sum l[n_in_jf_N+n_jf^T_i/2+n_if^T_j/2]\n\n:param bool smallStrains: if false (large strains), real values of volume and interaction lengths are computed. If true, only :yref:`refLength<Dem3DofGeom::refLength>` of interactions and initial volume are computed (can save some time).\n\n:return: macroscopic stress tensor as Matrix3");
py::def("normalShearStressTensors",Shop__normalShearStressTensors,(py::args("compressionPositive")=false),"Compute overall stress tensor of the periodic cell decomposed in 2 parts, one contributed by normal forces, the other by shear forces. The formulation can be found in [Thornton2000]_, eq. (3):\n\n.. math:: \\tens{sigma}_{ij}=\\frac{2}{V}\\sum R N \\vec{n}_i \\vec{n}_j+\\frac{2}{V}\\sum R T \\vec{n}_i\\vec{t}_j\n\nwhere $V$ is the cell volume, $R$ is \"contact radius\" (in our implementation, current distance between particle centroids), $\\vec{n}$ is the normal vector, $\\vec{t}$ is a vector perpendicular to $\\vec{n}$, $N$ and $T$ are norms of normal and shear forces.");
py::def("maxOverlapRatio",maxOverlapRatio,"Return maximum overlap ration in interactions (with :yref:`ScGeom`) of two :yref:`spheres<Sphere>`. The ratio is computed as $\\frac{u_N}{2(r_1 r_2)/r_1+r_2}$, where $u_N$ is the current overlap distance and $r_1$, $r_2$ are radii of the two spheres in contact.");