예제 #1
0
int *generateNCounts(galaxy *gals, int numGals, int numVoxelsPerDim, int xStart,
	int yStart, int zStart, int boxLength){

	// Allocate the voxel array.
	int *voxels = calloc(pow(numVoxelsPerDim, 3), sizeof(int));

	// Convert the galaxy list to cartesian coordinates.
	cartesianGalaxy *cartGals = convertToCartesian(gals, numGals);

	// Loop through each galaxy and add it to the corresponding voxel.
	double voxelLength = (double)boxLength/numVoxelsPerDim;
	int ind;
	#pragma omp parallel for
	for(ind = 0; ind < numGals; ind++){
		// Adjust the location of the galaxy.
		double x = (cartGals+ind)->x - xStart;
		double y = (cartGals+ind)->y - yStart;
		double z = (cartGals+ind)->z - zStart;

		// Calculate the index of the galaxy.
		int i = x/voxelLength;
		int j = y/voxelLength;
		int k = z/voxelLength;
		int index = i + numVoxelsPerDim*j + pow(numVoxelsPerDim, 2)*k;

		// Increment the voxel at this location.
		#pragma omp critical
			voxels[index]++;
	}

	return voxels;
}
예제 #2
0
/**
 * Compute the area as a diagnostic and print it stdout.
 */
void SwarmCylinders::Spline::computeArea()
{
	double da = 1e-3;
	vector<double> x;
	vector<double> y;

	for (int i = 0; i < 1.0 / da; i++)
	{
		vector<double> a;

		a.push_back(i * da * M_PI);
		vector<double> r;

		r.push_back(evaluate(a[0]));
		convertToCartesian(r, a);
		x.push_back(r[0]);
		y.push_back(a[0]);
		a.clear();
		r.clear();
	}

	double area = 0;

	const int xsize = x.size();
	for (int i = 0; i < xsize - 1; i++)
		area += 0.5 * (x[i + 1] - x[i]) * (y[i] + y[i + 1]);

	printf("** Area: %1.10f", -area);
}
예제 #3
0
/**
 * Check if the spline crosses the y-axis, if so, abort.
 */
void SwarmCylinders::checkValidityOfSpline() const
{
	const int nSpline = 512;
	const double ymin = 0.10; // if 0, prevents you from creating splines that cross the y-axis
	const double dalpha = 2.0 * M_PI / (double) nSpline;

	vector<double> xTest;
	vector<double> yTest;

	for (int i = 0; i < nSpline; i++)
	{
		xTest.push_back(spline.evaluate((double) i + 0.5) * dalpha);
		yTest.push_back(((double) i + 0.5) * dalpha);
	}
	convertToCartesian(xTest, yTest);

	for (int i = 0; i < nSpline; i++)
	{
		if (yTest[i] < ymin)
		{
			printf("** The spline crosses or is too close to the the mirror plane! (ymin = %0.4f, k1 = %0.4f k2 = %0.4f, alpha = %0.4f)\n", ymin, K1, K2, alpha);
			abort();
		}
	}
}
예제 #4
0
QImage CurveTransform::transform() {
	for(unsigned int i = 0; i < image_width; i++) {
		for(unsigned int j = 0; j < image_height; j++) {
			CartesianPair coords = {i, j};
			drawPixels(convertToPixels(convertToCartesian(convertToPolar(coords))),coords); //Lisp, eat your heart out
		}
	}
	return out_image;	
}
예제 #5
0
/**
 * Initially place the cylinders somewhere inside the region bounded by the
 * spline.
 */
void SwarmCylinders::placeCylinders()
{
	printf("** Number of agents: %d\n", n);
	printf("** Placing agents %1.4f inside of the boundary! \n", rmin);

	double dalpha = 2.0 * M_PI / (double) n;
	for (int i = 0; i < n; i++)
	{
		x.push_back(spline.evaluate(((double) i + 0.5) * dalpha) - rmin);
		y.push_back(((double) i + 0.5) * dalpha);
	}
	convertToCartesian(x, y);
}
예제 #6
0
double *generateMap(galaxy *gals, int numGals, int numVoxelsPerDim, int xStart,
	int yStart, int zStart, int boxLength, int **voxels){

	// Allocate the voxel array.
	*voxels = calloc(pow(numVoxelsPerDim, 3), sizeof(int));

	// Convert the galaxy list to cartesian coordinates.
	cartesianGalaxy *cartGals = convertToCartesian(gals, numGals);

	// Loop through each galaxy and add it to the corresponding voxel.
	double voxelLength = (double)boxLength/numVoxelsPerDim;
	int ind;
	#pragma omp parallel for
	for(ind = 0; ind < numGals; ind++){
		// Adjust the location of the galaxy.
		double x = (cartGals+ind)->x - xStart;
		double y = (cartGals+ind)->y - yStart;
		double z = (cartGals+ind)->z - zStart;

		// Calculate the index of the galaxy.
		int i = x/voxelLength;
		int j = y/voxelLength;
		int k = z/voxelLength;
		int index = i + numVoxelsPerDim*j + pow(numVoxelsPerDim, 2)*k;

		// Increment the voxel at this location.
		#pragma omp critical
			(*(*voxels + index))++;
	}

	// Loop through each voxel and calculate the contrasts.
	double p0 = numGals/pow(numVoxelsPerDim, 3);
	double *map = calloc(pow(numVoxelsPerDim, 3), sizeof(double));
	#pragma omp parallel for
	for(ind = 0; ind < (int)pow(numVoxelsPerDim, 3); ind++){
		if((*voxels)[ind] == 0){
			map[ind] = -0.9;
		}else{
			*(map+ind) = (*(*voxels+ind) - p0)/p0;
		}
	}

	return map;
}
예제 #7
0
/**
 * Print the spline in (x,y) coordinates to a file named spline.txt.
 */
