Exemplo n.º 1
0
// ---------------------------------------------------------------------------
/// Simple tester of the mapper (uses linear distribution function to generate mapper).
// ---------------------------------------------------------------------------
void
mapper_testLinear (void)
{
  int i;
  FILE *fp;
  double y, dy;
  mapper_t *mapper;

  say ("Testing of the distribution function mapper using linear function with known inverse mapping.");
  say ("See file output/test_mapper.dat for results.");

  mapper = mapper_create (func_lin, 0, sqrt (2.0), 20);

  fp = cfg_open ("output/test_mapper.dat", "wt", __func__);
  fprintf (fp, "variables = y invGood invNum delta\nzone t=\"test\", f = point\n");
  for (y = 0, dy = 0.01 ; y <= 1.0 ; y += dy)
  {
    double x1 = mapper_invoke (y, mapper);
    fprintf (fp, "%e %e %e %e\n", y, sqrt (2*y), x1, x1 - sqrt (2*y));
  }

  fprintf (fp, "zone t=\"integral\", f = point\n");
  for (i = 0 ; i < mapper->N ; i++)
    fprintf (fp, "%e %e %e %e\n", mapper->arg[i], mapper->func[i], 0.5*mapper->arg[i]*mapper->arg[i], mapper->func[i] - 0.5*mapper->arg[i]*mapper->arg[i]);
  fclose (fp);

  mapper_destroy (mapper);
}
Exemplo n.º 2
0
// ---------------------------------------------------------------------------
/// More advanced tester of the mapper (uses maxwellian distribution function to generate mapper).
// ---------------------------------------------------------------------------
void
mapper_testMaxwell (void)
{
  int i;
  FILE *fp;
  double y, dy;
  mapper_t *mapper;

  say ("Testing of the distribution function mapper using Maxwell function with known inverse mapping.");
  say ("See file output/test_mapper2.dat for results.");

  mapper = mapper_create (func_maxwell, - 10.0, 10.0, 5000);								// Creates mapper.

  const double norm = 1.0/(erf (mapper->arg[mapper->N]) - erf (mapper->arg[0]));					// Normalization for analitic result.
  fp = cfg_open ("output/test_mapper2.dat", "wt", __func__);
  fprintf (fp, "variables = x yGood yNum delta\nzone t=\"test\", f = point\n");
  for (y = 0.0, dy = 0.01 ; y <= 1.0 + 1e-7 ; y += dy)
  {
    double x = mapper_invoke (y, mapper);
    double analitic = norm*(erf(x) - erf (mapper->arg[0]));
    fprintf (fp, "%e %e %e %e\n", x, y, analitic, y - analitic);
  }

  fprintf (fp, "zone t=\"integral\", f = point\n");
  for (i = 0 ; i <= mapper->N ; i++)
  {
    double analitic = norm*(erf (mapper->arg[i]) - erf (mapper->arg[0]));
    fprintf (fp, "%e %e %e %e\n", mapper->arg[i], analitic, mapper->func[i], mapper->func[i] - analitic);
  }
  fclose (fp);

  mapper_destroy (mapper);
}
Exemplo n.º 3
0
Arquivo: cli.c Projeto: draringi/gini
void CLIDestroy()
{
	mapper_destroy(&cli_mapper);
	map_destroy(&cli_map);
}
Exemplo n.º 4
0
/**
  * Creates the DF itself used values precalculated at tag_photoDF(FILE *fp).
  */
static double
tag_photoInit(const double rho, const int uniformWeight, double qDivM)
{
	int nMax = 0;
	int patternSize = nx * ny * nz * Nx * Ny * Nz * N * (1 + mirror) * (1 + nRotations);
	marker_t *pattern = (marker_t *) malloc(patternSize * sizeof(marker_t));
	FILE *fp = NULL;

	mapper_t *mapper;	// Creates mapper.
	if(uniformWeight) mapper = mapper_create(tag_photoDF_DF, 0, mc_pi, 1000);
	else mapper = mapper_create(tag_photoDF_markers, 0, mc_pi, 1000);

	if(!cpu_here) {
		fp = cfg_open("output/photoDF_pattern.dat", "wt", "tag_photoInit");	// Saves pattern for examination.
		fprintf(fp, "variables = <greek>j/p</greek>, <greek>q/p</greek>, x, y, z, v<sub>x</sub>, v<sub>y</sub>, v<sub>z</sub>\nzone t=\"Basic pattern\", f = point\n");
	}

	int p = 0;		// Makes basic pattern.
	for(int i = 0; i < nx * Nx; ++i)
		for(int j = 0; j < ny * Ny; ++j)
			for(int k = 0; k < nz * Nz; ++k)
				for(int l = 0; l < N; ++l) {
					double phi, theta, tmp;
					denavit_createQuartet(p, nx * ny * nz * Nx * Ny * Nz * N, &tmp, &theta, &phi, &tmp);	// Gets Denavit-Wallsh coverage sample.

					theta /= 1.0 + mirror;	// Fills vz > 0 part (mirror will fill the rest).
					phi /= 1.0 + nRotations;	// Fills one slice of pie in V-space.

					pattern[p].x = h1 * (i + 0.5) / (double) nx;	// Uniform mesh in space.
					pattern[p].y = h2 * (j + 0.5) / (double) ny;
					pattern[p].z = h3 * (k + 0.5) / (double) nz;

					theta = mapper_invoke(theta, mapper);	// Morphes angle to get desired distribution.

					pattern[p].vx = V0 * sin(theta) * cos(phi * 2 * mc_pi);
					pattern[p].vy = V0 * sin(theta) * sin(phi * 2 * mc_pi);
					pattern[p].vz = V0 * cos(theta);

					pattern[p].rho = rho;
					pattern[p].rho = qDivM;

					if(!cpu_here) fprintf(fp, "%e %e %e %e %e %e %e %e\n", atan2(pattern[p].vx, pattern[p].vy) / mc_pi, acos(pattern[p]. vz / V0) / mc_pi,
							pattern[p].x, pattern[p].y, pattern[p].z, pattern[p].vx, pattern[p].vy, pattern[p].vz);
					++p;
				}
	nMax = p;

	mapper_destroy(mapper);	// Destroys mapper to free memory.

	if(!uniformWeight)	// Correction of the weights of the markers.
	{
		double correction = 0;
		for(int i = 0; i < nMax; ++i)	// Sets angular distribution of charge density.
		{
			pattern[i].rho = pattern[i].vz * pattern[i].vz;
			correction += pattern[i].rho;
		}

		correction = rho * nMax / correction;	// Sets proper magnitudes.
		for(int i = 0; i < nMax; ++i) pattern[i].rho *= correction;
	}

	if(!cpu_here) fprintf(fp, "\nzone t=\"Mirrored\", f = point\n");
	for(int i = 0; i < nMax && mirror; ++i)	// Adds mirrored basic pattern to the group.
	{
		pattern[p] = pattern[p - nMax];	// Full copy of all fields.

		/// \todo Remix mirror pattern (line allocate not in form pppp/p'p'p'p'p'/p_rotp_rot, but interleave) to avoid explicit excitation of the modes with \f$ lambda = N_x h_x \f$.
		pattern[p].z = h3 * Nz - pattern[p].z;	// Mirror: Z -> Z'.
		pattern[p].vz = -pattern[p].vz;	// Mirror: Vz - Vz'.

		if(!cpu_here) fprintf(fp, "%e %e %e %e %e %e %e %e\n", atan2(pattern[p].vx, pattern[p].vy) / mc_pi, acos(pattern[p].vz / V0) / mc_pi,
				pattern[p].x, pattern[p].y, pattern[p].z, pattern[p].vx, pattern[p].vy, pattern[p].vz);

		++p;
	}
	nMax = p;

	// Pattern += (basic pattern & mirror) rotated by 2*\pi*j/(nRotations + 1), j = 1, .., nRot.
	for(int l = 1; l <= nRotations; ++l) {
		if(!cpu_here) fprintf(fp, "\nzone t=\"Rotated by %d<sup>o</sup>\", f = point\n", (int) l * 360 / (nRotations + 1));
		double phi = 2 * mc_pi * l / (double) (nRotations + 1);
		for(int k = 0; k < nMax; ++k) {
			pattern[p] = pattern[k];	// Full copy of all fields.

			pattern[p].vx = pattern[k].vx * cos(phi) - pattern[k].vy * sin(phi);	// Rotation of the V vector.
			pattern[p].vy = pattern[k].vx * sin(phi) + pattern[k].vy * cos(phi);

			if(!cpu_here)
				fprintf(fp, "%e %e %e %e %e %e %e %e\n", atan2(pattern[p].vx, pattern[p].vy) / mc_pi, acos(pattern[p].vz / V0) / mc_pi,
						pattern[p].x, pattern[p].y, pattern[p].z, pattern[p].vx, pattern[p].vy, pattern[p].vz);

			++p;
		}
	}
	if(!cpu_here) fclose(fp);

	if(p != patternSize)	// Checks prediction of the pattern size.
		error("tag_photoInit: number of initialized markers is smaller than used one.");

	double xMin = +1e100, yMin = +1e100, zMin = +1e100;	// Bounding box of the pattern.
	double xMax = -1e100, yMax = -1e100, zMax = -1e100;
	for(p = 0; p < patternSize; ++p) {
		xMin = (pattern[p].x < xMin) ? pattern[p].x : xMin;
		yMin = (pattern[p].y < yMin) ? pattern[p].y : yMin;
		zMin = (pattern[p].z < zMin) ? pattern[p].z : zMin;
		xMax = (pattern[p].x > xMax) ? pattern[p].x : xMax;
		yMax = (pattern[p].y > yMax) ? pattern[p].y : yMax;
		zMax = (pattern[p].z > zMax) ? pattern[p].z : zMax;
	}
	xMin -= 1e-4 * h1;	// Extends bbox to ensure overlap and real check.
	yMin -= 1e-4 * h2;
	zMin -= 1e-4 * h3;
	xMax += 1e-4 * h1;
	yMax += 1e-4 * h2;
	zMax += 1e-4 * h3;

	double nPart = 0;
	for(int i = dmn_mesh_min[0]; i < dmn_mesh_max[0] + 1 - mc_have_x; i += Nx)	// Fills domain by pattern.
	{
		for(int j = dmn_mesh_min[1];
		     j < dmn_mesh_max[1] + 1 - mc_have_y; j += Ny) {
			for(int k = dmn_mesh_min[2];
			     k < dmn_mesh_max[2] + 1 - mc_have_z;
			     k += Nz) {
				if(((i * h1 + xMax < cpu_mesh_min[0] * h1 || i * h1 + xMin > cpu_mesh_max[0] * h1) && mc_have_x) ||	// Comparison by bounding box.
				    ((j * h2 + yMax < cpu_mesh_min[1] * h2|| j * h2 + yMin > cpu_mesh_max[1] * h2) && mc_have_y) ||
				    ((k * h3 + zMax < cpu_mesh_min[2] * h3|| k * h3 + zMin > cpu_mesh_max[2] * h3) && mc_have_z))
					continue;

				for(int l = 0; l < patternSize; ++l) {
					double x, y, z;
					x = pattern[l].x + i * h1;
					y = pattern[l].y + j * h2;
					z = pattern[l].z + k * h3;

					if(((x >= cpu_mesh_min[0] * h1 && x < cpu_mesh_max[0] * h1) || !mc_have_x) &&	// Fine filter for || setup.
					    ((y >= cpu_mesh_min[1] * h2&& y < cpu_mesh_max[1] * h2) || !mc_have_y) &&
					    ((z >= cpu_mesh_min[2] * h3 && z < cpu_mesh_max[2] * h3) || !mc_have_z)) {
						marker_t *marker = plasma_marker();	// Gets pointer on uninitialized marker.
						marker->x = x;
						marker->y = y;
						marker->z = z;
						marker->vx = pattern[l].vx;
						marker->vy = pattern[l].vy;
						marker->vz = pattern[l].vz;
						marker->rho = pattern[l].rho;
						nPart++;
					}
				}
			}
		}
	}

	free(pattern);		// Releases memory used to store stencil.

	return nPart;
}