yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #07398
[Branch ~yade-dev/yade/trunk] Rev 2801: -Update clumps forces and torques in Newton, as in https://blueprints.launchpad.net/yade/+spec/cl...
------------------------------------------------------------
revno: 2801
committer: Bruno Chareyre <bruno.chareyre@xxxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2011-04-03 18:49:58 +0200
message:
-Update clumps forces and torques in Newton, as in https://blueprints.launchpad.net/yade/+spec/clump-forces.
-Update Shop::unbalancedForce accordingly
-Remove the old unbalancedForce code from TSController and make it point to the Shop version.
modified:
core/ForceContainer.hpp
pkg/dem/NewtonIntegrator.cpp
pkg/dem/Shop.cpp
pkg/dem/TriaxialStressController.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 'core/ForceContainer.hpp'
--- core/ForceContainer.hpp 2011-03-17 13:47:46 +0000
+++ core/ForceContainer.hpp 2011-04-03 16:49:58 +0000
@@ -66,13 +66,7 @@
inline void ensureSynced(){ if(!synced) throw runtime_error("ForceContainer not thread-synchronized; call sync() first!"); }
- #if 0
- /*! Function to allow friend classes to get force even if not synced.
- * Dangerous! The caller must know what it is doing! (i.e. don't read after write
- * for a particular body id. */
- const Vector3r& getForceUnsynced (Body::id_t id){ensureSize(id); return _force[id];}
- const Vector3r& getTorqueUnsynced(Body::id_t id){ensureSize(id); return _force[id];}
- #endif
+
// dummy function to avoid template resolution failure
friend class boost::serialization::access; template<class ArchiveT> void serialize(ArchiveT & ar, unsigned int version){}
public:
@@ -84,7 +78,6 @@
sizeOfThreads.push_back(0);
}
}
-
const Vector3r& getForce(Body::id_t id) { ensureSynced(); return ((size_t)id<size)?_force[id]:_zero; }
void addForce(Body::id_t id, const Vector3r& f){ ensureSize(id,omp_get_thread_num()); synced=false; _forceData[omp_get_thread_num()][id]+=f;}
const Vector3r& getTorque(Body::id_t id) { ensureSynced(); return ((size_t)id<size)?_torque[id]:_zero; }
@@ -93,6 +86,13 @@
void addMove(Body::id_t id, const Vector3r& m) { ensureSize(id,omp_get_thread_num()); synced=false; moveRotUsed=true; _moveData[omp_get_thread_num()][id]+=m;}
const Vector3r& getRot(Body::id_t id) { ensureSynced(); return ((size_t)id<size)?_rot[id]:_zero; }
void addRot(Body::id_t id, const Vector3r& r) { ensureSize(id,omp_get_thread_num()); synced=false; moveRotUsed=true; _rotData[omp_get_thread_num()][id]+=r;}
+
+ /*! Function to allow friend classes to get force even if not synced. Used for clumps by NewtonIntegrator.
+ * Dangerous! The caller must know what it is doing! (i.e. don't read after write
+ * for a particular body id. */
+ Vector3r& getForceUnsynced (Body::id_t id){return ((size_t)id<size)?_force[id]:_zero;}
+ Vector3r& getTorqueUnsynced(Body::id_t id){return ((size_t)id<size)?_torque[id]:_zero;}
+
/* To be benchmarked: sum thread data in getForce/getTorque upon request for each body individually instead of by the sync() function globally */
// this function is used from python so that running simulation is not slowed down by sync'ing on occasions
// since Vector3r writes are not atomic, it might (rarely) return wrong value, if the computation is running meanwhile
=== modified file 'pkg/dem/NewtonIntegrator.cpp'
--- pkg/dem/NewtonIntegrator.cpp 2011-01-29 22:47:18 +0000
+++ pkg/dem/NewtonIntegrator.cpp 2011-04-03 16:49:58 +0000
@@ -107,7 +107,21 @@
if(unlikely(!b || b->isClumpMember())) continue;
State* state=b->state.get(); const Body::id_t& id=b->getId();
- Vector3r f=scene->forces.getForce(id), m=scene->forces.getTorque(id);
+ Vector3r f=Vector3r::Zero(), m=Vector3r::Zero();
+ // clumps forces
+ if(b->isClump()) {
+ b->shape->cast<Clump>().addForceTorqueFromMembers(state,scene,f,m);
+ #ifdef YADE_OPENMP
+ //it is safe here, since onky one thread will read/write
+ scene->forces.getTorqueUnsynced(id)+=m;
+ scene->forces.getForceUnsynced(id)+=f;
+ #else
+ scene->forces.addTorque(id,m);
+ scene->forces.addForce(id, f);
+ #endif
+ }
+ //in most cases, the initial force on clumps will zero and next line is not changing f and m, but make sure we don't miss something (e.g. user defined forces on clumps)
+ f=scene->forces.getForce(id); m=scene->forces.getTorque(id);
#ifdef YADE_DEBUG
if(isnan(f[0])||isnan(f[1])||isnan(f[2])) throw runtime_error(("NewtonIntegrator: NaN force acting on #"+lexical_cast<string>(id)+".").c_str());
if(isnan(m[0])||isnan(m[1])||isnan(m[2])) throw runtime_error(("NewtonIntegrator: NaN torque acting on #"+lexical_cast<string>(id)+".").c_str());
@@ -119,6 +133,8 @@
// in aperiodic boundaries, it is equal to absolute velocity
Vector3r fluctVel=isPeriodic?scene->cell->bodyFluctuationVel(b->state->pos,b->state->vel):state->vel;
+
+
// numerical damping & kinetic energy
if(unlikely(trackEnergy)) updateEnergy(b,state,fluctVel,f,m);
@@ -127,8 +143,6 @@
// for particles not totally blocked, compute accelerations; otherwise, the computations would be useless
if (state->blockedDOFs!=State::DOF_ALL) {
- // forces
- if(b->isClump()) b->shape->cast<Clump>().addForceTorqueFromMembers(state,scene,f,m);
// linear acceleration
Vector3r linAccel=computeAccel(f,state->mass,state->blockedDOFs);
cundallDamp2nd(dt,f,fluctVel,linAccel);
=== modified file 'pkg/dem/Shop.cpp'
--- pkg/dem/Shop.cpp 2011-03-16 21:02:40 +0000
+++ pkg/dem/Shop.cpp 2011-04-03 16:49:58 +0000
@@ -162,8 +162,8 @@
Real sumF=0,maxF=0,currF; int nb=0;
FOREACH(const shared_ptr<Body>& b, *rb->bodies){
if(!b || b->isClumpMember() || !b->isDynamic()) continue;
- if(!b->isClump()){ currF=rb->forces.getForce(b->id).norm(); }
- else { // for clump, sum forces from members on the clump itself
+ currF=rb->forces.getForce(b->id).norm();
+ if(b->isClump() && currF==0){ // this should not happen unless the function is called by an engine whose position in the loop is before Newton (with the exception of bodies which really have null force), because clumps forces are updated in Newton. Typical triaxial loops are using such ordering unfortunately (triaxEngine before Newton). So, here we make sure that they will get correct unbalance. In the future, it is better for optimality to check unbalancedF inside scripts at the end of loops, so that this "if" is never active.
Vector3r f(rb->forces.getForce(b->id)),m(Vector3r::Zero());
b->shape->cast<Clump>().addForceTorqueFromMembers(b->state.get(),rb,f,m);
currF=f.norm();
=== modified file 'pkg/dem/TriaxialStressController.cpp'
--- pkg/dem/TriaxialStressController.cpp 2010-12-31 14:35:21 +0000
+++ pkg/dem/TriaxialStressController.cpp 2011-04-03 16:49:58 +0000
@@ -14,6 +14,7 @@
#include<yade/core/State.hpp>
#include<assert.h>
#include<yade/core/Scene.hpp>
+#include<yade/pkg/dem/Shop.hpp>
CREATE_LOGGER(TriaxialStressController);
YADE_PLUGIN((TriaxialStressController));
@@ -244,53 +245,6 @@
/*!
\fn TriaxialStressController::ComputeUnbalancedForce( bool maxUnbalanced)
*/
-Real TriaxialStressController::ComputeUnbalancedForce( bool maxUnbalanced)
-{
- scene->forces.sync();
- //compute the mean contact force
- Real MeanForce = 0.f;
- long nForce = 0;
- shared_ptr<BodyContainer>& bodies = scene->bodies;
-
- InteractionContainer::iterator ii = scene->interactions->begin();
- InteractionContainer::iterator iiEnd = scene->interactions->end();
- for( ; ii!=iiEnd ; ++ii ) {
- if ((*ii)->isReal()) {
- const shared_ptr<Interaction>& contact = *ii;
- Real f = (static_cast<FrictPhys*> ((contact->phys.get()))->normalForce+static_cast<FrictPhys*>(contact->phys.get())->shearForce).squaredNorm();
- if (f!=0) {
- MeanForce += sqrt(f);
- ++nForce;}
- }
- }
- if (nForce!=0) MeanForce /= nForce;
-
- if (!maxUnbalanced) {
- //compute mean Unbalanced Force
- Real MeanUnbalanced=0;
- long nBodies = 0;
- BodyContainer::iterator bi = bodies->begin();
- BodyContainer::iterator biEnd = bodies->end();
- Real f;
- for( ; bi!=biEnd ; ++bi ) {
- if ((*bi)->isDynamic()) {
- f=getForce(scene,(*bi)->getId()).norm();
- MeanUnbalanced += f;
- if (f!=0) ++nBodies;
- }
- }
- if (nBodies != 0 && MeanForce != 0) MeanUnbalanced = MeanUnbalanced/nBodies/MeanForce;
- return MeanUnbalanced;
- } else {
- //compute max Unbalanced Force
- Real MaxUnbalanced=0;
- BodyContainer::iterator bi = bodies->begin();
- BodyContainer::iterator biEnd = bodies->end();
- for( ; bi!=biEnd ; ++bi ) if ((*bi)->isDynamic())
- MaxUnbalanced = std::max(getForce(scene,(*bi)->getId()).norm(),MaxUnbalanced);
- if (MeanForce != 0) MaxUnbalanced = MaxUnbalanced/MeanForce;
- return MaxUnbalanced;
- }
-}
+Real TriaxialStressController::ComputeUnbalancedForce( bool maxUnbalanced) {return Shop::unbalancedForce(maxUnbalanced,scene);}