Example #1
0
void move_camera(int nc, int krp)
{
	double curr_time = 0;
	while (curr_time < dtp) 
	{
		null_buf(nc, krp);
		move_particles(nc, krp);
		final_buf(nc, krp);
		curr_time += dtp_var[krp];
	}
}
Example #2
0
float find_location(Map map, Particle particles[]) {
    float readings[72] = {
        32, 32, 32, 32, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 15, 15, 15,
        15, 15, 30,	30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 15, 15, 15,
        15, 15, 30, 30, 30, 30,	30, 30, 30, 30, 30, 30, 30, 30, 30, 15, 15, 15,
        15, 15, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30
    };
    int i = 54, ii;
    int *histogram = calloc(360, sizeof(int));

    robot_position = 270;

    while (variance(particles, NUM_PARTICLES) > POSITION_PROBABILITY_THRESHOLD * POSITION_PROBABILITY_THRESHOLD) {

        move_particles(particles);
        robot_position += TRAVEL_DISTANCE;

        if (robot_position > 360)
            robot_position -= 360;

        monte_carlo(map, particles, NUM_PARTICLES, readings[i % 72]);

        qsort(particles, NUM_PARTICLES, sizeof(Particle), compare_particles);
        if (i == 1 || i == 10) {
            printf("at time %d:\n", i);

            for (ii = 0; ii < NUM_PARTICLES; ii++) {
                histogram[(int)particles[ii].position]++;
            }

            for (ii = 0; ii < 360; ii++) {
                printf("%d, %d\n", ii, histogram[ii]);
            }
        }
        printf("at time %d std deviation: %.2f\n", i, standard_deviation(particles, NUM_PARTICLES));
        i++;
        if (i > 71)
            i = 0;
    }

    printf("Location %.2f in %d turns\n", mean_position(particles, NUM_PARTICLES), i);
    printf("Actual location %d\n", (int)robot_position);
    free(histogram);
    return mean_position(particles, NUM_PARTICLES);
}
Example #3
0
// The start of the Application
int App::start(const std::vector<std::string> &args)
{
	clan::DisplayWindowDescription win_desc;
	//win_desc.set_version(3, 2, false);
	win_desc.set_allow_resize(true);
	win_desc.set_title("Point Sprite Example");
	win_desc.set_size(clan::Size( 800, 480 ), false);

	clan::DisplayWindow window(win_desc);
    clan::SlotContainer cc;
	cc.connect(window.sig_window_close(), clan::bind_member(this, &App::on_window_close));
	cc.connect(window.get_ic().get_keyboard().sig_key_up(), clan::bind_member(this, &App::on_input_up));

	std::string theme;
	if (clan::FileHelp::file_exists("../../../Resources/GUIThemeAero/theme.css"))
		theme = "../../../Resources/GUIThemeAero";
	else if (clan::FileHelp::file_exists("../../../Resources/GUIThemeBasic/theme.css"))
		theme = "../../../Resources/GUIThemeBasic";
	else
		throw clan::Exception("No themes found");

	clan::GUIWindowManagerTexture wm(window);
	clan::GUIManager gui(wm, theme);
	
	clan::Canvas canvas(window);

	// Deleted automatically by the GUI
	Options *options = new Options(gui, clan::Rect(0, 0, canvas.get_size()));

	clan::Image image_grid(canvas, "../Blend/Resources/grid.png");
	clan::Texture2D texture_particle(canvas, "Resources/particle.png");
	float grid_width = (float) image_grid.get_width();
	float grid_height = (float) image_grid.get_height();

	grid_space = (float) (image_grid.get_width());

	setup_particles();

	clan::ShaderObject vertex_shader(canvas, clan::shadertype_vertex, text_shader_vertex);
	if(!vertex_shader.compile())
	{
		throw clan::Exception(clan::string_format("Unable to compile vertex shader object: %1", vertex_shader.get_info_log()));
	}

	clan::ShaderObject fragment_shader(canvas, clan::shadertype_fragment, text_shader_fragment);
	if(!fragment_shader.compile())
	{
		throw clan::Exception(clan::string_format("Unable to compile fragment shader object: %1", fragment_shader.get_info_log()));
	}

	clan::ProgramObject program_object(canvas);
	program_object.attach(vertex_shader);
	program_object.attach(fragment_shader);
	program_object.bind_attribute_location(0, "InPosition");
	program_object.bind_attribute_location(1, "InColor");
	if (!program_object.link())
	{
		throw clan::Exception(clan::string_format("Unable to link program object: %1", program_object.get_info_log()));
	}
	program_object.set_uniform1i("Texture0", 0);

	options->request_repaint();

	clan::BlendStateDescription blend_state_desc;
	blend_state_desc.enable_blending(true);
	blend_state_desc.set_blend_function(clan::blend_src_alpha, clan::blend_one, clan::blend_src_alpha, clan::blend_one);
	clan::BlendState blend_state(canvas, blend_state_desc);

	clan::GameTime game_time;

	while (!quit)
	{
		game_time.update();

		wm.process();
		wm.draw_windows(canvas);

		int num_particles = options->num_particles;
		if (num_particles > max_particles)
			num_particles = max_particles;

		move_particles(game_time.get_time_elapsed(), num_particles);

		const float grid_xpos = 10.0f;
		const float grid_ypos = 10.0f;

		// Draw the grid
		image_grid.draw(canvas, grid_xpos, grid_ypos);

		if (num_particles > 0)
		{
			std::vector<clan::Vec2f> positions;
			std::vector<clan::Colorf> colors;
			positions.resize(num_particles);
			colors.resize(num_particles);

			for (int cnt=0; cnt<num_particles; cnt++)
			{
				positions[cnt] = clan::Vec2f(grid_xpos + particles[cnt].xpos, grid_ypos + particles[cnt].ypos);
				switch (cnt % 3)
				{
					case 0:
						colors[cnt] = clan::Colorf(1.0f, 0.0f, 0.0f, 1.0f);
						break;
					case 1:
						colors[cnt] = clan::Colorf(0.0f, 1.0f, 0.0f, 1.0f);
						break;
					case 2:
						colors[cnt] = clan::Colorf(0.0f, 0.0f, 1.0f, 1.0f);
						break;
				}
			};

			canvas.flush();
			clan::GraphicContext gc = canvas.get_gc();

			canvas.set_blend_state(blend_state);

			clan::RasterizerStateDescription raster_state_desc;
			raster_state_desc.set_point_size(options->point_size);
			raster_state_desc.set_point_sprite_origin(clan::origin_upper_left);
			clan::RasterizerState raster_state(canvas, raster_state_desc);
			canvas.set_rasterizer_state(raster_state);

			clan::PrimitivesArray primarray(gc);

			clan::VertexArrayVector<clan::Vec2f> gpu_positions = clan::VertexArrayVector<clan::Vec2f>(gc, &positions[0], positions.size());
			clan::VertexArrayVector<clan::Colorf> gpu_colors = clan::VertexArrayVector<clan::Colorf>(gc, &colors[0], colors.size());

			primarray.set_attributes(0, gpu_positions);
			primarray.set_attributes(1, gpu_colors);

			ProgramUniforms buffer;
			buffer.cl_ModelViewProjectionMatrix = canvas.get_projection() * canvas.get_modelview();
			clan::UniformVector<ProgramUniforms> uniform_vector(gc, &buffer, 1);
			gc.set_uniform_buffer(0, uniform_vector);

			gc.set_texture(0, texture_particle);
			gc.set_program_object(program_object);
			gc.draw_primitives(clan::type_points, num_particles, primarray);
			gc.reset_program_object();
			gc.reset_texture(0);

			gc.reset_blend_state();
			gc.reset_rasterizer_state();
		}

		window.flip(1);

		clan::KeepAlive::process();
	}
	return 0;
}
Example #4
0
bool App::update()
{
	game_time.update();

	options->set_needs_render();
	options->set_rect(clan::Size(canvas.get_size()));
	options->update(clan::Colorf(0.6f, 0.6f, 0.2f, 1.0f));

	int num_particles = options->num_particles;
	if (num_particles > max_particles)
		num_particles = max_particles;

	move_particles(game_time.get_time_elapsed(), num_particles);

	const float grid_xpos = 10.0f;
	const float grid_ypos = 10.0f;

	// Draw the grid
	image_grid.draw(canvas, grid_xpos, grid_ypos);

	if (num_particles > 0)
	{
		std::vector<clan::Vec2f> positions;
		std::vector<clan::Colorf> colors;
		positions.resize(num_particles);
		colors.resize(num_particles);

		for (int cnt=0; cnt<num_particles; cnt++)
		{
			positions[cnt] = clan::Vec2f(grid_xpos + particles[cnt].xpos, grid_ypos + particles[cnt].ypos);
			switch (cnt % 3)
			{
				case 0:
					colors[cnt] = clan::Colorf(1.0f, 0.0f, 0.0f, 1.0f);
					break;
				case 1:
					colors[cnt] = clan::Colorf(0.0f, 1.0f, 0.0f, 1.0f);
					break;
				case 2:
					colors[cnt] = clan::Colorf(0.0f, 0.0f, 1.0f, 1.0f);
					break;
			}
		};

		canvas.flush();
		clan::GraphicContext gc = canvas.get_gc();

		canvas.set_blend_state(blend_state);

		clan::RasterizerStateDescription raster_state_desc;
		raster_state_desc.set_point_size(options->point_size);
		raster_state_desc.set_point_sprite_origin(clan::origin_upper_left);
		clan::RasterizerState raster_state(canvas, raster_state_desc);
		canvas.set_rasterizer_state(raster_state);

		clan::PrimitivesArray primarray(gc);

		clan::VertexArrayVector<clan::Vec2f> gpu_positions = clan::VertexArrayVector<clan::Vec2f>(gc, &positions[0], positions.size());
		clan::VertexArrayVector<clan::Colorf> gpu_colors = clan::VertexArrayVector<clan::Colorf>(gc, &colors[0], colors.size());

		primarray.set_attributes(0, gpu_positions);
		primarray.set_attributes(1, gpu_colors);

		ProgramUniforms buffer;
		buffer.cl_ModelViewProjectionMatrix = canvas.get_projection() * canvas.get_transform();
		clan::UniformVector<ProgramUniforms> uniform_vector(gc, &buffer, 1);
		gc.set_uniform_buffer(0, uniform_vector);

		gc.set_texture(0, texture_particle);
		gc.set_program_object(program_object);
		gc.draw_primitives(clan::type_points, num_particles, primarray);
		gc.reset_program_object();
		gc.reset_texture(0);

		gc.reset_blend_state();
		gc.reset_rasterizer_state();
	}

	window.flip(1);

	return !quit;
}
Example #5
0
// The start of the Application
int App::start(const std::vector<CL_String> &args)
{
	CL_OpenGLWindowDescription win_desc;
	//win_desc.set_version(3, 2, false);
	win_desc.set_allow_resize(true);
	win_desc.set_title("Point Sprite Example");
	win_desc.set_size(CL_Size( 800, 480 ), false);

	CL_DisplayWindow window(win_desc);
	CL_Slot slot_quit = window.sig_window_close().connect(this, &App::on_window_close);
	CL_Slot slot_input_up = (window.get_ic().get_keyboard()).sig_key_up().connect(this, &App::on_input_up);

	CL_String theme;
	if (CL_FileHelp::file_exists("../../../Resources/GUIThemeAero/theme.css"))
		theme = "../../../Resources/GUIThemeAero";
	else if (CL_FileHelp::file_exists("../../../Resources/GUIThemeBasic/theme.css"))
		theme = "../../../Resources/GUIThemeBasic";
	else
		throw CL_Exception("No themes found");

	CL_GUIWindowManagerTexture wm(window);
	CL_GUIManager gui(wm, theme);
	
	CL_GraphicContext gc = window.get_gc();

	// Deleted automatically by the GUI
	Options *options = new Options(gui, CL_Rect(0, 0, gc.get_size()));

	CL_Image image_grid(gc, "../Blend/Resources/grid.png");
	CL_Texture texture_particle(gc, "Resources/particle.png");
	float grid_width = (float) image_grid.get_width();
	float grid_height = (float) image_grid.get_height();

	grid_space = (float) (image_grid.get_width());

	setup_particles();

	CL_ShaderObject vertex_shader(gc, cl_shadertype_vertex, text_shader_vertex);
	if(!vertex_shader.compile())
	{
		throw CL_Exception(cl_format("Unable to compile vertex shader object: %1", vertex_shader.get_info_log()));
	}

	CL_ShaderObject fragment_shader(gc, cl_shadertype_fragment, text_shader_fragment);
	if(!fragment_shader.compile())
	{
		throw CL_Exception(cl_format("Unable to compile fragment shader object: %1", fragment_shader.get_info_log()));
	}

	CL_ProgramObject program_object(gc);
	program_object.attach(vertex_shader);
	program_object.attach(fragment_shader);
	program_object.bind_attribute_location(0, "InPosition");
	program_object.bind_attribute_location(1, "InColor");
	if (!program_object.link())
	{
		throw CL_Exception(cl_format("Unable to link program object: %1", program_object.get_info_log()));
	}

	options->request_repaint();

	unsigned int time_last = CL_System::get_time();

	while (!quit)
	{
		unsigned int time_now = CL_System::get_time();
		float time_diff = (float) (time_now - time_last);
		time_last = time_now;

		wm.process();
		wm.draw_windows(gc);

		int num_particles = options->num_particles;
		if (num_particles > max_particles)
			num_particles = max_particles;

		move_particles(time_diff, num_particles);

		const float grid_xpos = 10.0f;
		const float grid_ypos = 10.0f;

		// Draw the grid
		image_grid.draw(gc, grid_xpos, grid_ypos);

		if (num_particles > 0)
		{
			std::vector<CL_Vec2f> positions;
			std::vector<CL_Vec4f> colors;
			positions.resize(num_particles);
			colors.resize(num_particles);

			for (int cnt=0; cnt<num_particles; cnt++)
			{
				positions[cnt] = CL_Vec2f(grid_xpos + particles[cnt].xpos, grid_ypos + particles[cnt].ypos);
				switch (cnt % 3)
				{
					case 0:
						colors[cnt] = CL_Vec4f(1.0f, 0.0f, 0.0f, 1.0f);
						break;
					case 1:
						colors[cnt] = CL_Vec4f(0.0f, 1.0f, 0.0f, 1.0f);
						break;
					case 2:
						colors[cnt] = CL_Vec4f(0.0f, 0.0f, 1.0f, 1.0f);
						break;
				}
			};

			CL_BlendMode blend;
			blend.enable_blending(true);
			blend.set_blend_function(cl_blend_src_alpha, cl_blend_one, cl_blend_src_alpha, cl_blend_one);
			gc.set_blend_mode(blend);
			CL_Pen pen;
			pen.enable_point_sprite(true);
			pen.set_point_size(options->point_size);
			pen.set_point_sprite_origin(cl_point_sprite_origin_upper_left);
			gc.set_pen(pen);

			program_object.set_uniform1i("Texture0", 0);

			gc.set_texture(0, texture_particle);
			CL_PrimitivesArray prim_array(gc);
			prim_array.set_attributes(0, &positions[0]);
			prim_array.set_attributes(1, &colors[0]);
			gc.set_program_object(program_object);
			gc.draw_primitives(cl_points, num_particles, prim_array);
			gc.reset_program_object();
			gc.reset_texture(0);
			gc.reset_blend_mode();

			gc.reset_pen();
		}

		window.flip(1);

		CL_KeepAlive::process();
	}
	return 0;
}
Example #6
0
/*! This function finds the next synchronization point of the system (i.e. the
 *  earliest point of time any of the particles needs a force computation),
 *  and drifts the system to this point of time.  If the system drifts over
 *  the desired time of a snapshot file, the function will drift to this
 *  moment, generate an output, and then resume the drift.
 */
