Advertisement
Guest User

Untitled

a guest
Mar 27th, 2017
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.84 KB | None | 0 0
  1. bool checkDistance(Particle& p1, Particle& p2){ //checks whether the distance between p1 and p2 is less than 1
  2. double dist = 0, relDist;
  3. for ( int i = 0; i < dim; i++){ //loop over all dimensions
  4. relDist = p1.pos[i] - p2.pos[i];
  5. if (fabs(relDist) > halfSize){ //max separation in one dimension is half of system size with PBC
  6. if(relDist < 0){ //shift the relative distance to the shortest possible one (minimum image convention)
  7. relDist += systemSize;
  8. }
  9. else {
  10. relDist -= systemSize;
  11. }
  12. }
  13. dist += relDist * relDist;
  14. }
  15. return (dist < 1);
  16. }
  17.  
  18. vector< vector< double> > System::calcForces(vector<vector<double> >& noise){ //calculate the force working on all particles in my system, adds a noise to this force (which is made in other function)
  19.  
  20. vector<vector<double> > forces (numberOfParticles, vector<double>(dim,0.0)); //contains the force working on every particle
  21.  
  22. /* this looks up neighbors with linked cell method*/
  23.  
  24. int numberOfCells = systemSize/interactionRange; //number of cells in one dimension. This way, all particles within interactionRange from a certain particle are in the same cell and in the neighboring cells.
  25. vector<vector<int> > header(numberOfCells, vector<int> (numberOfCells, -1)); //contains highest particle index for each cell, -1 if no particle
  26. vector<int> link(numberOfParticles, -1); //gives index of particle in same cell; -1 if no particle
  27. vector<int> centralCell, neighboringCell; //these contain the indices of particle in central cell and four of its neighbouring cells (in 2D). Don't need to loop over all neighbours for all cells.
  28. centralCell.reserve(numberOfParticles/(systemSize*systemSize) *2); //this is the amount of ints every cell will on average contain, probably unnecessary to reserve
  29. neighboringCell.reserve(numberOfParticles/(systemSize*systemSize) *2* 4);
  30.  
  31. vector<vector<double> > unitVectors (numberOfParticles, vector<double>(dim)); //create unit vector of velocities for all particles, needed for later force calculation
  32.  
  33. double norm = 0.0;
  34. double dotProduct = 0.0; //needed for force calculation
  35.  
  36. for(int i = 0; i < numberOfParticles; i++){
  37. for(int j = 0; j < dim; j++){
  38. norm += particleList[i].vel[j] * particleList[i].vel[j];
  39. }
  40. norm = sqrt(norm);
  41. for (int j = 0; j < dim; j++){
  42. unitVectors[i][j] = particleList[i].vel[j] / norm;
  43. }
  44. norm = 0.0;
  45. }
  46.  
  47. vector<vector<double> > averages(numberOfParticles, vector<double>(dim,0.0)); //contains average velocities of neighboring particles
  48. vector<int> neighborCount(numberOfParticles,0); //number of neighbours for every particle
  49. for (int i = 0; i < numberOfParticles; i++){ //fill header and link
  50. int xIndex = numberOfCells * particleList[i].pos[0] / systemSize;
  51. int yIndex = numberOfCells * particleList[i].pos[1] / systemSize;
  52. link[i] = header[xIndex][yIndex];
  53. header[xIndex][yIndex] = i;
  54. }
  55.  
  56.  
  57. for (int i = 0; i < numberOfCells; i++){ //only need to check with 4 cells. Uses PBC
  58. for (int j = 0; j < numberOfCells; j++){
  59. int tempIndex = header[i][j];
  60. while (tempIndex > -1){ //fill vector with particles in central cell
  61. centralCell.emplace_back(tempIndex);
  62. tempIndex = link[tempIndex];
  63. }
  64.  
  65. //fill vector with particles in 4 of the neighboring cells. The '%'s are used for periodic boundary conditions.
  66. tempIndex = header[(i+1) % numberOfCells][j];
  67. while (tempIndex > -1){
  68. neighboringCell.emplace_back(tempIndex);
  69. tempIndex = link[tempIndex];
  70. }
  71.  
  72. tempIndex = header[(i+1) % numberOfCells][(j+1) % numberOfCells];
  73. while (tempIndex > -1){
  74. neighboringCell.emplace_back(tempIndex);
  75. tempIndex = link[tempIndex];
  76. }
  77.  
  78. tempIndex = header[i][(j+1) % numberOfCells];
  79. while (tempIndex > -1){
  80. neighboringCell.emplace_back(tempIndex);
  81. tempIndex = link[tempIndex];
  82. }
  83.  
  84. tempIndex = header[(i+1) % numberOfCells][((j-1) % numberOfCells + numberOfCells) % numberOfCells];
  85. while (tempIndex > -1){
  86. neighboringCell.emplace_back(tempIndex);
  87. tempIndex = link[tempIndex];
  88. }
  89.  
  90. //calculate distance between particles in central cell + particles in neighboring cell. if smaller than interaction range, add to neighbors
  91. for (unsigned int k = 0; k < centralCell.size(); k++){
  92. neighborCount[centralCell[k]] +=1;
  93. for (int d = 0; d < dim; d++){
  94. averages[centralCell[k]][d] += unitVectors[centralCell[k]][d];
  95. }
  96. for(unsigned int l = 0; l < k; l++){
  97. if(checkDistance(particleList[centralCell[k]], particleList[centralCell[l]])){
  98. neighborCount[centralCell[k]] +=1;
  99. neighborCount[centralCell[l]] +=1;
  100. for (int d = 0; d < dim; d++){
  101. averages[centralCell[k]][d] += unitVectors[centralCell[l]][d];
  102. averages[centralCell[l]][d] += unitVectors[centralCell[k]][d];
  103. }
  104. }
  105. }
  106. }
  107.  
  108. for(unsigned int k = 0; k < centralCell.size(); k++){
  109. for(unsigned int l = 0; l < neighboringCell.size(); l++){
  110. if(checkDistance(particleList[centralCell[k]], particleList[neighboringCell[l]])){
  111. neighborCount[centralCell[k]] +=1;
  112. neighborCount[neighboringCell[l]] +=1;
  113. for (int d = 0; d < dim; d++){
  114. averages[centralCell[k]][d] += unitVectors[neighboringCell[l]][d];
  115. averages[neighboringCell[l]][d] += unitVectors[centralCell[k]][d];
  116. }
  117. }
  118. }
  119. }
  120. centralCell.clear();
  121. neighboringCell.clear();
  122. }
  123. }
  124.  
  125. int numberOfNeighbors;
  126. for(int i = 0; i < numberOfParticles; i++){ //calculate social force + friction + noise
  127. for (int k = 0; k < dim; k++){
  128. forces[i][k] = noise[i][k] - particleList[i].vel[k]; //stochastic + friction
  129. }
  130. if(neighborCount[i] != 0){
  131. numberOfNeighbors = neighborCount[i];
  132. for(int k = 0; k < dim; k++){
  133. dotProduct += averages[i][k]/numberOfNeighbors * unitVectors[i][k];
  134. }
  135.  
  136. for (int k = 0; k < dim; k++){
  137. forces[i][k] += couplingFactor * (averages[i][k]/numberOfNeighbors - unitVectors[i][k] * dotProduct);
  138. }
  139. dotProduct = 0.0;
  140. }
  141. }
  142. return forces;
  143. }
  144.  
  145. class Vector2D {
  146. // ...methods, etc.
  147.  
  148. float x;
  149. float y;
  150. };
  151.  
  152. class Vector3D {
  153. // ...methods, etc.
  154.  
  155. float x;
  156. float y;
  157. float z;
  158. };
  159.  
  160. for (int i = 0; i < numberOfParticles; i++) {
  161. unitVectors[i] = particleList[i].normalize();
  162. }
  163.  
  164. //calculate distance between particles in central cell + particles in neighboring cell. if smaller than interaction range, add to neighbors
  165. for (unsigned int k = 0; k < centralCell.size(); k++){
  166. neighborCount[centralCell[k]] +=1;
  167. for (int d = 0; d < dim; d++){
  168. averages[centralCell[k]][d] += unitVectors[centralCell[k]][d];
  169. }
  170. for(unsigned int l = 0; l < k; l++){
  171. if(checkDistance(particleList[centralCell[k]], particleList[centralCell[l]])){
  172. neighborCount[centralCell[k]] +=1;
  173. neighborCount[centralCell[l]] +=1;
  174. for (int d = 0; d < dim; d++){
  175. averages[centralCell[k]][d] += unitVectors[centralCell[l]][d];
  176. averages[centralCell[l]][d] += unitVectors[centralCell[k]][d];
  177. }
  178. }
  179. }
  180. }
  181.  
  182. for (unsigned int k = 0; k < centralCell.size(); k++)
  183. {
  184. int index = centralCell[k];
  185. neighborCount[index] += 1;
  186. //... etc., replacing centralCell[k] with index everywhere
  187. }
  188.  
  189. int neighborIndexes[4] = {
  190. header[i][j],
  191. header[(i+1) % numberOfCells][j],
  192. header[i][(j+1) % numberOfCells],
  193. header[(i+1) % numberOfCells][((j-1) % numberOfCells + numberOfCells) % numberOfCells]
  194. };
  195.  
  196. for (int k = 0; k < 4; k++)
  197. {
  198. int tempIndex = neighborIndexes[k];
  199. while(tempIndex > -1) {
  200. neighboringCell.emplace_back(tempIndex);
  201. tempIndex = link[tempIndex];
  202. }
  203. }
  204.  
  205. vector<VectorBase> forces(numberOfParticles);
  206.  
  207. vector<T> forces(numberOfParticles);
  208.  
  209. class Vector2D{
  210. public:
  211. double _x;
  212. double _y;
  213. Vector2D(){ _x = 0; _y = 0; }
  214. Vector2D(double x, double y){ _x = x; _y = y; }
  215. double norm() const
  216. {
  217. return sqrt(_x*_x + _y*_y);
  218. }
  219.  
  220. Vector2D& operator+=(Vector2D v){
  221. _x += v._x;
  222. _y += v._y;
  223. return *this;
  224. }
  225.  
  226. Vector2D& operator-=(Vector2D v){
  227. _x -= v._x;
  228. _y -= v._y;
  229. return *this;
  230. }
  231.  
  232. Vector2D& operator*=(double s) {
  233. _x *= s;
  234. _y *= s;
  235. return *this;
  236. }
  237.  
  238. Vector2D& operator/=(double s) {
  239. _x /= s;
  240. _y /= s;
  241. return *this;
  242. }
  243. };
  244.  
  245. inline Vector2D operator+(Vector2D a, Vector2D b) { return a += b; }
  246. inline Vector2D operator-(Vector2D a, Vector2D b) { return a -= b; }
  247. inline Vector2D operator*(Vector2D a, double s) { return a *= s; }
  248. inline Vector2D operator*(Vector2D a, Vector2D b){ return a._x * b._x + a._y * b._y; } //inner product of two vectors
  249. inline Vector2D operator*(double s, Vector2D b) { return b *= s; }
  250. inline Vector2D operator/(Vector2D a, double s) { return a /= s; }
  251. inline Vector2D normalize(Vector2D a){ return a / a.norm(); }
  252.  
  253. class Particle {
  254. public:
  255. Vector2D pos;
  256. Vector2D vel;
  257. };
  258.  
  259. bool checkDistance(Particle& p1, Particle& p2){
  260. double dist = 0, relDist;
  261. relDist = p1.pos._x - p2.pos._x;
  262. if (fabs(relDist) > systemSize / 2){ //max separation in one dimension is half of system size
  263. if (relDist < 0){
  264. relDist += systemSize;
  265. }
  266. else {
  267. relDist -= systemSize;
  268. }
  269. }
  270. dist += relDist * relDist;
  271.  
  272. relDist = p1.pos._y - p2.pos._y;
  273. if (fabs(relDist) > systemSize / 2){ //max separation in one dimension is half of system size
  274. if (relDist < 0){
  275. relDist += systemSize;
  276. }
  277. else {
  278. relDist -= systemSize;
  279. }
  280. }
  281. dist += relDist * relDist;
  282.  
  283. return (dist < 1);
  284. }
  285.  
  286. vector<Vector2D> System::calcForces(vector<Vector2D>& noise){
  287.  
  288. vector<Vector2D> forces (numberOfParticles); //contains the force working on every particle
  289. vector<Vector2D> averages(numberOfParticles); //contains average velocities of neighboring particles
  290.  
  291. /* creates neighborlist with linked cell method*/
  292.  
  293. int numberOfCells = systemSize; //number of cells in one dimension. This way, all particles within interactionRange from a certain particle are in the same cell and in the neighboring cells.
  294. vector<vector<int> > header(numberOfCells, vector<int> (numberOfCells, -1)); //contains highest particle index for each cell, -1 if no particle -> need better option for this
  295. vector<int> link(numberOfParticles, -1); //gives index of particle in same cell; -1 if no particle
  296. vector<int> centralCell, neighboringCell;
  297. centralCell.reserve(numberOfParticles/(systemSize*systemSize) *2);
  298. neighboringCell.reserve(numberOfParticles/(systemSize*systemSize) *2* 4);
  299.  
  300. vector<Vector2D> unitVectors (numberOfParticles); //create unit vector of velocities for all particles
  301. for(int i = 0; i < numberOfParticles; i++){
  302. unitVectors[i] = normalize(particleList[i].vel);
  303. }
  304.  
  305. vector<int> neighborCount(numberOfParticles,0);
  306. for (int i = 0; i < numberOfParticles; i++){ //fill header and link
  307. int xIndex = particleList[i].pos._x;
  308. int yIndex = particleList[i].pos._y;
  309. link[i] = header[xIndex][yIndex];
  310. header[xIndex][yIndex] = i;
  311. }
  312.  
  313.  
  314. for (int i = 0; i < numberOfCells; i++){ //only need to check with 4 cells. Uses PBC
  315. for (int j = 0; j < numberOfCells; j++){
  316.  
  317. int tempIndex = header[i][j];
  318. while (tempIndex > -1){ //fill vector with particles in central cell
  319. centralCell.emplace_back(tempIndex);
  320. tempIndex = link[tempIndex];
  321. }
  322.  
  323. int neighborIndexes[4] = {
  324. header[(i + 1) % numberOfCells][j],
  325. header[i][(j + 1) % numberOfCells],
  326. header[(i + 1) % numberOfCells][(j + 1) % numberOfCells],
  327. header[(i + 1) % numberOfCells][((j - 1) % numberOfCells + numberOfCells) % numberOfCells]
  328. };
  329.  
  330. for (int k = 0; k < 4; k++)
  331. {
  332. int tempIndex = neighborIndexes[k];
  333. while (tempIndex > -1) {
  334. neighboringCell.emplace_back(tempIndex);
  335. tempIndex = link[tempIndex];
  336. }
  337. }
  338.  
  339. int index1, index2;
  340. //calculate distance between particles in central cell + particles in neighboring cell. if smaller than interaction range, add to neighbors
  341. for (unsigned int k = 0; k < centralCell.size(); k++){
  342. index1 = centralCell[k];
  343. neighborCount[index1] +=1;
  344. averages[index1] += unitVectors[index1];
  345. for(unsigned int l = 0; l < k; l++){
  346. index2 = centralCell[l];
  347. if(checkDistance(particleList[index1], particleList[index2])){
  348. neighborCount[index1] +=1;
  349. neighborCount[index2] +=1;
  350. averages[index1] += unitVectors[index2];
  351. averages[index2] += unitVectors[index1];
  352. }
  353. }
  354. }
  355.  
  356. for(unsigned int k = 0; k < centralCell.size(); k++){
  357. index1 = centralCell[k];
  358. for(unsigned int l = 0; l < neighboringCell.size(); l++){
  359. index2 = neighboringCell[l];
  360. if(checkDistance(particleList[index1], particleList[index2])){
  361. neighborCount[index1] +=1;
  362. neighborCount[index2] +=1;
  363. averages[index1] += unitVectors[index2];
  364. averages[index1] += unitVectors[index2];
  365. }
  366. }
  367. }
  368. centralCell.clear();
  369. neighboringCell.clear();
  370. }
  371. }
  372.  
  373. double dotProduct = 0.0;
  374.  
  375. for(int i = 0; i < numberOfParticles; i++){ //calculate social force + friction + noise
  376. forces[i] = noise[i]- particleList[i].vel; //stochastic + friction
  377. averages[i] /= neighborCount[i] ;
  378. dotProduct = averages[i] * unitVectors[i];
  379. forces[i] += couplingFactor * (averages[i]- unitVectors[i] * dotProduct);
  380. }
  381. }
  382. return forces;
  383. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement