void problem_init(int argc, char* argv[]){
	// Setup constants
#ifdef GRAVITY_TREE
	opening_angle2	= .5;
#endif
	OMEGA 				= 0.00013143527;	// 1/s
	tmax				= 2.*M_PI/OMEGA;
	G 				= 6.67428e-11;		// N / (1e-5 kg)^2 m^2
	softening 			= 0.1;			// m
	dt 				= 1e-2*2.*M_PI/OMEGA;	// s
	root_nx = 8; root_ny = 8; root_nz = 1;
	nghostx = 2; nghosty = 2; nghostz = 0; 			// Use three ghost rings
	double surfacedensity 		= 418; 			// kg/m^2
	double particle_density		= 400;			// kg/m^3
	double particle_radius_min 	= 1;			// m
	double particle_radius_max 	= 4;			// m
	double particle_radius_slope 	= -3;	
	boxsize 			= 70.7;
	if (argc>1){						// Try to read boxsize from command line
		boxsize = atof(argv[1]);
	}
	init_box();
	
	// Initial conditions
	// Use Bridges et al coefficient of restitution.
	coefficient_of_restitution_for_velocity = coefficient_of_restitution_bridges;
	minimum_collision_velocity = particle_radius_min*OMEGA*0.001;  // small fraction of the shear
	double total_mass = surfacedensity*boxsize*boxsize;
	for(int i=0;i<root_n;i++){
#ifdef MPI
		if (communication_mpi_rootbox_is_local(i)==0) continue;
#endif
		// Ring particles
		double mass = 0;
		while(mass<total_mass){
			struct particle pt;
			int ri = i%root_nx;
			int rj = ((i-ri)/root_nx)%root_ny;
			int xmin = -boxsize_x/2.+(double)(ri)*boxsize;
			int ymin = -boxsize_y/2.+(double)(rj)*boxsize;
			pt.x 		= tools_uniform(xmin,xmin+boxsize);
			pt.y 		= tools_uniform(ymin,ymin+boxsize);
			pt.z 		= tools_normal(1.);					// m
			pt.vx 		= 0;
			pt.vy 		= -1.5*pt.x*OMEGA;
			pt.vz 		= 0;
			pt.ax 		= 0;
			pt.ay 		= 0;
			pt.az 		= 0;
			double radius 	= tools_powerlaw(particle_radius_min,particle_radius_max,particle_radius_slope);
#ifndef COLLISIONS_NONE
			pt.r 		= radius;						// m
#endif // COLLISIONS_NONE
			double	particle_mass = particle_density*4./3.*M_PI*radius*radius*radius;
			pt.m 		= particle_mass; 	// kg
			particles_add(pt);
			mass += particle_mass;
		}
	}
}
void problem_init(int argc, char* argv[]){
	// Setup constants
#ifdef GRAVITY_TREE
	opening_angle2	= .5;
#endif // GRAVITY_TREE
	OMEGA 				= 0.00013143527;	// 1/s
	G 				= 6.67428e-11;		// N / (1e-5 kg)^2 m^2
	softening 			= 0.1;			// m
	dt 				= 1e-3*2.*M_PI/OMEGA;	// s
#ifdef OPENGL
	display_rotate_z		= 20;			// Rotate the box by 20 around the z axis, then 
	display_rotate_x		= 60;			// rotate the box by 60 degrees around the x axis	
#ifdef LIBPNG
	system("mkdir png");
#endif // LIBPNG
#endif // OPENGL
	root_nx = 2; root_ny = 2; root_nz = 1;
	nghostx = 2; nghosty = 2; nghostz = 0; 			// Use two ghost rings
	double surfacedensity 		= 400; 			// kg/m^2
	double particle_density		= 400;			// kg/m^3
	double particle_radius_min 	= 1;			// m
	double particle_radius_max 	= 4;			// m
	double particle_radius_slope 	= -3;	
	boxsize 			= 100;			// m
	if (argc>1){						// Try to read boxsize from command line
		boxsize = atof(argv[1]);
	}
	init_box();
	
	// Initial conditions
	printf("Toomre wavelength: %f\n",2.*M_PI*M_PI*surfacedensity/OMEGA/OMEGA*G);
	// Use Bridges et al coefficient of restitution.
	coefficient_of_restitution_for_velocity = coefficient_of_restitution_bridges;
	minimum_collision_velocity = particle_radius_min*OMEGA*0.001;  // small fraction of the shear
	double total_mass = surfacedensity*boxsize_x*boxsize_y;
	double mass = 0;
	while(mass<total_mass){
		struct particle pt;
		pt.x 		= tools_uniform(-boxsize_x/2.,boxsize_x/2.);
		pt.y 		= tools_uniform(-boxsize_y/2.,boxsize_y/2.);
		pt.z 		= tools_normal(1.);					// m
		pt.vx 		= 0;
		pt.vy 		= -1.5*pt.x*OMEGA;
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		double radius 	= tools_powerlaw(particle_radius_min,particle_radius_max,particle_radius_slope);
#ifndef COLLISIONS_NONE
		pt.r 		= radius;						// m
#endif
		double		particle_mass = particle_density*4./3.*M_PI*radius*radius*radius;
		pt.m 		= particle_mass; 	// kg
		particles_add(pt);
		mass += particle_mass;
	}
}
Exemple #3
0
void problem_init(int argc, char* argv[]){
	// Setup constants
#ifdef GRAVITY_TREE
	opening_angle2	= .5;
#endif
	OMEGA 				= 0.00013143527;	// 1/s
	G 				= 6.67428e-11;		// N / (1e-5 kg)^2 m^2
	softening 			= 0.1;			// m
	dt 				= 1e-3*2.*M_PI/OMEGA;	// s
	root_nx = 2; root_ny = 2; root_nz = 1;
	nghostx = 2; nghosty = 2; nghostz = 0; 			// Use two ghost rings
	double surfacedensity 		= 400; 			// kg/m^2
	double particle_density		= 400;			// kg/m^3
	double particle_radius_min 	= 1;			// m
	double particle_radius_max 	= 4;			// m
	double particle_radius_slope 	= -3;	
	boxsize 			= 100;
	if (argc>1){						// Try to read boxsize from command line
		boxsize = atof(argv[1]);
	}
	init_box();
	
	// Initial conditions
	printf("Toomre wavelength: %f\n",2.*M_PI*M_PI*surfacedensity/OMEGA/OMEGA*G);
	// Use Bridges et al coefficient of restitution.
	coefficient_of_restitution_for_velocity = coefficient_of_restitution_bridges;
	minimum_collision_velocity = particle_radius_min*OMEGA*0.001;  // small fraction of the shear
	double total_mass = surfacedensity*boxsize_x*boxsize_y;
#ifdef MPI
	// Only initialise particles on master. This should also be parallelied but the details depend on the individual problem.
	if (mpi_id==0){
#endif
		double mass = 0;
		while(mass<total_mass){
			struct particle pt;
			pt.x 		= tools_uniform(-boxsize_x/2.,boxsize_x/2.);
			pt.y 		= tools_uniform(-boxsize_y/2.,boxsize_y/2.);
			pt.z 		= tools_normal(1.);					// m
			pt.vx 		= 0;
			pt.vy 		= -1.5*pt.x*OMEGA;
			pt.vz 		= 0;
			pt.ax 		= 0;
			pt.ay 		= 0;
			pt.az 		= 0;
			double radius 	= tools_powerlaw(particle_radius_min,particle_radius_max,particle_radius_slope);
#ifndef COLLISIONS_NONE
			pt.r 		= radius;						// m
#endif
			double		particle_mass = particle_density*4./3.*M_PI*radius*radius*radius;
			pt.m 		= particle_mass; 	// kg
			particles_add(pt);
			mass += particle_mass;
		}
#ifdef MPI
	}
#endif
}
Exemple #4
0
void problem_init(int argc, char* argv[]){
	// Setup constants
	OMEGA 				= 0.00013143527;	// 1/s
	G 				= 6.67428e-11;		// N / (1e-5 kg)^2 m^2
	dt 				= 1e-3*2.*M_PI/OMEGA;	// s
	root_nx = 10; root_ny = 1; root_nz = 1;
	nghostx = 1; nghosty = 1; nghostz = 0; 			// Use two one ring (+cutoff, see below)
	double surfacedensity 		= 400; 			// kg/m^2
	double particle_density		= 400;			// kg/m^3
	double particle_radius_min 	= 1;			// m
	double particle_radius_max 	= 4;			// m
	double particle_radius_slope 	= -3;	
	boxsize 			= 100;
	if (argc>1){						// Try to read boxsize from command line
		boxsize = atof(argv[1]);
	}
	init_box();
#ifdef GRAVITY_GRAPE
	gravity_range = boxsize/2.;
#endif // GRAVITY_GRAPE
	
	// Initial conditions
	printf("Toomre wavelength: %f\n",2.*M_PI*M_PI*surfacedensity/OMEGA/OMEGA*G);
#ifndef COLLISIONS_NONE
	// Use Bridges et al coefficient of restitution.
	coefficient_of_restitution_for_velocity	= coefficient_of_restitution_bridges;
	minimum_collision_velocity		= particle_radius_min*OMEGA*0.001;  // small fraction of the shear
	softening 				= 0.1;			// m
#else  // COLLISIONS_NONE
	softening				= particle_radius_max;
#endif // COLLISIONS_NONE
	double total_mass = surfacedensity*boxsize_x*boxsize_y;
	double mass = 0;
	while(mass<total_mass){
		struct particle pt;
		pt.x 		= tools_uniform(-boxsize_x/2.,boxsize_x/2.);
		pt.y 		= tools_uniform(-boxsize_y/2.,boxsize_y/2.);
		pt.z 		= tools_normal(1.);					// m
		pt.vx 		= 0;
		pt.vy 		= -1.5*pt.x*OMEGA;
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		double radius 	= tools_powerlaw(particle_radius_min,particle_radius_max,particle_radius_slope);
#ifndef COLLISIONS_NONE
		pt.r 		= radius;						// m
#endif
		double		particle_mass = particle_density*4./3.*M_PI*radius*radius*radius;
		pt.m 		= particle_mass; 	// kg
		particles_add(pt);
		mass += particle_mass;
	}
}
Exemple #5
0
void problem_init(int argc, char* argv[]){
	// Setup constants
#ifdef GRAVITY_TREE
	opening_angle2	= .5;
#endif // GRAVITY_TREE
	integrator			= SEI;
	OMEGA 				= 0.00013143527;	// 1/s
	G 				= 6.67428e-11;		// N / (1e-5 kg)^2 m^2
	softening 			= 0.1;			// m
	dt 				= 1e-3*2.*M_PI/OMEGA;	// s
	root_nx = 2; root_ny = 2; root_nz = 1;
	nghostx = 2; nghosty = 2; nghostz = 0; 			// Use two ghost rings
	double surfacedensity 		= 840; 			// kg/m^2
	double particle_density		= 900;			// kg/m^3
	double particle_radius_min 	= 1.;			// m
	double particle_radius_max 	= 1.;			// m
	double particle_radius_slope 	= -3;	
	boxsize 			= 40;			// m
	if (argc>1){						// Try to read boxsize from command line
		boxsize = atof(argv[1]);
	}
	init_box();
	
	// Initial conditions
	printf("Toomre wavelength: %f\n",4.*M_PI*M_PI*surfacedensity/OMEGA/OMEGA*G);
	// Use Bridges et al coefficient of restitution.
	coefficient_of_restitution_for_velocity = coefficient_of_restitution_bridges;
	// Change collision_resolve routing from default.
	collision_resolve = collision_resolve_hardsphere_pullaway;
	// Small residual velocity to avoid particles from sinking into each other.
	minimum_collision_velocity = particle_radius_min*OMEGA*0.001;  // small fraction of the shear
	double total_mass = surfacedensity*boxsize_x*boxsize_y;
	double mass = 0;
	while(mass<total_mass){
		struct particle pt;
		pt.x 		= tools_uniform(-boxsize_x/2.,boxsize_x/2.);
		pt.y 		= tools_uniform(-boxsize_y/2.,boxsize_y/2.);
		pt.z 		= tools_normal(1.);					// m
		pt.vx 		= 0;
		pt.vy 		= -1.5*pt.x*OMEGA;
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		double radius 	= tools_powerlaw(particle_radius_min,particle_radius_max,particle_radius_slope);
#ifndef COLLISIONS_NONE
		pt.r 		= radius;						// m
#endif
		double		particle_mass = particle_density*4./3.*M_PI*radius*radius*radius;
		pt.m 		= particle_mass; 	// kg
		particles_add(pt);
		mass += particle_mass;
	}
}
Exemple #6
0
void problem_init(int argc, char* argv[]){

	// Integrator parameters
	OMEGA = 1.0;
	dt = 1.0e-3;										// timestep
	tmax = dt*Nsteps_per_output*Noutput;				// simulation stop time
//#ifdef OPENGL
//	display_rotate_z = 90;								// display rotation angle (deg)
//	display_rotate_x = 0;	
//#endif

	//Particle parameters
	double x0_max = 10;									// particles' initial -x0_max < x < x0_max
	double y0_max = 50;									// particles' initial y range
    double z0_max = 0.0;								// particles' initial z range
	boxsize = 1;
	root_nx	= 20;
	root_ny = 100;
	root_nz = 10;
	nghostx = 0;
	nghosty = 1;										// ghost boxes along y direction only
	nghostz = 0;
	double radius = 0.0;								// particle radius
	double density = 0.5;								// particle density in cgs when radius is in cm
	coefficient_of_restitution = 0.5;
	minimum_collision_velocity = 0.001;
	init_box();

	// Initial conditions
	for (int i=0; i<N_init; i++){
		struct particle p;
		p.x = tools_uniform(-x0_max, x0_max);
		p.y = tools_uniform(-y0_max, y0_max);
		p.z = tools_uniform(-z0_max, z0_max);
		p.vx = 0;
		p.vy = -1.5*p.x*OMEGA;
		p.vz = 0;
		p.ax = 0;
		p.ay = 0;
		p.az = 0;
		p.m = 4*M_PI*density*radius*radius*radius/3;
		p.r = radius;
	    //pt.id = i;
		particles_add(p);
	}
}
Exemple #7
0
void problem_init(int argc, char* argv[]){
	// Setup constants
	opening_angle2	= 1.5;		// This constant determines the accuracy of the tree code gravity estimate.
	G 		= 1;		
	softening 	= 0.01;		// Gravitational softening length
	dt 		= 3e-3;		// Timestep
	boxsize 	= 1.2;		// Particles outside the box are removed
	root_nx = 1; root_ny = 1; root_nz = 1;
	nghostx = 0; nghosty = 0; nghostz = 0; 		
	init_box();

	// Setup particles
	double disc_mass = 2e-1;	// Total disc mass
	int _N = 10000;			// Number of particles
	// Initial conditions
	struct particle star;
	star.x 		= 0; star.y 	= 0; star.z	= 0;
	star.vx 	= 0; star.vy 	= 0; star.vz 	= 0;
	star.ax 	= 0; star.ay 	= 0; star.az 	= 0;
	star.m 		= 1;
#ifdef INTEGRATOR_WH
	// Insert particle manually. Don't add it to tree.
	Nmax 			+= 128;
	particles 		= realloc(particles,sizeof(struct particle)*Nmax);
	particles[N] 		= star;
	N++;
#else // INTEGRATOR_WH
	particles_add(star);
#endif // INTEGRATOR_WH
	while(N<_N){
		struct particle pt;
		double a	= tools_powerlaw(boxsize/10.,boxsize/2./1.2,-1.5);
		double phi 	= tools_uniform(0,2.*M_PI);
		pt.x 		= a*cos(phi);
		pt.y 		= a*sin(phi);
		pt.z 		= a*tools_normal(0.001);
		double mu 	= star.m + disc_mass * (pow(a,-3./2.)-pow(boxsize/10.,-3./2.))/(pow(boxsize/2./1.2,-3./2.)-pow(boxsize/10.,-3./2.));
		double vkep 	= sqrt(G*mu/a);
		pt.vx 		=  vkep * sin(phi);
		pt.vy 		= -vkep * cos(phi);
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		pt.m 		= disc_mass/(double)_N;
		particles_add(pt);
	}
}
Exemple #8
0
void problem_init(int argc, char* argv[]){
	// Setup constants
	G 		= 1;		
	integrator	= LEAPFROG;
	softening 	= 0.01;		
	dt 		= 3e-3;
	boxsize 	= 1.2;
	root_nx = 1; root_ny = 1; root_nz = 1;
	nghostx = 0; nghosty = 0; nghostz = 0; 		
	init_box();

	// Setup particles
	double disc_mass = 2e-1;
	int _N = 10000;
	// Initial conditions
	struct particle star;
	star.x 		= 0; star.y 	= 0; star.z	= 0;
	star.vx 	= 0; star.vy 	= 0; star.vz 	= 0;
	star.ax 	= 0; star.ay 	= 0; star.az 	= 0;
	star.m 		= 1;
#ifdef INTEGRATOR_WH
	// Insert particle manually. Don't add it to tree.
	Nmax 			+= 128;
	particles 		= realloc(particles,sizeof(struct particle)*Nmax);
	particles[N] 		= star;
	N++;
#else // INTEGRATOR_WH
	particles_add(star);
#endif // INTEGRATOR_WH
	while(N<_N){
		struct particle pt;
		double a	= tools_powerlaw(boxsize/10.,boxsize/2./1.2,-1.5);
		double phi 	= tools_uniform(0,2.*M_PI);
		pt.x 		= a*cos(phi);
		pt.y 		= a*sin(phi);
		pt.z 		= a*tools_normal(0.001);
		double mu 	= star.m + disc_mass * (pow(a,-3./2.)-pow(boxsize/10.,-3./2.))/(pow(boxsize/2./1.2,-3./2.)-pow(boxsize/10.,-3./2.));
		double vkep 	= sqrt(G*mu/a);
		pt.vx 		=  vkep * sin(phi);
		pt.vy 		= -vkep * cos(phi);
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		pt.m 		= disc_mass/(double)_N;
		particles_add(pt);
	}
}
Exemple #9
0
void problem_init(int argc, char* argv[]){
	// Setup constants
	integrator	= WH;
	G 		= 1;		
	N_active	= 1;
	N_collisions	= 1; 	// Don't detect collisions for the star.
	softening 	= 0.01;		
	dt 		= 1e-3;
	boxsize 	= 2.4;
	root_nx = 1; root_ny = 1; root_nz = 1;
	nghostx = 0; nghosty = 0; nghostz = 0; 		
	init_box();

	// Setup particles
	int _N = 1000;
	// Initial conditions
	struct particle star;
	star.x 		= 0; star.y 	= 0; star.z	= 0;
	star.vx 	= 0; star.vy 	= 0; star.vz 	= 0;
	star.ax 	= 0; star.ay 	= 0; star.az 	= 0;
	star.m 		= 1;
	star.r		= 0.01;
	particles_add(star);
	while(N<_N){
		struct particle pt;
		double a	= tools_powerlaw(boxsize/2.9,boxsize/3.1,.5);
		double phi 	= tools_uniform(0,2.*M_PI);
		pt.x 		= a*cos(phi);
		pt.y 		= a*sin(phi);
		pt.z 		= a*tools_normal(0.0001);
		double vkep 	= sqrt(G*star.m/a);
		pt.vx 		=  vkep * sin(phi);
		pt.vy 		= -vkep * cos(phi);
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		pt.m 		= 0.0001;
		pt.r 		= .3/sqrt((double)_N);
		particles_add(pt);
	}
}
Exemple #10
0
void problem_init(int argc, char* argv[]){
	// Setup constants
	G 		= 1;		
	softening 	= 0.01;		
	dt 		= 3e-3;
	boxsize 	= 2.4;
	integrator	= LEAPFROG;
	root_nx = 1; root_ny = 1; root_nz = 1;
	nghostx = 0; nghosty = 0; nghostz = 0; 		
	init_box();

	// Initial conditions
	struct particle star;
	star.x 		= 0; star.y 	= 0; star.z	= 0;
	star.vx 	= 0; star.vy 	= 0; star.vz 	= 0;
	star.ax 	= 0; star.ay 	= 0; star.az 	= 0;
	star.m 		= 1;
	particles_add(star);
	
	// Setup disk particles
	double disc_mass = 2e-1;
	int _N = 1024*4;
	while(N<_N){
		struct particle pt;
		double a	= tools_powerlaw(boxsize/20.,boxsize/4./1.2,-1.5);
		double phi 	= tools_uniform(0,2.*M_PI);
		pt.x 		= a*cos(phi);
		pt.y 		= a*sin(phi);
		pt.z 		= a*tools_normal(0.001);
		double mu 	= star.m + disc_mass * (pow(a,-3./2.)-pow(boxsize/20.,-3./2.))/(pow(boxsize/4./1.2,-3./2.)-pow(boxsize/20.,-3./2.));
		double vkep 	= sqrt(G*mu/a);
		pt.vx 		=  vkep * sin(phi);
		pt.vy 		= -vkep * cos(phi);
		pt.vz 		= 0;
		pt.ax 		= 0;
		pt.ay 		= 0;
		pt.az 		= 0;
		pt.m 		= disc_mass/(double)_N;
		particles_add(pt);
	}
}
Exemple #11
0
void tools_init_plummer(int _N, double M, double R) {
	// Algorithm from:	
	// http://adsabs.harvard.edu/abs/1974A%26A....37..183A
	
	double E = 3./64.*M_PI*M*M/R;
	for (int i=0;i<_N;i++){
		struct particle star;
		double r = pow(pow(tools_uniform(0,1),-2./3.)-1.,-1./2.);
		double x2 = tools_uniform(0,1);
		double x3 = tools_uniform(0,2.*M_PI);
		star.z = (1.-2.*x2)*r;
		star.x = sqrt(r*r-star.z*star.z)*cos(x3);
		star.y = sqrt(r*r-star.z*star.z)*sin(x3);
		double x5,g,q;
		do{
			x5 = tools_uniform(0.,1.);
			q = tools_uniform(0.,1.);
			g = q*q*pow(1.-q*q,7./2.);
		}while(0.1*x5>g);
		double ve = pow(2.,1./2.)*pow(1.+r*r,-1./4.);
		double v = q*ve;
		double x6 = tools_uniform(0.,1.);
		double x7 = tools_uniform(0.,2.*M_PI);
		star.vz = (1.-2.*x6)*v;
		star.vx = sqrt(v*v-star.vz*star.vz)*cos(x7);
		star.vy = sqrt(v*v-star.vz*star.vz)*sin(x7);
		
		star.x *= 3.*M_PI/64.*M*M/E;
		star.y *= 3.*M_PI/64.*M*M/E;
		star.z *= 3.*M_PI/64.*M*M/E;
		
		star.vx *= sqrt(E*64./3./M_PI/M);
		star.vy *= sqrt(E*64./3./M_PI/M);
		star.vz *= sqrt(E*64./3./M_PI/M);

		star.m = M/(double)_N;


		particles_add(star);
	}
}
Exemple #12
0
double tools_rayleigh(double sigma){
	double y = tools_uniform(0.,1.);
	return sigma*sqrt(-2*log(y));
}
Exemple #13
0
double tools_powerlaw(double min, double max, double slope){
	double y = tools_uniform(0., 1.);
	return pow( (pow(max,slope+1.)-pow(min,slope+1.))*y+pow(min,slope+1.), 1./(slope+1.));
}
Exemple #14
0
void problem_init(int argc, char* argv[]) {
    // Setup constants
    double radius 	= 1;
    double mass	= 1;
    dt 		= 1e-1;
    integrator	= LEAPFROG;
    // Override default collision handling to account for border particles
    coefficient_of_restitution 	= 0.15;
    collision_resolve = collision_resolve_hardsphere_withborder;
    root_nx = 1;
    root_ny = 1;
    root_nz = 4;
    nghostx = 1;
    nghosty = 1;
    nghostz = 0;
    boxsize = 20;
    init_box();
    double N_part 	= 0.00937*boxsize_x*boxsize_y*boxsize_z;

    // Add Border Particles
    double border_spacing_x = boxsize_x/(floor(boxsize_x/radius/2.)-1.);
    double border_spacing_y = boxsize_y/(floor(boxsize_y/radius/2.)-1.);
    struct particle pt;
    pt.vx 		= 0;
    pt.vz 		= 0;
    pt.ax 		= 0;
    pt.ay 		= 0;
    pt.az 		= 0;
    pt.r 		= radius;
    pt.m 		= mass;
    for(double x = -boxsize_x/2.; x<boxsize_x/2.-border_spacing_x/2.; x+=border_spacing_x) {
        for(double y = -boxsize_y/2.; y<boxsize_y/2.-border_spacing_y/2.; y+=border_spacing_y) {
            pt.x 		= x;
            pt.y 		= y;

            // Add particle to bottom
            pt.z 		= -boxsize_z/2.+radius;
            pt.vy 		= 1;
            particles_add(pt);

            // Add particle to top
            pt.z 		= boxsize_z/2.-radius;
            pt.vy 		= -1;
            particles_add(pt);
            N_tree_fixed++;
        }
    }

    N_border = N;
#ifdef TREE
    N_tree_fixed = N_border;
#endif // TREE

    // Add real particles
    while(N-N_border<N_part) {
        struct particle pt;
        pt.x 		= tools_uniform(-boxsize_x/2.,boxsize_x/2.);
        pt.y 		= tools_uniform(-boxsize_y/2.,boxsize_y/2.);
        pt.z 		= 0.758*tools_uniform(-boxsize_z/2.,boxsize_z/2.);
        pt.vx 		= tools_normal(0.001);
        pt.vy 		= tools_normal(0.001);
        pt.vz 		= tools_normal(0.001);
        pt.ax 		= 0;
        pt.ay 		= 0;
        pt.az 		= 0;
        pt.r 		= radius;						// m
        pt.m 		= 1;
        particles_add(pt);
    }
}