yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #12574
[Branch ~yade-pkg/yade/git-trunk] Rev 3809: Move implementation of methods of ForceContainer in cpp.
------------------------------------------------------------
revno: 3809
committer: Anton Gladky <gladky.anton@xxxxxxxxx>
timestamp: Tue 2016-03-22 22:43:09 +0100
message:
Move implementation of methods of ForceContainer in cpp.
We have code duplication in hpp-file.
added:
core/ForceContainer.cpp
modified:
core/ForceContainer.hpp
--
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
=== added file 'core/ForceContainer.cpp'
--- core/ForceContainer.cpp 1970-01-01 00:00:00 +0000
+++ core/ForceContainer.cpp 2016-03-22 21:43:09 +0000
@@ -0,0 +1,410 @@
+#include <core/ForceContainer.hpp>
+
+#ifdef YADE_OPENMP
+#include <omp.h>
+inline void ForceContainer::ensureSize(Body::id_t id, int threadN) {
+ assert(nThreads>omp_get_thread_num());
+ const Body::id_t idMaxTmp = max(id, _maxId[threadN]);
+ _maxId[threadN] = 0;
+ if (threadN<0) {
+ resizePerm(min((size_t)1.5*(idMaxTmp+100),(size_t)(idMaxTmp+2000)));
+ } else if (sizeOfThreads[threadN]<=(size_t)idMaxTmp) {
+ resize(min((size_t)1.5*(idMaxTmp+100),(size_t)(idMaxTmp+2000)),threadN);
+ }
+}
+
+inline void ForceContainer::ensureSynced() {
+ if(!synced) throw runtime_error("ForceContainer not thread-synchronized; call sync() first!");
+}
+
+ForceContainer::ForceContainer() {
+ nThreads=omp_get_max_threads();
+ for(int i=0; i<nThreads; i++){
+ _forceData.push_back(vvector()); _torqueData.push_back(vvector());
+ _moveData.push_back(vvector()); _rotData.push_back(vvector());
+ sizeOfThreads.push_back(0);
+ _maxId.push_back(0);
+ }
+}
+
+const Vector3r& ForceContainer::getForce(Body::id_t id) {
+ ensureSynced();
+ return ((size_t)id<size)?_force[id]:_zero;
+}
+
+void ForceContainer::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& ForceContainer::getTorque(Body::id_t id) {
+ ensureSynced();
+ return ((size_t)id<size)?_torque[id]:_zero;
+}
+
+void ForceContainer::addTorque(Body::id_t id, const Vector3r& t) {
+ ensureSize(id,omp_get_thread_num());
+ synced=false;
+ _torqueData[omp_get_thread_num()][id]+=t;
+}
+
+const Vector3r& ForceContainer::getMove(Body::id_t id) {
+ ensureSynced();
+ return ((size_t)id<size)?_move[id]:_zero;
+}
+
+void ForceContainer::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& ForceContainer::getRot(Body::id_t id) {
+ ensureSynced();
+ return ((size_t)id<size)?_rot[id]:_zero;
+}
+
+void ForceContainer::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;
+}
+
+void ForceContainer::addMaxId(Body::id_t id) {
+ _maxId[omp_get_thread_num()]=id;
+}
+
+void ForceContainer::setPermForce(Body::id_t id, const Vector3r& f) {
+ ensureSize(id,-1);
+ synced=false;
+ _permForce[id]=f;
+ permForceUsed=true;
+}
+
+void ForceContainer::setPermTorque(Body::id_t id, const Vector3r& t) {
+ ensureSize(id,-1);
+ synced=false;
+ _permTorque[id]=t;
+ permForceUsed=true;
+}
+
+const Vector3r& ForceContainer::getPermForce(Body::id_t id) {
+ ensureSynced();
+ return ((size_t)id<size)?_permForce[id]:_zero;
+}
+
+const Vector3r& ForceContainer::getPermTorque(Body::id_t id) {
+ ensureSynced();
+ return ((size_t)id<size)?_permTorque[id]:_zero;
+}
+
+const Vector3r& ForceContainer::getForceUnsynced(Body::id_t id) {
+ assert ((size_t)id<size);
+ return _force[id];
+}
+
+const Vector3r& ForceContainer::getTorqueUnsynced(Body::id_t id) {
+ assert ((size_t)id<size);
+ return _torque[id];
+}
+
+void ForceContainer::addForceUnsynced(Body::id_t id, const Vector3r& f) {
+ assert ((size_t)id<size);
+ _force[id]+=f;
+}
+
+void ForceContainer::addTorqueUnsynced(Body::id_t id, const Vector3r& m) {
+ assert ((size_t)id<size);
+ _torque[id]+=m;
+}
+
+Vector3r ForceContainer::getForceSingle(Body::id_t id) {
+ Vector3r ret(Vector3r::Zero());
+ for(int t=0; t<nThreads; t++) {
+ ret+=((size_t)id<sizeOfThreads[t])?_forceData [t][id]:_zero;
+ }
+ if (permForceUsed) ret+=_permForce[id];
+ return ret;
+}
+
+Vector3r ForceContainer::getTorqueSingle(Body::id_t id) {
+ Vector3r ret(Vector3r::Zero());
+ for(int t=0; t<nThreads; t++) {
+ ret+=((size_t)id<sizeOfThreads[t])?_torqueData[t][id]:_zero;
+ }
+ if (permForceUsed) ret+=_permTorque[id];
+ return ret;
+}
+
+Vector3r ForceContainer::getMoveSingle(Body::id_t id) {
+ Vector3r ret(Vector3r::Zero());
+ for(int t=0; t<nThreads; t++) {
+ ret+=((size_t)id<sizeOfThreads[t])?_moveData[t][id]:_zero;
+ }
+ return ret;
+}
+
+Vector3r ForceContainer::getRotSingle(Body::id_t id) {
+ Vector3r ret(Vector3r::Zero());
+ for(int t=0; t<nThreads; t++) {
+ ret+=((size_t)id<sizeOfThreads[t])?_rotData[t][id]:_zero;
+ }
+ return ret;
+}
+
+void ForceContainer::syncSizesOfContainers() {
+ if (syncedSizes) return;
+ //check whether all containers have equal length, and if not resize it
+ for(int i=0; i<nThreads; i++){
+ if (sizeOfThreads[i]<size) resize(size,i);
+ }
+ _force.resize(size,Vector3r::Zero());
+ _torque.resize(size,Vector3r::Zero());
+ _permForce.resize(size,Vector3r::Zero());
+ _permTorque.resize(size,Vector3r::Zero());
+ _move.resize(size,Vector3r::Zero());
+ _rot.resize(size,Vector3r::Zero());
+ syncedSizes=true;
+}
+
+void ForceContainer::sync(){
+ for(int i=0; i<nThreads; i++){
+ if (_maxId[i] > 0) { synced = false;}
+ }
+ if(synced) return;
+ boost::mutex::scoped_lock lock(globalMutex);
+ if(synced) return; // if synced meanwhile
+
+ for(int i=0; i<nThreads; i++){
+ if (_maxId[i] > 0) { ensureSize(_maxId[i],i);}
+ }
+
+ syncSizesOfContainers();
+
+ for(long id=0; id<(long)size; id++){
+ Vector3r sumF(Vector3r::Zero()), sumT(Vector3r::Zero());
+ for(int thread=0; thread<nThreads; thread++){ sumF+=_forceData[thread][id]; sumT+=_torqueData[thread][id];}
+ _force[id]=sumF; _torque[id]=sumT;
+ if (permForceUsed) {_force[id]+=_permForce[id]; _torque[id]+=_permTorque[id];}
+ }
+ if(moveRotUsed){
+ for(long id=0; id<(long)size; id++){
+ Vector3r sumM(Vector3r::Zero()), sumR(Vector3r::Zero());
+ for(int thread=0; thread<nThreads; thread++){ sumM+=_moveData[thread][id]; sumR+=_rotData[thread][id];}
+ _move[id]=sumM; _rot[id]=sumR;
+ }
+ }
+ synced=true; syncCount++;
+}
+
+void ForceContainer::resize(size_t newSize, int threadN) {
+ _forceData [threadN].resize(newSize,Vector3r::Zero());
+ _torqueData[threadN].resize(newSize,Vector3r::Zero());
+ _moveData[threadN].resize(newSize,Vector3r::Zero());
+ _rotData[threadN].resize(newSize,Vector3r::Zero());
+ sizeOfThreads[threadN] = newSize;
+ if (size<newSize) size=newSize;
+ syncedSizes=false;
+}
+
+void ForceContainer::resizePerm(size_t newSize) {
+ _permForce.resize(newSize,Vector3r::Zero());
+ _permTorque.resize(newSize,Vector3r::Zero());
+ if (size<newSize) size=newSize;
+ syncedSizes=false;
+}
+
+void ForceContainer::reset(long iter, bool resetAll) {
+ syncSizesOfContainers();
+ for(int thread=0; thread<nThreads; thread++){
+ memset(&_forceData [thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
+ memset(&_torqueData[thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
+ if(moveRotUsed){
+ memset(&_moveData [thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
+ memset(&_rotData [thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
+ }
+ }
+ memset(&_force [0], 0,sizeof(Vector3r)*size);
+ memset(&_torque[0], 0,sizeof(Vector3r)*size);
+ if(moveRotUsed){
+ memset(&_move [0], 0,sizeof(Vector3r)*size);
+ memset(&_rot [0], 0,sizeof(Vector3r)*size);
+ }
+ if (resetAll){
+ memset(&_permForce [0], 0,sizeof(Vector3r)*size);
+ memset(&_permTorque[0], 0,sizeof(Vector3r)*size);
+ permForceUsed = false;
+ }
+ if (!permForceUsed) synced=true; else synced=false;
+ moveRotUsed=false;
+ lastReset=iter;
+}
+
+const int& ForceContainer::getNumAllocatedThreads() {
+ return nThreads;
+}
+
+const bool& ForceContainer::getMoveRotUsed() {
+ return moveRotUsed;
+}
+
+const bool& ForceContainer::getPermForceUsed() {
+ return permForceUsed;
+}
+
+#else
+void ForceContainer::ensureSize(Body::id_t id) {
+ const Body::id_t idMaxTmp = max(id, _maxId);
+ _maxId = 0;
+ if(size<=(size_t)idMaxTmp) resize(min((size_t)1.5*(idMaxTmp+100),(size_t)(idMaxTmp+2000)));
+}
+
+const Vector3r& ForceContainer::getForceUnsynced (Body::id_t id) {
+ return getForce(id);
+}
+
+const Vector3r& ForceContainer::getTorqueUnsynced(Body::id_t id) {
+ return getForce(id);
+}
+
+const Vector3r& ForceContainer::getForce(Body::id_t id) {
+ ensureSize(id);
+ return _force[id];
+}
+
+void ForceContainer::addForce(Body::id_t id,const Vector3r& f) {
+ ensureSize(id);
+ _force[id]+=f;
+}
+
+const Vector3r& ForceContainer::getTorque(Body::id_t id) {
+ ensureSize(id);
+ return _torque[id];
+}
+
+void ForceContainer::addTorque(Body::id_t id,const Vector3r& t) {
+ ensureSize(id);
+ _torque[id]+=t;
+}
+
+const Vector3r& ForceContainer::getMove(Body::id_t id) {
+ ensureSize(id);
+ return _move[id];
+}
+
+void ForceContainer::addMove(Body::id_t id,const Vector3r& f) {
+ ensureSize(id);
+ moveRotUsed=true;
+ _move[id]+=f;
+}
+
+const Vector3r& ForceContainer::getRot(Body::id_t id) {
+ ensureSize(id);
+ return _rot[id];
+}
+
+void ForceContainer::addRot(Body::id_t id,const Vector3r& f) {
+ ensureSize(id);
+ moveRotUsed=true;
+ _rot[id]+=f;
+}
+
+void ForceContainer::setPermForce(Body::id_t id, const Vector3r& f) {
+ ensureSize(id);
+ _permForce[id]=f;
+ permForceUsed=true;
+}
+
+void ForceContainer::setPermTorque(Body::id_t id, const Vector3r& t) {
+ ensureSize(id);
+ _permTorque[id]=t;
+ permForceUsed=true;
+}
+
+void ForceContainer::addMaxId(Body::id_t id) {
+ _maxId=id;
+}
+
+const Vector3r& ForceContainer::getPermForce(Body::id_t id) {
+ ensureSize(id);
+ return _permForce[id];
+}
+
+const Vector3r& ForceContainer::getPermTorque(Body::id_t id) {
+ ensureSize(id);
+ return _permTorque[id];
+}
+
+const Vector3r ForceContainer::getForceSingle (Body::id_t id) {
+ ensureSize(id);
+ if (permForceUsed) {
+ return _force [id] + _permForce[id];
+ } else {
+ return _force [id];
+ }
+}
+const Vector3r ForceContainer::getTorqueSingle(Body::id_t id) {
+ ensureSize(id);
+ if (permForceUsed) {
+ return _torque[id] + _permTorque[id];
+ } else {
+ return _torque[id];
+ }
+}
+const Vector3r& ForceContainer::getMoveSingle(Body::id_t id) {
+ ensureSize(id);
+ return _move [id];
+}
+
+const Vector3r& ForceContainer::getRotSingle(Body::id_t id) {
+ ensureSize(id);
+ return _rot[id];
+}
+
+void ForceContainer::reset(long iter, bool resetAll) {
+ memset(&_force [0],0,sizeof(Vector3r)*size);
+ memset(&_torque[0],0,sizeof(Vector3r)*size);
+ if(moveRotUsed){
+ memset(&_move [0],0,sizeof(Vector3r)*size);
+ memset(&_rot [0],0,sizeof(Vector3r)*size);
+ moveRotUsed=false;
+ }
+ if (resetAll){
+ memset(&_permForce [0], 0,sizeof(Vector3r)*size);
+ memset(&_permTorque[0], 0,sizeof(Vector3r)*size);
+ permForceUsed = false;
+ }
+ lastReset=iter;
+}
+
+void ForceContainer::sync() {
+ if (_maxId>0) {
+ ensureSize(_maxId);
+ _maxId=0;
+ }
+ if (permForceUsed) {
+ for(long id=0; id<(long)size; id++) {
+ _force[id]+=_permForce[id];
+ _torque[id]+=_permTorque[id];
+ }
+ }
+ return;
+}
+
+void ForceContainer::resize(size_t newSize) {
+ _force.resize(newSize,Vector3r::Zero());
+ _torque.resize(newSize,Vector3r::Zero());
+ _permForce.resize(newSize,Vector3r::Zero());
+ _permTorque.resize(newSize,Vector3r::Zero());
+ _move.resize(newSize,Vector3r::Zero());
+ _rot.resize(newSize,Vector3r::Zero());
+ size=newSize;
+}
+
+const int ForceContainer::getNumAllocatedThreads() const {return 1;}
+const bool& ForceContainer::getMoveRotUsed() const {return moveRotUsed;}
+const bool& ForceContainer::getPermForceUsed() const {return permForceUsed;}
+#endif
=== modified file 'core/ForceContainer.hpp'
--- core/ForceContainer.hpp 2016-01-28 13:24:40 +0000
+++ core/ForceContainer.hpp 2016-03-22 21:43:09 +0000
@@ -51,164 +51,71 @@
std::vector<Body::id_t> _maxId;
vvector _force, _torque, _move, _rot, _permForce, _permTorque;
std::vector<size_t> sizeOfThreads;
- size_t size;
- bool syncedSizes;
+ size_t size = 0;
+ bool syncedSizes = true;
int nThreads;
- bool synced,moveRotUsed,permForceUsed;
+ bool synced = true;
+ bool moveRotUsed = false;
+ bool permForceUsed = false;
boost::mutex globalMutex;
- Vector3r _zero;
+ Vector3r _zero = Vector3r::Zero();
- inline void ensureSize(Body::id_t id, int threadN){
- assert(nThreads>omp_get_thread_num());
- const Body::id_t idMaxTmp = max(id, _maxId[threadN]);
- _maxId[threadN] = 0;
- if (threadN<0) {
- resizePerm(min((size_t)1.5*(idMaxTmp+100),(size_t)(idMaxTmp+2000)));
- } else if (sizeOfThreads[threadN]<=(size_t)idMaxTmp) {
- resize(min((size_t)1.5*(idMaxTmp+100),(size_t)(idMaxTmp+2000)),threadN);
- }
- }
- inline void ensureSynced(){ if(!synced) throw runtime_error("ForceContainer not thread-synchronized; call sync() first!"); }
+ void ensureSize(Body::id_t id, int threadN);
+ void ensureSynced();
// dummy function to avoid template resolution failure
- friend class boost::serialization::access; template<class ArchiveT> void serialize(ArchiveT & ar, unsigned int version){}
+ friend class boost::serialization::access;
+ template<class ArchiveT> void serialize(ArchiveT & ar, unsigned int version){}
public:
- ForceContainer(): size(0), syncedSizes(true),synced(true),moveRotUsed(false),permForceUsed(false),_zero(Vector3r::Zero()),syncCount(0),lastReset(0){
- nThreads=omp_get_max_threads();
- for(int i=0; i<nThreads; i++){
- _forceData.push_back(vvector()); _torqueData.push_back(vvector());
- _moveData.push_back(vvector()); _rotData.push_back(vvector());
- sizeOfThreads.push_back(0);
- _maxId.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; }
- void addTorque(Body::id_t id, const Vector3r& t){ ensureSize(id,omp_get_thread_num()); synced=false; _torqueData[omp_get_thread_num()][id]+=t;}
- const Vector3r& getMove(Body::id_t id) { ensureSynced(); return ((size_t)id<size)?_move[id]:_zero; }
- 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;}
- void addMaxId(Body::id_t id) { _maxId[omp_get_thread_num()]=id;}
+ unsigned long syncCount = 0;
+ long lastReset = 0;
+ ForceContainer();
+ const Vector3r& getForce(Body::id_t id);
+ void addForce(Body::id_t id, const Vector3r& f);
+ const Vector3r& getTorque(Body::id_t id);
+ void addTorque(Body::id_t id, const Vector3r& t);
+ const Vector3r& getMove(Body::id_t id);
+ void addMove(Body::id_t id, const Vector3r& m);
+ const Vector3r& getRot(Body::id_t id);
+ void addRot(Body::id_t id, const Vector3r& r);
+ void addMaxId(Body::id_t id);
- void setPermForce(Body::id_t id, const Vector3r& f){ ensureSize(id,-1); synced=false; _permForce[id]=f; permForceUsed=true;}
- void setPermTorque(Body::id_t id, const Vector3r& t){ ensureSize(id,-1); synced=false; _permTorque[id]=t; permForceUsed=true;}
- const Vector3r& getPermForce(Body::id_t id) { ensureSynced(); return ((size_t)id<size)?_permForce[id]:_zero; }
- const Vector3r& getPermTorque(Body::id_t id) { ensureSynced(); return ((size_t)id<size)?_permTorque[id]:_zero; }
+ void setPermForce(Body::id_t id, const Vector3r& f);
+ void setPermTorque(Body::id_t id, const Vector3r& t);
+ const Vector3r& getPermForce(Body::id_t id);
+ const Vector3r& getPermTorque(Body::id_t id);
/*! 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. */
- const Vector3r& getForceUnsynced (Body::id_t id){assert ((size_t)id<size); return _force[id];}
- const Vector3r& getTorqueUnsynced(Body::id_t id){assert ((size_t)id<size); return _torque[id];}
- 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; }
+ const Vector3r& getForceUnsynced (Body::id_t id);
+ const Vector3r& getTorqueUnsynced(Body::id_t id);
+ void addForceUnsynced(Body::id_t id, const Vector3r& f);
+ void addTorqueUnsynced(Body::id_t id, const Vector3r& 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
// since Vector3r writes are not atomic, it might (rarely) return wrong value, if the computation is running meanwhile
- Vector3r getForceSingle (Body::id_t id){ Vector3r ret(Vector3r::Zero()); for(int t=0; t<nThreads; t++){ ret+=((size_t)id<sizeOfThreads[t])?_forceData [t][id]:_zero; } if (permForceUsed) ret+=_permForce[id]; return ret; }
- Vector3r getTorqueSingle(Body::id_t id){ Vector3r ret(Vector3r::Zero()); for(int t=0; t<nThreads; t++){ ret+=((size_t)id<sizeOfThreads[t])?_torqueData[t][id]:_zero; } if (permForceUsed) ret+=_permTorque[id]; return ret; }
- Vector3r getMoveSingle (Body::id_t id){ Vector3r ret(Vector3r::Zero()); for(int t=0; t<nThreads; t++){ ret+=((size_t)id<sizeOfThreads[t])?_moveData [t][id]:_zero; } return ret; }
- Vector3r getRotSingle (Body::id_t id){ Vector3r ret(Vector3r::Zero()); for(int t=0; t<nThreads; t++){ ret+=((size_t)id<sizeOfThreads[t])?_rotData [t][id]:_zero; } return ret; }
+ Vector3r getForceSingle (Body::id_t id);
+ Vector3r getTorqueSingle(Body::id_t id);
+ Vector3r getMoveSingle (Body::id_t id);
+ Vector3r getRotSingle (Body::id_t id);
- inline void syncSizesOfContainers() {
- if (syncedSizes) return;
- //check whether all containers have equal length, and if not resize it
- for(int i=0; i<nThreads; i++){
- if (sizeOfThreads[i]<size) resize(size,i);
- }
- _force.resize(size,Vector3r::Zero());
- _torque.resize(size,Vector3r::Zero());
- _permForce.resize(size,Vector3r::Zero());
- _permTorque.resize(size,Vector3r::Zero());
- _move.resize(size,Vector3r::Zero());
- _rot.resize(size,Vector3r::Zero());
- syncedSizes=true;
- }
+ void syncSizesOfContainers();
/* Sum contributions from all threads, save to _force&_torque.
* Locks globalMutex, since one thread modifies common data (_force&_torque).
* Must be called before get* methods are used. Exception is thrown otherwise, since data are not consistent. */
- inline void sync(){
- for(int i=0; i<nThreads; i++){
- if (_maxId[i] > 0) { synced = false;}
- }
- if(synced) return;
- boost::mutex::scoped_lock lock(globalMutex);
- if(synced) return; // if synced meanwhile
-
- for(int i=0; i<nThreads; i++){
- if (_maxId[i] > 0) { ensureSize(_maxId[i],i);}
- }
-
- syncSizesOfContainers();
-
- for(long id=0; id<(long)size; id++){
- Vector3r sumF(Vector3r::Zero()), sumT(Vector3r::Zero());
- for(int thread=0; thread<nThreads; thread++){ sumF+=_forceData[thread][id]; sumT+=_torqueData[thread][id];}
- _force[id]=sumF; _torque[id]=sumT;
- if (permForceUsed) {_force[id]+=_permForce[id]; _torque[id]+=_permTorque[id];}
- }
- if(moveRotUsed){
- for(long id=0; id<(long)size; id++){
- Vector3r sumM(Vector3r::Zero()), sumR(Vector3r::Zero());
- for(int thread=0; thread<nThreads; thread++){ sumM+=_moveData[thread][id]; sumR+=_rotData[thread][id];}
- _move[id]=sumM; _rot[id]=sumR;
- }
- }
- synced=true; syncCount++;
- }
- unsigned long syncCount;
- long lastReset;
-
- void resize(size_t newSize, int threadN){
- _forceData [threadN].resize(newSize,Vector3r::Zero());
- _torqueData[threadN].resize(newSize,Vector3r::Zero());
- _moveData[threadN].resize(newSize,Vector3r::Zero());
- _rotData[threadN].resize(newSize,Vector3r::Zero());
- sizeOfThreads[threadN] = newSize;
- if (size<newSize) size=newSize;
- syncedSizes=false;
- }
- void resizePerm(size_t newSize){
- _permForce.resize(newSize,Vector3r::Zero());
- _permTorque.resize(newSize,Vector3r::Zero());
- if (size<newSize) size=newSize;
- syncedSizes=false;
- }
+ void sync();
+ void resize(size_t newSize, int threadN);
+ void resizePerm(size_t newSize);
/*! Reset all resetable data, also reset summary forces/torques and mark the container clean.
If resetAll, reset also user defined forces and torques*/
// perhaps should be private and friend Scene or whatever the only caller should be
- void reset(long iter, bool resetAll=false){
- syncSizesOfContainers();
- for(int thread=0; thread<nThreads; thread++){
- memset(&_forceData [thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
- memset(&_torqueData[thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
- if(moveRotUsed){
- memset(&_moveData [thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
- memset(&_rotData [thread][0],0,sizeof(Vector3r)*sizeOfThreads[thread]);
- }
- }
- memset(&_force [0], 0,sizeof(Vector3r)*size);
- memset(&_torque[0], 0,sizeof(Vector3r)*size);
- if(moveRotUsed){
- memset(&_move [0], 0,sizeof(Vector3r)*size);
- memset(&_rot [0], 0,sizeof(Vector3r)*size);
- }
- if (resetAll){
- memset(&_permForce [0], 0,sizeof(Vector3r)*size);
- memset(&_permTorque[0], 0,sizeof(Vector3r)*size);
- permForceUsed = false;
- }
- if (!permForceUsed) synced=true; else synced=false;
- moveRotUsed=false;
- lastReset=iter;
- }
+ void reset(long iter, bool resetAll=false);
//! say for how many threads we have allocated space
- const int& getNumAllocatedThreads() const {return nThreads;}
- const bool& getMoveRotUsed() const {return moveRotUsed;}
- const bool& getPermForceUsed() const {return permForceUsed;}
+ const int& getNumAllocatedThreads();
+ const bool& getMoveRotUsed();
+ const bool& getPermForceUsed();
};
#else
@@ -219,100 +126,52 @@
std::vector<Vector3r> _torque;
std::vector<Vector3r> _move;
std::vector<Vector3r> _rot;
- std::vector<Vector3r> _permForce, _permTorque;
- Body::id_t _maxId;
- size_t size;
- bool moveRotUsed, permForceUsed;
- inline void ensureSize(Body::id_t id){
- const Body::id_t idMaxTmp = max(id, _maxId);
- _maxId = 0;
- if(size<=(size_t)idMaxTmp) resize(min((size_t)1.5*(idMaxTmp+100),(size_t)(idMaxTmp+2000)));
- }
- #if 0
- const Vector3r& getForceUnsynced (Body::id_t id){ return getForce(id);}
- const Vector3r& getTorqueUnsynced(Body::id_t id){ return getForce(id);}
- #endif
+ std::vector<Vector3r> _permForce;
+ std::vector<Vector3r> _permTorque;
+ Body::id_t _maxId=0;
+ size_t size=0;
+ bool moveRotUsed = false;
+ bool permForceUsed = false;
+ void ensureSize(Body::id_t id);
+
+ const Vector3r& getForceUnsynced (Body::id_t id);
+ const Vector3r& getTorqueUnsynced(Body::id_t id);
+
// dummy function to avoid template resolution failure
friend class boost::serialization::access; template<class ArchiveT> void serialize(ArchiveT & ar, unsigned int version){}
public:
- ForceContainer(): _maxId(0), size(0), moveRotUsed(false), permForceUsed(false), syncCount(0), lastReset(0){}
- const Vector3r& getForce(Body::id_t id){ensureSize(id); return _force[id];}
- void addForce(Body::id_t id,const Vector3r& f){ensureSize(id); _force[id]+=f;}
- const Vector3r& getTorque(Body::id_t id){ensureSize(id); return _torque[id];}
- void addTorque(Body::id_t id,const Vector3r& t){ensureSize(id); _torque[id]+=t;}
- const Vector3r& getMove(Body::id_t id){ensureSize(id); return _move[id];}
- void addMove(Body::id_t id,const Vector3r& f){ensureSize(id); moveRotUsed=true; _move[id]+=f;}
- const Vector3r& getRot(Body::id_t id){ensureSize(id); return _rot[id];}
- void addRot(Body::id_t id,const Vector3r& f){ensureSize(id); moveRotUsed=true; _rot[id]+=f;}
- void setPermForce(Body::id_t id, const Vector3r& f){ ensureSize(id); _permForce[id]=f; permForceUsed=true;}
- void setPermTorque(Body::id_t id, const Vector3r& t){ ensureSize(id); _permTorque[id]=t; permForceUsed=true;}
- void addMaxId(Body::id_t id) { _maxId=id;}
- const Vector3r& getPermForce(Body::id_t id) { ensureSize(id); return _permForce[id]; }
- const Vector3r& getPermTorque(Body::id_t id) { ensureSize(id); return _permTorque[id]; }
+ unsigned long syncCount = 0;
+ long lastReset=0;
+ ForceContainer() {}
+ const Vector3r& getForce(Body::id_t id);
+ void addForce(Body::id_t id,const Vector3r& f);
+ const Vector3r& getTorque(Body::id_t id);
+ void addTorque(Body::id_t id,const Vector3r& t);
+ const Vector3r& getMove(Body::id_t id);
+ void addMove(Body::id_t id,const Vector3r& f);
+ const Vector3r& getRot(Body::id_t id);
+ void addRot(Body::id_t id,const Vector3r& f);
+ void setPermForce(Body::id_t id, const Vector3r& f);
+ void setPermTorque(Body::id_t id, const Vector3r& t);
+ void addMaxId(Body::id_t id);
+ const Vector3r& getPermForce(Body::id_t id);
+ const Vector3r& getPermTorque(Body::id_t id);
// single getters do the same as globally synced ones in the non-parallel flavor
- const Vector3r getForceSingle (Body::id_t id){
- ensureSize(id);
- if (permForceUsed) {
- return _force [id] + _permForce[id];
- } else {
- return _force [id];
- }
- }
- const Vector3r getTorqueSingle(Body::id_t id){
- ensureSize(id);
- if (permForceUsed) {
- return _torque[id] + _permTorque[id];
- } else {
- return _torque[id];
- }
- }
- const Vector3r& getMoveSingle (Body::id_t id){ ensureSize(id); return _move [id]; }
- const Vector3r& getRotSingle (Body::id_t id){ ensureSize(id); return _rot [id]; }
+ const Vector3r getForceSingle (Body::id_t id);
+ const Vector3r getTorqueSingle(Body::id_t id);
+ const Vector3r& getMoveSingle (Body::id_t id);
+ const Vector3r& getRotSingle (Body::id_t id);
//! Set all forces to zero
- void reset(long iter, bool resetAll=false){
- memset(&_force [0],0,sizeof(Vector3r)*size);
- memset(&_torque[0],0,sizeof(Vector3r)*size);
- if(moveRotUsed){
- memset(&_move [0],0,sizeof(Vector3r)*size);
- memset(&_rot [0],0,sizeof(Vector3r)*size);
- moveRotUsed=false;
- }
- if (resetAll){
- memset(&_permForce [0], 0,sizeof(Vector3r)*size);
- memset(&_permTorque[0], 0,sizeof(Vector3r)*size);
- permForceUsed = false;
- }
- lastReset=iter;
- }
-
- void sync() {
- if (_maxId>0) {ensureSize(_maxId); _maxId=0;}
- if (permForceUsed) {
- for(long id=0; id<(long)size; id++) {
- _force[id]+=_permForce[id];
- _torque[id]+=_permTorque[id];
- }
- }
- return;
- }
- unsigned long syncCount;
+ void reset(long iter, bool resetAll=false);
+ void sync();
// interaction in which the container was last reset; used by NewtonIntegrator to detect whether ForceResetter was not forgotten
- long lastReset;
/*! Resize the container; this happens automatically,
* but you may want to set the size beforehand to avoid resizes as the simulation grows. */
- void resize(size_t newSize){
- _force.resize(newSize,Vector3r::Zero());
- _torque.resize(newSize,Vector3r::Zero());
- _permForce.resize(newSize,Vector3r::Zero());
- _permTorque.resize(newSize,Vector3r::Zero());
- _move.resize(newSize,Vector3r::Zero());
- _rot.resize(newSize,Vector3r::Zero());
- size=newSize;
- }
- const int getNumAllocatedThreads() const {return 1;}
- const bool& getMoveRotUsed() const {return moveRotUsed;}
- const bool& getPermForceUsed() const {return permForceUsed;}
+ void resize(size_t newSize);
+ const int getNumAllocatedThreads() const;
+ const bool& getMoveRotUsed() const;
+ const bool& getPermForceUsed() const;
};
#endif