int testMomentum(){ int n = 10; int i; double momentum[3]; int failed = 0; particle * stuff = malloc(n * sizeof(particle)); initialize_linearx(stuff, n); //zero momentum totalMomentum(stuff, n, momentum); if(momentum[0] != 0 || momentum[1] != 0 || momentum[2] != 0){ failed++; printf("nonzero momentum found x=%lf y=%lf z=%lf, expected zero momentum\n", momentum[0], momentum[1], momentum[2]); } //some momentum expected stuff[0].vx = 1; stuff[1].vx = 2; stuff[1].vy = 2; totalMomentum(stuff, n, momentum); if(momentum[0] != 3 || momentum[1] != 2 || momentum[2] != 0){ failed++; printf("unexpected momentum found x=%lf y=%lf z=%lf, expected 3,2,0\n", momentum[0], momentum[1], momentum[2]); } //non-equal masses stuff[0].mass = 2; totalMomentum(stuff, n, momentum); if(momentum[0] != 4 || momentum[1] != 2 || momentum[2] != 0){ failed++; printf("unexpected momentum found x=%lf y=%lf z=%lf, expected 4,2,0\n", momentum[0], momentum[1], momentum[2]); } //fprintParticles(stdout, stuff, n); free(stuff); if(failed == 0){ printf("momentum calculation passed\n"); } return !failed; }
Vector3D* GrapheneLatticeCreator::createVelocities(double *T, VelocityDistribution distribution, bool* fixingMap) { //defining random function function<Vector3D()> next; std::mt19937 *generator = NULL; std::normal_distribution<double> *dist = NULL; switch (distribution) { case MAXWELLBOLTZMANN: dist = new std::normal_distribution<double>(0, 1); generator = new std::mt19937((unsigned)time(0)); next = [generator, dist]() { return Vector3D((*dist)(*generator), (*dist)(*generator), (*dist)(*generator)); }; break; case UNIFORM: default: srand((unsigned int)time(0)); next = []() { Vector3D v( (double)rand() / RAND_MAX - 0.5, (double)rand() / RAND_MAX - 0.5, (double)rand() / RAND_MAX - 0.5 ); return v / v.norm(); }; break; } Vector3D* velocities = new Vector3D[l * w * c]; Vector3D totalMomentum(0, 0, 0); unsigned movable = 0; for (size_t i = 0; i < l; ++i) { for (size_t j = 0; j < w; ++j) { for (size_t k = 0; k < c; ++k) { size_t idx = linearize(i, j, k); if (fixingMap[idx]) { velocities[idx] = Vector3D(0, 0, 0); } else { velocities[idx] = next(); ++movable; totalMomentum = totalMomentum + velocities[idx]; } } } } totalMomentum = totalMomentum / (double)movable; for (size_t i = 0; i < l; i++) { for (size_t j = 0; j < w; j++) { for (size_t k = 0; k < c; k++) { size_t idx = linearize(i, j, k); if (!fixingMap[idx]) { velocities[idx] = velocities[idx] - totalMomentum; } } } } for (size_t i = 0; i < l; i++) { int number = 0; double v2 = 0; for (size_t j = 0; j < w; j++) { for (size_t k = 0; k < c; k++) { size_t idx = linearize(i, j, k); if (!fixingMap[idx]) { ++number; v2 += velocities[idx] || velocities[idx]; } } } v2 *= a2m * a2m; double multiplier = sqrt(3 * number * boltzmann * T[i] / mass / v2); for (size_t j = 0; j < w; ++j) { for (size_t k = 0; k < c; ++k) { size_t idx = linearize(i, j, k); velocities[idx] = multiplier * velocities[idx]; totalMomentum = totalMomentum + velocities[idx]; } } } if (dist != NULL) { delete dist; dist = NULL; } if (generator != NULL) { delete generator; generator = NULL; } return velocities; }