void find_next_sync_point_and_drift(void)
{
  int n, flag, *temp, i, nskip=20;
  long long int min_glob, min;
  double timeold;
  double t0, t1;
  int task_max, loc_max, tot_loc_max, list_loc_max[NTask], n_check;
  double hubble_a, dt_raytrace=0, nh_local, nh_max, tot_nh_max, mass_max, tot_mass_max, ray_dist2, list_nh_max[NTask], list_mass_max[NTask];
#ifdef RAYTRACE_TG
  double nu_min_H = 3.3e15;
  double nu_min_He = 1.32e16;
  double c_s = 16.5967; //soundspeed of 20,000K gas in km/s
#endif

  if (All.ComovingIntegrationOn) { /* comoving variables */
    hubble_a = All.Omega0 / (All.Time * All.Time * All.Time)
	+ (1 - All.Omega0 - All.OmegaLambda) / (All.Time * All.Time) 
        + All.OmegaLambda;
    hubble_a = All.Hubble * All.HubbleParam * sqrt(hubble_a);
  }
  else hubble_a = 1.0;

  t0 = second();

  timeold = All.Time;

  /*SINK - must skip any accreted particles at the beginning of the SPH particle list*/
  for(i = 0; i < NumPart; i++)
    {
      if(P[i].Type == 5 || P[i].ID >= 0)
	break;
    }


  if(i == NumPart)
    min = INT_MAX;
  else
    {
      for(n = i+1, min = P[i].Ti_endstep; n < NumPart; n++)
	{
	  if(P[n].Type == 0 && P[n].ID < 0) /*SINK*/
	    continue;

          if(min > P[n].Ti_endstep)
            min = P[n].Ti_endstep;
	}
    } 

  MPI_Allreduce(&min, &min_glob, 1, MPI_LONG, MPI_MIN, MPI_COMM_WORLD);

  /* We check whether this is a full step where all particles are synchronized */
  flag = 1;
  for(n = 0; n < NumPart; n++)
    {
      if(P[n].Type == 0 && P[n].ID < 0) /*SINK*/
	continue;
      if(P[n].Ti_endstep > min_glob)
        flag = 0;
    }

  MPI_Allreduce(&flag, &Flag_FullStep, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);

#ifdef PMGRID
  if(min_glob >= All.PM_Ti_endstep)
    {
      min_glob = All.PM_Ti_endstep;
      Flag_FullStep = 1;
    }
#endif

  /* Determine 'NumForceUpdate', i.e. the number of particles on this processor that are going to be active */
  for(n = 0, NumForceUpdate = 0; n < NumPart; n++)
    {
      if(P[n].Type == 0 && P[n].ID < 0) /*SINK*/
	continue;
      if(P[n].Ti_endstep == min_glob)
#ifdef SELECTIVE_NO_GRAVITY
        if(!((1 << P[n].Type) & (SELECTIVE_NO_GRAVITY)))
#endif
          NumForceUpdate++;
    }

  /* note: NumForcesSinceLastDomainDecomp has type "long long" */
  temp = malloc(NTask * sizeof(int));
  MPI_Allgather(&NumForceUpdate, 1, MPI_INT, temp, 1, MPI_INT, MPI_COMM_WORLD);
  for(n = 0; n < NTask; n++)
    All.NumForcesSinceLastDomainDecomp += temp[n];
  free(temp);

  t1 = second();

  All.CPU_Predict += timediff(t0, t1);

  tot_nh_max = nh_max = nh_local = tot_mass_max = mass_max = tot_loc_max = loc_max = task_max = 0;

  for(n = 0; n < NTask; n++)
    list_nh_max[n] = list_mass_max[n] = list_loc_max[n] = 0;

  for(i = 0; i < N_gas; i++)
    if(P[i].ID > 0 /*&& P[i].Mass / All.HubbleParam * 1.0e10 < All.RefinementMass*/)
      {
        nh_local = SphP[i].Density*All.UnitDensity_in_cgs*All.HubbleParam*All.HubbleParam/All.Time/All.Time/All.Time*HYDROGEN_MASSFRAC/PROTONMASS;

        //if(nh_local > nh_max)
        if(P[i].ID == 2931027)
          {
            nh_max = nh_local;
            mass_max = P[i].Mass;
            loc_max = i;
          }
      }

  MPI_Allgather(&nh_max, 1, MPI_DOUBLE, &list_nh_max, 1, MPI_DOUBLE, MPI_COMM_WORLD);

  MPI_Allgather(&mass_max, 1, MPI_DOUBLE, &list_mass_max, 1, MPI_DOUBLE, MPI_COMM_WORLD);

  MPI_Allgather(&loc_max, 1, MPI_INT, &list_loc_max, 1, MPI_INT, MPI_COMM_WORLD);

  for(n = 0; n < NTask; n++)
    if(list_nh_max[n] > tot_nh_max)
      {
        tot_nh_max = list_nh_max[n];
        tot_mass_max = list_mass_max[n];
        tot_loc_max = list_loc_max[n];
        task_max = n;
      }

    dt_raytrace = fmax(fmax((min_glob - All.Time_last) * All.Timebase_interval, All.MinSizeTimestep), All.Timebase_interval) / hubble_a * All.UnitTime_in_s;
    All.t_s = All.t_s + dt_raytrace;   //time in seconds
    All.r_s = All.x_s * c_s * All.t_s / 3.08568025e16 / All.Time * All.HubbleParam;     //shock radius in km (converted to comoving kpc)
    All.n_s = All.alpha0/(4.0*3.14159*6.67e-8*pow(All.t_s,2))*HYDROGEN_MASSFRAC/PROTONMASS;
    All.n_sink =  All.alpha0/(4.0*3.14159*6.67e-8*pow((All.tacc - 300.*3.e7),2))*HYDROGEN_MASSFRAC/PROTONMASS;
    //All.n_sink = 1.e-1;

    All.Time_last = min_glob;

#ifdef RAYTRACE_TG
  if(ThisTask == task_max)
    ray_dist2 = (P[tot_loc_max].Pos[0] - All.BoxSize / 2.0) * (P[tot_loc_max].Pos[0] - All.BoxSize / 2.0) + (P[tot_loc_max].Pos[1] - All.BoxSize / 2.0) * (P[tot_loc_max].Pos[1] - All.BoxSize / 2.0) + (P[tot_loc_max].Pos[2] - All.BoxSize / 2.0) * (P[tot_loc_max].Pos[2] - All.BoxSize / 2.0);

  MPI_Bcast(&ray_dist2, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);

  if(ThisTask == task_max)
    {
    if(All.NumCurrentTiStep % 100 == 0) 
      printf("Densest particle (ID %d) with nh = %g at x = %g, y = %g, z = %g and mass %g\n", P[tot_loc_max].ID, tot_nh_max, P[tot_loc_max].Pos[0], P[tot_loc_max].Pos[1], P[tot_loc_max].Pos[2], P[tot_loc_max].Mass / All.HubbleParam * 1.0e10);
    for(n = 0; n < N_gas; n++)
      if(P[n].ID == P[tot_loc_max].ID)          //center ray at most dense particle
          {
           All.star_mass = P[n].Mass/All.HubbleParam/1.e-10;           //sink mass in solar masses
           printf("star_mass =%lg\n", All.star_mass);
           //All.star_mass = 1.e-5;
           //All.star_mass = 0;
           //All.star_mass = 2.e1;
           }
   
     n_check = 140740; 
     if(All.NumCurrentTiStep == 0)
       {
       //All.mdot= 0.095*pow(All.star_mass, -0.814);
       All.numtot = 155639;
       All.alpha = alpha_calc(n_check);
       All.mdot = mdot_calc(All.numtot);
       //All.mdot = 1.e-7;
       //All.mdot = 1.e6;
       } 

     All.flag_sink = 0;
     if(All.NumCurrentTiStep == 10 || All.NumCurrentTiStep == 1000 || All.t_s - All.t_s0 > 3.e7)
       {
       All.alpha = alpha_calc(n_check);
       All.mdot = mdot_calc(All.numtot);
       //All.mdot= 1.e-7;
       //All.mdot= 1.e6;
       All.numtot = All.numtot + All.sink_number_global;
       All.t_s0 = All.t_s;
       All.flag_sink = 1;
       printf("All.numtot = %d, All.t_s0_sink = %lg, All.t_s0 = %lg\n", All.numtot, All.t_s0_sink, All.t_s0);
       }


     if(All.NumCurrentTiStep < 1)
       All.lum_tot = lum_calc(1, All.star_mass, All.mdot, nu_min_H, 1.e-5);

     if(All.NumCurrentTiStep % 100 == 0) 
       printf("run lum_tot = %lg, Teff = %lg, mdot = %lg\n", All.lum_tot, All.Teff, All.mdot);

     if(All.ray_flag_sun == 3)
        {
        for(i=0; i<=6; i++)
           {
           All.heat_ion[i] = heat_ion_rates(i, All.lum_tot, All.Teff);
           COOLR.heat_ion[i] = All.heat_ion[i];
           if(All.NumCurrentTiStep % 10000 == 0)
             printf("heat_ion %d = %lg\n", i, COOLR.heat_ion[i]);
           }
         }
      }

      MPI_Bcast(&All.star_mass, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.star_rad, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.alpha, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.numtot, 1, MPI_INT, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.mdot, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.t_s0, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.flag_sink, 1, MPI_INT, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.tacc, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&COOLR.heat_ion, 7, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      
//make sure ray doesn't go outside of box (?)


//ARS adding condition that the LW radiation actually needs to be significant before computation time will be spent on the ray-tracing)

  if(tot_nh_max >= 0.99*All.ray_crit_dens && ray.flag_continue == 0 && ray_dist2 < All.ray_r_max_sink * All.ray_r_max_sink)
    {
      ray.flag_start = 1;

      if(ThisTask == task_max)
        All.ray_center_ID = P[tot_loc_max].ID;

      MPI_Bcast(&All.ray_center_ID, 1, MPI_INT, task_max, MPI_COMM_WORLD);

      if(ThisTask == task_max && All.NumCurrentTiStep % 1000 == 0)
        printf("Found starp (ID %d) at x = %g, y = %g, z = %g with mass %g\n", P[tot_loc_max].ID, P[tot_loc_max].Pos[0], P[tot_loc_max].Pos[1], P[tot_loc_max].Pos[2], P[tot_loc_max].Mass / All.HubbleParam * 1.0e10);

    }

  // ARS asks why we cannot have a SINK be a star particle (starp)?
  if(tot_nh_max >  0.99*All.SinkCriticalDens && ray_dist2 < All.ray_r_max_sink * All.ray_r_max_sink)
    {
      if(ThisTask == task_max && All.NumCurrentTiStep % 100 == 0)
        printf("Problem! A sink instead of a starp will form (ID %d) at x = %g, y = %g, z = %g with mass %g! Aborting...\n", P[tot_loc_max].ID, P[tot_loc_max].Pos[0], P[tot_loc_max].Pos[1], P[tot_loc_max].Pos[2], P[tot_loc_max].Mass / All.HubbleParam * 1.0e10);

      //exit(0);
    }


  if(All.lum_tot < 1.e36 || All.star_mass < 1.0)
    {
    nskip = 100;
    if(ThisTask == 0 && All.NumCurrentTiStep % 100 == 0)
     printf("Let's not ray trace quite so often\n");
    }

  if(ray.flag_start == 1 && ray.flag_continue == 0 || (ray.flag_start == 1 && All.NumCurrentTiStep % nskip == 0) || (ray.flag_start == 1 && All.t_s - All.t_s0_acc > 3.e5) || All.NumCurrentTiStep < 2)  //ARS asks: Where should the parentheses go?
    {
      All.t_s0_acc = All.t_s;
      if(ThisTask == 0)
        printf("Imma gonna ray trace so there.\n");
      if(ray.flag_start == 1 && ray.flag_continue == 0)
        {
          All.Time_last_raytrace = All.Time;

          dt_raytrace = fmax(All.Timebase_interval, All.MinSizeTimestep) / hubble_a * All.UnitTime_in_s;
        }
      else
        dt_raytrace = fmax(fmax((min_glob - All.Time_last_raytrace) * All.Timebase_interval, All.MinSizeTimestep), All.Timebase_interval) / hubble_a * All.UnitTime_in_s;

      if(ThisTask == task_max)
        {
        ray.Q_H_ion =  lum_calc(0, All.star_mass, All.mdot, nu_min_H, dt_raytrace);
        ray.Q_He_ion = lum_calc(0, All.star_mass, All.mdot, nu_min_He, dt_raytrace);
        All.Q_LW =     lum_calc(4, All.star_mass, All.mdot, nu_min_H, dt_raytrace); 
        All.lum_tot =  lum_calc(1, All.star_mass, All.mdot, nu_min_H, dt_raytrace);
        }

      MPI_Bcast(&ray.Q_H_ion, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&ray.Q_He_ion, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.lum_tot, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);
      MPI_Bcast(&All.Teff, 1, MPI_DOUBLE, task_max, MPI_COMM_WORLD);

      All.r_s = All.x_s * c_s * All.t_s / 3.08568025e16 / All.Time * All.HubbleParam;     //shock radius in km (converted to comoving kpc)
      All.n_s = All.alpha0/(4.0*3.14159*6.67e-8*pow(All.t_s,2))*HYDROGEN_MASSFRAC/PROTONMASS;
      All.n_sink =  All.alpha0/(4.0*3.14159*6.67e-8*pow((All.tacc - 300.*3.e7),2))*HYDROGEN_MASSFRAC/PROTONMASS;
      All.n_hii = All.alpha0/(4.0*3.14159*6.67e-8*pow((All.tacc - 1600.*3.e7),2))*HYDROGEN_MASSFRAC/PROTONMASS;
      if(All.n_hii < 2.35e6) All.n_hii = 2.35e6;
      //All.n_hii = 1.e3;

      if(ThisTask == 0)
        printf("t_s = %lg, tacc = %lg, r_s = %lg, n_s = %lg n_sink = %lg, n_hii = %lg\n", All.t_s, All.tacc, All.r_s, All.n_s, All.n_sink, All.n_hii);

      //if(All.lum_tot > 0.0)
      raytrace_TG(dt_raytrace);

      All.Time_last_raytrace = min_glob;
    }
#endif


  while(min_glob >= All.Ti_nextoutput && All.Ti_nextoutput >= 0)
    {
#ifdef CHEMCOOL
      All.NeedAbundancesForOutput = 1;
#endif
      move_particles(All.Ti_Current, All.Ti_nextoutput);

      All.Ti_Current = All.Ti_nextoutput;

      if(All.ComovingIntegrationOn)
	All.Time = All.TimeBegin * exp(All.Ti_Current * All.Timebase_interval);
      else
	All.Time = All.TimeBegin + All.Ti_Current * All.Timebase_interval;

#ifdef OUTPUTPOTENTIAL
      All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency;
      domain_Decomposition();
      compute_potential();
#endif
      if(All.NumCurrentTiStep > 20)
        savepositions(All.SnapshotFileCount++);	/* write snapshot file */
#ifdef CHEMCOOL
      All.NeedAbundancesForOutput = 0;
#endif

      All.Ti_nextoutput = find_next_outputtime(All.Ti_nextoutput + 1);
#ifdef CHEMCOOL
      All.Ti_nextnextoutput = find_next_outputtime(All.Ti_nextoutput + 1);
#endif
    }

  move_particles(All.Ti_Current, min_glob);

  All.Ti_Current = min_glob;

  if(All.ComovingIntegrationOn)
    All.Time = All.TimeBegin * exp(All.Ti_Current * All.Timebase_interval);
  else
    All.Time = All.TimeBegin + All.Ti_Current * All.Timebase_interval;

  All.TimeStep = All.Time - timeold;
}
Example #7
0
/*! This function finds the next synchronization point of the system (i.e. the
 *  earliest point of time any of the particles needs a force computation),
 *  and drifts the system to this point of time.  If the system drifts over
 *  the desired time of a snapshot file, the function will drift to this
 *  moment, generate an output, and then resume the drift.
 */
void find_next_sync_point_and_drift(void)
{
  int n, min, min_glob, flag, *temp;
  double timeold;
  double t0, t1;

  t0 = second();

  timeold = All.Time;

  for(n = 1, min = P[0].Ti_endstep; n < NumPart; n++)
    if(min > P[n].Ti_endstep)
      min = P[n].Ti_endstep;

  MPI_Allreduce(&min, &min_glob, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);

  /* We check whether this is a full step where all particles are synchronized */
  flag = 1;
  for(n = 0; n < NumPart; n++)
    if(P[n].Ti_endstep > min_glob)
      flag = 0;

  MPI_Allreduce(&flag, &Flag_FullStep, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);

#ifdef PMGRID
  if(min_glob >= All.PM_Ti_endstep)
    {
      min_glob = All.PM_Ti_endstep;
      Flag_FullStep = 1;
    }
#endif

  /* Determine 'NumForceUpdate', i.e. the number of particles on this processor that are going to be active */
  for(n = 0, NumForceUpdate = 0; n < NumPart; n++)
    {
      if(P[n].Ti_endstep == min_glob)
#ifdef SELECTIVE_NO_GRAVITY
        if(!((1 << P[n].Type) & (SELECTIVE_NO_GRAVITY)))
#endif
          NumForceUpdate++;
    }

  /* note: NumForcesSinceLastDomainDecomp has type "long long" */
  temp = malloc(NTask * sizeof(int));
  MPI_Allgather(&NumForceUpdate, 1, MPI_INT, temp, 1, MPI_INT, MPI_COMM_WORLD);
  for(n = 0; n < NTask; n++)
    All.NumForcesSinceLastDomainDecomp += temp[n];
  free(temp);



  t1 = second();

  All.CPU_Predict += timediff(t0, t1);

  while(min_glob >= All.Ti_nextoutput && All.Ti_nextoutput >= 0)
    {
      move_particles(All.Ti_Current, All.Ti_nextoutput);

      All.Ti_Current = All.Ti_nextoutput;

      if(All.ComovingIntegrationOn)
	All.Time = All.TimeBegin * exp(All.Ti_Current * All.Timebase_interval);
      else
	All.Time = All.TimeBegin + All.Ti_Current * All.Timebase_interval;

#ifdef OUTPUTPOTENTIAL
      All.NumForcesSinceLastDomainDecomp = 1 + All.TotNumPart * All.TreeDomainUpdateFrequency;
      domain_Decomposition();
      compute_potential();
#endif
      savepositions(All.SnapshotFileCount++);	/* write snapshot file */

      All.Ti_nextoutput = find_next_outputtime(All.Ti_nextoutput + 1);
    }

  move_particles(All.Ti_Current, min_glob);

  All.Ti_Current = min_glob;

  if(All.ComovingIntegrationOn)
    All.Time = All.TimeBegin * exp(All.Ti_Current * All.Timebase_interval);
  else
    All.Time = All.TimeBegin + All.Ti_Current * All.Timebase_interval;

  All.TimeStep = All.Time - timeold;
}