void Law2_ScGeom_ElectrostaticPhys::getTotalStresses(Matrix3r& DLStresses) { vector<Matrix3r> NDs; getStressForEachBody(NDs); DLStresses = Matrix3r::Zero(); const shared_ptr<Scene>& scene=Omega::instance().getScene(); if(!scene->isPeriodic) { LOG_ERROR("This method can only be used in periodic simulations"); return; } for(unsigned int i(0);i<NDs.size();i++) { Sphere * s = YADE_CAST<Sphere*>(Body::byId(i,scene)->shape.get()); if(s) { Real vol = 4./3.*M_PI*pow(s->radius,3); DLStresses += NDs[i]*vol; } } DLStresses /= scene->cell->getVolume(); }
py::tuple Law2_ScGeom_ElectrostaticPhys::PyGetStressForEachBody() { py::list nc, sc, nl, sl, nd; vector<Matrix3r> NCs, SCs, NLs, SLs, NDs; Law2_ScGeom_ImplicitLubricationPhys::getStressForEachBody(NCs, SCs, NLs, SLs); getStressForEachBody(NDs); FOREACH(const Matrix3r& m, NCs) nc.append(m); FOREACH(const Matrix3r& m, SCs) sc.append(m); FOREACH(const Matrix3r& m, NLs) nl.append(m); FOREACH(const Matrix3r& m, SLs) sl.append(m); FOREACH(const Matrix3r& m, NDs) nd.append(m); return py::make_tuple(nc, sc, nl, sl, nd); }
void PolyhedraSplitter::action() { const shared_ptr<Scene> _rb=shared_ptr<Scene>(); shared_ptr<Scene> rb=(_rb?_rb:Omega::instance().getScene()); vector<PSplitT> splitsV; vector<Matrix3r> bStresses (scene->bodies->size(), Matrix3r::Zero()); getStressForEachBody(bStresses); FOREACH(const shared_ptr<Body>& b, *rb->bodies){ if(!b || !b->material || !b->shape) continue; shared_ptr<Polyhedra> p=YADE_PTR_DYN_CAST<Polyhedra>(b->shape); shared_ptr<PolyhedraMat> m=YADE_PTR_DYN_CAST<PolyhedraMat>(b->material); if(p && m->IsSplitable){ //not real strees, to get real one, it has to be divided by body volume Matrix3r stress = bStresses[b->id]; //get eigenstresses Symmetrize(stress); Matrix3r I_vect(Matrix3r::Zero()), I_valu(Matrix3r::Zero()); matrixEigenDecomposition(stress,I_vect,I_valu); Eigen::Matrix3f::Index min_i, max_i; I_valu.diagonal().minCoeff(&min_i); I_valu.diagonal().maxCoeff(&max_i); //division of stress by volume const Vector3r dirC = I_vect.col(max_i); const Vector3r dirT = I_vect.col(min_i); const Vector3r dir1 = dirC.normalized() + dirT.normalized(); const Vector3r dir2 = dirC.normalized() - dirT.normalized(); //double sigma_t = -comp_stress/2.+ tens_stress; const Real sigma_t = pow(( pow(I_valu(0,0)-I_valu(1,1),2)+ pow(I_valu(0,0)-I_valu(2,2),2)+ pow(I_valu(1,1)-I_valu(2,2),2)) /2.,0.5)/p->GetVolume(); if (sigma_t > getStrength(p->GetVolume(),m->GetStrength())) { splitsV.push_back(std::make_tuple(b, dir1.normalized(), dir2.normalized())); } } } std::for_each(splitsV.begin(), splitsV.end(), &SplitPolyhedraDouble); }