void SwarmCylinders::printSpline() const
{
	double dalpha = 2.0 * M_PI / (double) M;

	vector<double> xs;
	vector<double> ys;

	for (int i = 0; i < M; i++)
	{
		xs.push_back(spline.evaluate(((double) i + 0.5) * dalpha));
		ys.push_back(((double) i + 0.5) * dalpha);
	}
	convertToCartesian(xs, ys);

	FILE* fid;
	fid = fopen("spline.txt", "w");
	for (int i = 0; i < (int) xs.size(); i++)
	{
		fprintf(fid, "%10.6f %10.6f\n", xs[i], ys[i]);
	}
	fclose(fid);
}
예제 #8
0
/**
 * Find the equilibrium after placing the cylinders in the domain somewhere.
 * Iterates until tolerence is met.
 */
void SwarmCylinders::findEquilibrium()
{
	double dalpha = 2.0 * M_PI / (double) M;

	vector<double> m;

	for (int i = 0; i < M; i++)
	{
		m.push_back(spline.evaluate(i * dalpha) * dalpha); /// assuming constant density charge on boundary
	}

	vector<double> xs;
	vector<double> ys;

	for (int i = 0; i < M; i++)
	{
		xs.push_back(spline.evaluate(((double) i + 0.5) * dalpha));
		ys.push_back(((double) i + 0.5) * dalpha);
	}

	convertToCartesian(xs, ys);

	int nIter = 0;
	bool steadyState = false;
	while (!steadyState)
	{
		vector<double> xNew;
		vector<double> yNew;
		const int xsize = x.size();
		for (int i = 0; i < xsize; i++)
		{
			xNew.push_back(0.0);
			yNew.push_back(0.0);
		}

		for (int i = 0; i < xsize; i++)
		{
			double u = 0.0;
			double v = 0.0;

			for (int j = 0; j < xsize; j++) /// from each body
			{
				if (i != j)
				{
					double norm = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
					double factor = factorCylinder / (norm * norm * norm);
					u += (x[i] - x[j]) * factor;
					v += (y[i] - y[j]) * factor;
				}
			}

			for (int j = 0; j < M; j++) /// from boundary
			{
				double norm = sqrt((x[i] - xs[j]) * (x[i] - xs[j]) + (y[i] - ys[j]) * (y[i] - ys[j]));
				double factor = factorBoundary * m[j] / (norm * norm * norm);
				u += (x[i] - xs[j]) * factor;
				v += (y[i] - ys[j]) * factor;
			}

			xNew[i] = x[i] + dt * u;
			yNew[i] = y[i] + dt * v;
		}

		convertToPolar(xNew, yNew);

		for (int i = 0; i < xsize; i++)
		{
			const double rMax = spline.evaluate(yNew[i]) - radius;
			if (rMax < xNew[i])
				xNew[i] = 0.1 * rMax; /// move it toward (0,0)

//			xNew[i] = min(spline.evaluate(yNew[i])-radius, xNew[i]); /// make it sit on the boundary if it is not repelled enough (not exactly correct)

		}

		convertToCartesian(xNew, yNew);

		double maxNorm = 0.0;
		for (int i = 0; i < xsize; i++)
		{
			double norm = sqrt((xNew[i] - x[i]) * (xNew[i] - x[i]) + (yNew[i] - y[i]) * (yNew[i] - y[i])); /// relative difference
			maxNorm = max(norm, maxNorm);
		}

		for (int i = 0; i < xsize; i++)
		{
			x[i] = xNew[i];
			y[i] = yNew[i];
		}

		// TODO Remove this testing shit, writing the positions each iteration

		if (nIter % 10 == 0)
		{
			FILE* fidx;
			FILE* fidy;

			if (nIter == 0)
			{
				fidx = fopen("x.txt", "w");
				fidy = fopen("y.txt", "w");
			}
			else
			{
				fidx = fopen("x.txt", "a");
				fidy = fopen("y.txt", "a");
			}

			const int xsize = x.size();
			for (int i = 0; i < xsize; ++i)
			{
				fprintf(fidx, "%e ", x[i]);
				fprintf(fidy, "%e ", y[i]);
			}

			fprintf(fidx, "\n");
			fprintf(fidy, "\n");

			fclose(fidx);
			fclose(fidy);
		}
		nIter++;

		if (maxNorm <= threshold)
			break;

		if (nIter % 5000 == 0)
			printf("** Norm at iteration %d: %e\n", nIter, maxNorm);

		if (nIter > 50000)
		{
			printf("** Something is wrong, swarm shape is not converging quickly enough... aborting... \n");
			abort();
		}
	}
	printf("** Number of iterations to steady state formation: %d\n", nIter);
}