예제 #1
0
파일: test.c 프로젝트: dillonrooney/3body
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;
}