← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-pkg/yade/git-trunk] Rev 3969: Resize ForceContainer after each body insert

 

------------------------------------------------------------
revno: 3969
committer: Anton Gladky <gladky.anton@xxxxxxxxx>
timestamp: Tue 2014-05-20 08:35:16 +0200
message:
  Resize ForceContainer after each body insert
  
  In a very rare cases, when clumps (possibly other
  bodies also) are generating continuosly without
  immediate contact to another body, ForceContainer
  can be not large enough to store force/torque information.
  
  Here we push zero force and torque to ForceContainer
  after each body insert to resize it if neccessary.
  
  Thanks Jörg Medack for bug report.
modified:
  core/BodyContainer.cpp
  core/ForceContainer.hpp
  pkg/dem/Integrator.cpp
  pkg/dem/NewtonIntegrator.cpp


--
lp:yade
https://code.launchpad.net/~yade-pkg/yade/git-trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-pkg/yade/git-trunk/+edit-subscription
=== modified file 'core/BodyContainer.cpp'
--- core/BodyContainer.cpp	2014-05-15 17:50:26 +0000
+++ core/BodyContainer.cpp	2014-05-20 06:35:16 +0000
@@ -46,6 +46,11 @@
 	scene->doSort = true;
 	
 	body[id]=b;
+
+	// Add Null-Vectors to force and torque containers to be sure they will have
+	// enough place for new body
+	scene->forces.addTorque(id,Vector3r::Zero());
+	scene->forces.addForce(id,Vector3r::Zero());
 	return id;
 }
 

=== modified file 'core/ForceContainer.hpp'
--- core/ForceContainer.hpp	2014-01-20 16:13:36 +0000
+++ core/ForceContainer.hpp	2014-05-20 06:35:16 +0000
@@ -97,8 +97,10 @@
 		/*! 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;}
+		const Vector3r& getForceUnsynced (Body::id_t id){return ((size_t)id<size)?_force[id]:_zero;}
+		const Vector3r& getTorqueUnsynced(Body::id_t id){return ((size_t)id<size)?_torque[id]:_zero;}
+		void  addForceUnsynced(Body::id_t id, const Vector3r& f){ assert ((size_t)id<size); _force[id]+=f; }
+		void  addTorqueUnsynced(Body::id_t id, const Vector3r& m){ assert ((size_t)id<size); _torque[id]+=m; }
 		
 		/* 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

=== modified file 'pkg/dem/Integrator.cpp'
--- pkg/dem/Integrator.cpp	2014-02-17 14:31:35 +0000
+++ pkg/dem/Integrator.cpp	2014-05-20 06:35:16 +0000
@@ -106,8 +106,8 @@
 				b->shape->cast<Clump>().addForceTorqueFromMembers(b->state.get(),scene,force,moment);
 				#ifdef YADE_OPENMP
 				//it is safe here, since only one thread will read/write
-				scene->forces.getTorqueUnsynced(id)+=moment;
-				scene->forces.getForceUnsynced(id)+=force;
+				scene->forces.addTorqueUnsynced(id,moment);
+				scene->forces.addForceUnsynced(id,force);
 				#else
 				scene->forces.addTorque(id,moment);
 				scene->forces.addForce(id,force);

=== modified file 'pkg/dem/NewtonIntegrator.cpp'
--- pkg/dem/NewtonIntegrator.cpp	2014-05-16 12:48:36 +0000
+++ pkg/dem/NewtonIntegrator.cpp	2014-05-20 06:35:16 +0000
@@ -142,14 +142,15 @@
 			// clump members are handled inside clumps
 			if(b->isClumpMember()) continue;
 			State* state=b->state.get(); const Body::id_t& id=b->getId();
-			Vector3r f=Vector3r::Zero(), m=Vector3r::Zero();
+			Vector3r f=Vector3r::Zero(); 
+			Vector3r 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 only one 
-				scene->forces.getTorqueUnsynced(id)+=m;
-				scene->forces.getForceUnsynced(id)+=f;
+				//it is safe here, since only one thread is adding forces/torques
+				scene->forces.addTorqueUnsynced(id,m);
+				scene->forces.addForceUnsynced(id,f);
 				#else
 				scene->forces.addTorque(id,m);
 				scene->forces.addForce(id,f);
@@ -201,6 +202,7 @@
 			leapfrogTranslate(state,id,dt);
 			if(!useAspherical) leapfrogSphericalRotate(state,id,dt);
 			else leapfrogAsphericalRotate(state,id,dt,m);
+			
 			saveMaximaDisplacement(b);
 			// move individual members of the clump, save maxima velocity (for collider stride)
 			if(b->isClump()) Clump::moveMembers(b,scene,this);


Follow ups