Example #1
0
int exec_loop(solver_props *props){
  int i;
  int status = SUCCESS;

  // Initialize solvers for all iterators
# if defined TARGET_GPU
  gpu_init();
# endif
  for(i=0;i<NUM_ITERATORS;i++){
    solver_init(&props[i]);
  }

  // Execute the model(s) on the appropriate target
#if defined(TARGET_CPU)
  status = exec_cpu(props, 0);
#elif defined(TARGET_OPENMP)
  status = exec_parallel_cpu(props);
#elif defined(TARGET_GPU)
  status = exec_parallel_gpu(props);
#else
#error Invalid target
#endif

  // Free solvers for all iterators
  for(i=0;i<NUM_ITERATORS;i++){
    solver_free(&props[i]);
  }
# if defined TARGET_GPU
  gpu_exit();
# endif

  return status;
}
Example #2
0
int exec_loop(solver_props *props, const char *outputs_dirname, double *progress, int resuming){
  int i;
  int status = SUCCESS;

  // Initialize solvers for all iterators
  for(i=0;i<NUM_ITERATORS;i++){
    solver_init(&props[i]);
  }

  // Copy the state of the PRNG
  random_copy_state_to_device();

  // Execute the model(s) on the appropriate target
#if defined(TARGET_CPU)
  status = exec_cpu(props, outputs_dirname, progress, 0, resuming);
#elif defined(TARGET_OPENMP)
  status = exec_parallel_cpu(props, outputs_dirname, progress, resuming);
#elif defined(TARGET_GPU)
  status = exec_parallel_gpu(props, outputs_dirname, progress, resuming);
#else
#error Invalid target
#endif

  random_copy_state_from_device();

  // Free solvers for all iterators
  for(i=0;i<NUM_ITERATORS;i++){
    solver_free(&props[i]);
  }
# if defined TARGET_GPU
  gpu_exit();
# endif

  return status;
}
Example #3
0
File: driver.c Project: tuxfan/ska
int main(int argc, char *argv[])
{
	PetscErrorCode ierr;
	int i;
	grid *grd;

	MPI_Init(&argc,&argv);

	option options = parse_options(argc, argv);

	if (options.problem == JUMP) {
		grd = grid_create(-1, 1, options.nx,
		                  -1, 1, options.ny,
		                  -1, 1, options.nz);
	} else {
		grd = grid_create(0, 1, options.nx,
		                  0, 1, options.ny,
		                  0, 1, options.nz);
	}
	if (options.periodic > -1) grd->periodic[options.periodic] = 1;
	int rank;
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
	if (rank == 0) print_intro(&options);

	map *mp = map_create(options.map);
	grid_apply_map(grd, mp);

	problem *pb = problem_create(options.problem, grd->nd, mp->id);
	solver *sol = solver_create(grd, pb);

	ierr = solver_init(sol, grd);CHKERRQ(ierr);
	ierr = solver_run(sol);CHKERRQ(ierr);

	double *u = (double*) malloc(grd->num_pts*sizeof(double));
	double *diff = (double*) malloc(grd->num_pts*sizeof(double));
	grid_eval(grd, pb->sol, u);

	for (i = 0; i < grd->num_pts; i++)
		diff[i] = sol->state->phi[i] - u[i];

	print_norm(diff, grd->num_pts);

	free(u); free(diff);
	grid_destroy(grd); free(grd);
	map_destroy(mp); free(mp);
	problem_destroy(pb); free(pb);
	ierr = solver_destroy(sol);CHKERRQ(ierr); free(sol);

	if (options.eig && rank == 0) {
		system("./python/plot.py");
	}

	MPI_Finalize();

	return 0;
}
Example #4
0
int
main(int argc, char *argv[])
{ 
    if (argc != 2) {
        fprintf(stderr, "Expected 2 arguments\n");
        exit(1);
    }
    char *fname = argv[1];

    Solver solver;
    solver_init(&solver);

    printf("reading %s\n", fname);
    solver_read_file(&solver, fname);

    const bool solution_found = solver_naive(&solver);
    if (solution_found) {
        print_values(solver.values, solver.n_variables);
    }
    write_results(&solver, solution_found);

    solver_destroy(&solver);
}
Example #5
0
// This is a cheesy function that is not meant to go inside an inner loop.
// It is OK for one-off solving of 'plan b' puzzles,
// but for inner loops all of the structures should be created
// and initialized outside of the loop.
int solve_potential_bond_graph(
    const int *row_ptr, const int *col_ind, int nvertices, int k,
    int *binary_solution, int *pbest_score)
{
  int failflag = 0;

  int max_nvertices = nvertices;
  int max_ncomponents = nvertices;
  int max_target = nvertices;
  int max_nedges_undirected = nvertices + 1;
  int max_nedges_directed = max_nedges_undirected * 2;

  // Breadth first search, girth, and cycle allocation and initialization.
  BFS_WS bfs_ws;
  bfs_ws_init(&bfs_ws, nvertices);
  int *depth_ws = (int *) malloc(nvertices * sizeof(int));
  int *va_trace = (int *) malloc(nvertices * sizeof(int));
  int *vb_trace = (int *) malloc(nvertices * sizeof(int));

  int i, v;

  // Clear parent and depth arrays for girth and cycle related functions.
  for (v=0; v<nvertices; ++v) {
    bfs_ws.parent[v] = -1;
    depth_ws[v] = -1;
  }

  // Prepare to decompose the graph into connected components.
  int *component_labels = (int *) malloc(nvertices * sizeof(int));
  for (v=0; v<nvertices; ++v) {
    component_labels[v] = -1;
  }

  // Compute the connected components.
  CCGRAPH g;
  ccgraph_init(&g, max_nvertices, max_nedges_directed);
  ccgraph_compute(&g, row_ptr, col_ind, nvertices, &bfs_ws, component_labels);

  // Get the number of connected components that have cycles.
  // The purpose is to limit the size of the dynamic programming table
  // that is preallocated for solving the subset sum problem.
  int cyclic_component_count = 0;
  int c;
  for (c=0; c<g.ncomponents; ++c)
  {
    int component_nedges_undirected = ccgraph_get_component_nedges_undirected(
        &g, c);
    int component_nvertices = ccgraph_get_component_nvertices(
        &g, c);
    if (component_nedges_undirected >= component_nvertices) {
      cyclic_component_count++;
    }
  }

  // Initialize the subset sum solver workspaces.
  int *high = (int *) malloc(max_target * sizeof(int));
  int *low = (int *) malloc(max_target * sizeof(int));
  int *s3solution = (int *) malloc(cyclic_component_count * sizeof(int));
  S3TABLE s3table;
  s3table_init(&s3table, cyclic_component_count, max_target);
  s3table_clear(&s3table, cyclic_component_count, max_target);

  // Init the densest k-subgraph solver.
  SOLVER solver;
  solver_init(&solver, max_nvertices, max_ncomponents);

  // Get the densest k-subgraph.
  solver_toplevel(&solver,
      row_ptr, col_ind, &g, k,
      va_trace, vb_trace,
      &bfs_ws, depth_ws,
      &s3table, low, high, s3solution);

  // Require that the solution is complete.
  if (solver.nsolution != k) {
    print_csr_graph(row_ptr, col_ind, nvertices);
    assert(false);
  }

  // Fill the output values.
  memset(binary_solution, 0, nvertices * sizeof(int));
  for (i=0; i<solver.nsolution; ++i) {
    v = solver.solution[i];
    binary_solution[v] = 1;
  }
  *pbest_score = solver.score;

  // Free the memory.
  bfs_ws_destroy(&bfs_ws);
  ccgraph_destroy(&g);
  s3table_destroy(&s3table);
  solver_destroy(&solver);
  free(high);
  free(low);
  free(s3solution);
  free(component_labels);
  free(va_trace);
  free(vb_trace);
  free(depth_ws);

  return failflag;
}
Example #6
0
int run_simulation(struct simulation *sim)
{
struct device cell;
log_clear(sim);

printf_log(sim,_("Run_simulation\n"));

device_init(&cell);
cell.onlypos=FALSE;

dump_init(sim,&cell);

set_dump_status(sim,dump_stop_plot, FALSE);
set_dump_status(sim,dump_print_text, TRUE);


char temp[1000];

cell.kl_in_newton=FALSE;

//if (strcmp(outputpath,"")!=0) strcpy(get_output_path(sim),outputpath);

//if (strcmp(inputpath,"")!=0) strcpy(get_input_path(sim),inputpath);

dump_load_config(sim,&cell);

int i;
int z;
int x;
int y;


join_path(2,temp,get_output_path(sim),"error.dat");
remove(temp);

join_path(2,temp,get_output_path(sim),"equilibrium");
remove_dir(sim,temp);

join_path(2,temp,get_output_path(sim),"snapshots");
remove_dir(sim,temp);

join_path(2,temp,get_output_path(sim),"light_dump");
remove_dir(sim,temp);

join_path(2,temp,get_output_path(sim),"dynamic");
remove_dir(sim,temp);

join_path(2,temp,get_output_path(sim),"frequency");
remove_dir(sim,temp);



load_config(sim,&cell);

if (strcmp(sim->force_sim_mode,"")!=0)
{
	strcpy(cell.simmode,sim->force_sim_mode);
}

if (strcmp(cell.simmode,"opticalmodel@optics")!=0)
{
	solver_init(sim,cell.solver_name);
	newton_init(sim,cell.newton_name);

	printf_log(sim,_("Loading DoS for %d layers\n"),cell.my_epitaxy.electrical_layers);
	char tempn[100];
	char tempp[100];
	i=0;

	for (i=0;i<cell.my_epitaxy.electrical_layers;i++)
	{
		dos_init(&cell,i);
		printf_log(sim,"Load DoS %d/%d\n",i,cell.my_epitaxy.electrical_layers);
		sprintf(tempn,"%s_dosn.dat",cell.my_epitaxy.dos_file[i]);
		sprintf(tempp,"%s_dosp.dat",cell.my_epitaxy.dos_file[i]);
		load_dos(sim,&cell,tempn,tempp,i);
	}

	device_alloc_traps(&cell);

	if (get_dump_status(sim,dump_write_converge)==TRUE)
	{
	sim->converge = fopena(get_output_path(sim),"converge.dat","w");
	fclose(sim->converge);

	sim->tconverge=fopena(get_output_path(sim),"tconverge.dat","w");
	fclose(sim->tconverge);
	}

	mesh_cal_layer_widths(&cell);

	long double depth=0.0;
	long double percent=0.0;
	long double value=0.0;
	for (z=0;z<cell.zmeshpoints;z++)
	{
		for (x=0;x<cell.xmeshpoints;x++)
		{
			for (y=0;y<cell.ymeshpoints;y++)
			{

				depth=cell.ymesh[y]-cell.layer_start[cell.imat[z][x][y]];
				percent=depth/cell.layer_width[cell.imat[z][x][y]];
				cell.Nad[z][x][y]=get_dos_doping_start(&cell,cell.imat[z][x][y])+(get_dos_doping_stop(&cell,cell.imat[z][x][y])-get_dos_doping_start(&cell,cell.imat[z][x][y]))*percent;
			}
		}		
		
	}

	init_mat_arrays(&cell);




	for (z=0;z<cell.zmeshpoints;z++)
	{
		for (x=0;x<cell.xmeshpoints;x++)
		{
			for (y=0;y<cell.ymeshpoints;y++)
			{
				cell.phi[z][x][y]=0.0;
				cell.R[z][x][y]=0.0;
				cell.n[z][x][y]=0.0;
			}
		}
	}

	contacts_load(sim,&cell);

	cell.C=cell.xlen*cell.zlen*epsilon0*cell.epsilonr[0][0][0]/(cell.ylen+cell.other_layers);
	if (get_dump_status(sim,dump_print_text)==TRUE) printf_log(sim,"C=%Le\n",cell.C);
	cell.A=cell.xlen*cell.zlen;
	cell.Vol=cell.xlen*cell.zlen*cell.ylen;

	///////////////////////light model
	char old_model[100];
	gdouble old_Psun=0.0;
	old_Psun=light_get_sun(&cell.mylight);
	light_init(&cell.mylight);
	light_set_dx(&cell.mylight,cell.ymesh[1]-cell.ymesh[0]);
	light_load_config(sim,&cell.mylight);

	if (cell.led_on==TRUE)
	{
		strcpy(old_model,cell.mylight.mode);
		strcpy(cell.mylight.mode,"ray");
	}
	
	light_load_dlls(sim,&cell.mylight);
	light_setup_ray(sim,&cell,&cell.mylight);

	if (cell.led_on==TRUE)
	{
		cell.mylight.force_update=TRUE;

		light_set_sun(&(cell.mylight),1.0);
		light_set_sun_delta_at_wavelength(&(cell.mylight),cell.led_wavelength);
		light_solve_all(sim,&(cell.mylight));
		
		cell.mylight.force_update=FALSE;
		strcpy(cell.mylight.mode,old_model);
		light_set_sun(&(cell.mylight),old_Psun);
		light_free_dlls(sim,&cell.mylight);
		light_load_dlls(sim,&cell.mylight);
	}
	///////////////////////

	//update_arrays(&cell);

	contact_set_all_voltages(sim,&cell,0.0);
	get_initial(sim,&cell);

	remesh_shrink(&cell);

	if (cell.math_enable_pos_solver==TRUE)
	{
		for (z=0;z<cell.zmeshpoints;z++)
		{
			for (x=0;x<cell.xmeshpoints;x++)
			{
				solve_pos(sim,&cell,z,x);
			}
		}
	}


	time_init(sim,&cell);

	cell.N=0;
	cell.M=0;

	solver_realloc(sim,&cell);



	plot_open(sim);


	cell.go_time=FALSE;

	plot_now(sim,"plot");
	//set_solver_dump_every_matrix(1);

	find_n0(sim,&cell);
	//set_solver_dump_every_matrix(0);
	draw_gaus(&cell);


	if (cell.onlypos==TRUE)
	{
		join_path(2,temp,get_output_path(sim),"equilibrium");
		dump_1d_slice(sim,&cell,temp);
		device_free(sim,&cell);
		device_free_traps(&cell);
		mesh_free(sim,&cell);
		return 0;
	}
}


//Load the dll
if (is_domain(cell.simmode)!=0)
{
	char gussed_full_mode[200];
	if (guess_whole_sim_name(sim,gussed_full_mode,get_input_path(sim),cell.simmode)==0)
	{
		printf_log(sim,"I guess we are using running %s\n",gussed_full_mode);
		strcpy(cell.simmode,gussed_full_mode);
	}else
	{
		ewe(sim,"I could not guess which simulation to run from the mode %s\n",cell.simmode);
	}


}

run_electrical_dll(sim,&cell,strextract_domain(cell.simmode));


if (strcmp(cell.simmode,"opticalmodel@optics")!=0)
{
	device_free(sim,&cell);
	device_free_traps(&cell);
	mesh_free(sim,&cell);
	plot_close(sim);

	for (i=0;i<cell.my_epitaxy.electrical_layers;i++)
	{
		dos_free(&cell,i);
	}
	solver_free_memory(sim,&cell);

	newton_interface_free(sim);
	light_free(sim,&cell.mylight);
}



return cell.odes;
}
Example #7
0
int
full_solve (hid_t fid, hid_t dataset, hid_t* routeDatasets, hid_t dataspace, hid_t routeDataspace, hid_t datatype, hid_t routeDatatype, int cell_index, const inp_t * input_params, SOURCE_MODE mode,
            const cell_table_t * cell, const net_t * network, const time_steps_t * ts,
            int verbose)
{

  double *abundances = NULL;
  alloc_abundances( network, &abundances ); // Allocate the abundances array; it contains all species.

  rout_t* routes = NULL;
  if (( routes =
        malloc (sizeof (rout_t) *  input_params->output.n_output_species * N_OUTPUT_ROUTES)) == NULL)
    {
      fprintf (stderr, "astrochem: %s:%d: routes allocation failed.\n",
               __FILE__, __LINE__);
      return EXIT_SUCCESS;
    }

  double* output_abundances = NULL;
  if (( output_abundances =
        malloc (sizeof (double) * input_params->output.n_output_species )) == NULL)
    {
      fprintf (stderr, "astrochem: %s:%d: array allocation failed.\n",
               __FILE__, __LINE__);
      return EXIT_FAILURE;
    }

#ifdef HAVE_OPENMP
              omp_set_lock(&lock);
#endif


  // Create the memory dataspace, selecting all output abundances
  hsize_t size = input_params->output.n_output_species;
  hid_t memDataspace = H5Screate_simple(1, &size, NULL);

  // Create the file dataspace, and prepare selection of a chunk of the file
  hid_t fileDataspace = H5Scopy(dataspace);
  hsize_t     count[3]={  1, 1,  input_params->output.n_output_species };

  hsize_t routeSize[2] = { input_params->output.n_output_species, N_OUTPUT_ROUTES };
  hsize_t     routeCount[4]={  1, 1,  input_params->output.n_output_species, N_OUTPUT_ROUTES };
  hid_t routeFileDataspace, routeMemDataspace;
  if (input_params->output.trace_routes)
    {
      // Create the route memory dataspace, selecting all output routes
      routeMemDataspace = H5Screate_simple(2, routeSize, NULL);
      // Create the route file dataspace, and prepare selection of a chunk of the file
      routeFileDataspace = H5Scopy(routeDataspace);
    }

#ifdef HAVE_OPENMP
              omp_unset_lock(&lock);
#endif


  // Initializing abundance
#if 0 //Ultra complicated code
  const species_name_t* species = malloc( input_params->abundances.n_initial_abundances * sizeof(*species));
  double *initial_abundances = malloc( input_params->abundances.n_initial_abundances * sizeof(double) );

  int i;
  for( i = 0; i <  input_params->abundances.n_initial_abundances ; i++ )
    {
      strcpy( network->species_names[input_params->abundances.initial_abundances[i].species_idx ] , species[i] );
      initial_abundances[i] = input_params->abundances.initial_abundances[i].abundance;
    }
  set_initial_abundances( species, 3, initial_abundances, &network, abundances); // Set initial abundances
#else // same thing , without using api
  int i;
  for( i = 0; i <  input_params->abundances.n_initial_abundances ; i++ )
    {
      abundances[ input_params->abundances.initial_abundances[i].species_idx ] = input_params->abundances.initial_abundances[i].abundance;
    }
    
    // Add grain abundances
    int g, gm, gp;
    double gabs;
    g = find_species ("grain", network);
    gm = find_species ("grain(-)", network);
    gp = find_species ("grain(+)", network);
    
    // Check if grain abundances have already been initialized one way or another
    gabs=0.0;
    if(g>=0) gabs += abundances[ g ];
    if(gm>=0) gabs += abundances[ gm ];
    if(gp>=0) gabs += abundances[ gp ];
    
    if(gabs == 0.0) {
    	// Grains have not been initialized
    	// Check that grains are defined in our network, and if so, set the grain abundance
    	if(g>=0)
    		abundances[ g ] = input_params->phys.grain_abundance;
    }
#endif


  double min_nh;                 /* Minimum density */

  /* Compute the minimum density to set the absolute tolerance of the
     solver */
  min_nh = cell->nh[0];
  if (mode == DYNAMIC)
    {
      int i;

      for (i = 1; i < ts->n_time_steps; i++)
        {
          if (cell->nh[i] < min_nh)
            {
              min_nh = cell->nh[i];
            }
        }
    }

  astrochem_mem_t astrochem_mem;
  cell_t cell_unik;
  cell_unik.av = cell->av[0];
  cell_unik.nh = cell->nh[0];
  cell_unik.tgas = cell->tgas[0];
  cell_unik.tdust = cell->tdust[0];
  if( solver_init( &cell_unik, network, &input_params->phys, abundances, min_nh, input_params->solver.abs_err,  input_params->solver.rel_err, &astrochem_mem ) != EXIT_SUCCESS )
    {
      return EXIT_FAILURE;
    }
  else
    {
      int i, j;

      /* Solve the system for each time step. */
      for (i = 0; i < ts->n_time_steps; i++)
        {


          if (i!=0 && mode == DYNAMIC)
            {
              cell_unik.av = cell->av[i];
              cell_unik.nh = cell->nh[i];
              cell_unik.tgas = cell->tgas[i];
              cell_unik.tdust = cell->tdust[i];

              if( solve( &astrochem_mem, network, abundances,  ts->time_steps[i], &cell_unik, verbose ) != EXIT_SUCCESS )
                {
                  return EXIT_FAILURE;
                }
            }
          else
            {
              if( solve( &astrochem_mem, network, abundances,  ts->time_steps[i], NULL, verbose ) != EXIT_SUCCESS )
                {
                  return EXIT_FAILURE;
                }
            }


          /* Fill the array of abundances with the output species
             abundances. Ignore species that are not in the
             network. Abundance that are lower than MIN_ABUNDANCES are
             set to 0. */

          for (j = 0; j < input_params->output.n_output_species; j++)
            {
              if (mode == STATIC)
                {
                  output_abundances[j] =
                   (double) NV_Ith_S (astrochem_mem.y, input_params->output.output_species_idx[j]) / cell->nh[0];
                }
              else
                {
                  output_abundances[j] =
                   (double) NV_Ith_S (astrochem_mem.y, input_params->output.output_species_idx[j]) / cell->nh[i];
                }
              if (output_abundances[j] < MIN_ABUNDANCE)
                output_abundances[j] = 0.;

#ifdef HAVE_OPENMP
              omp_set_lock(&lock);
#endif
              // Select a chunk of the file
              hsize_t     start[3]={  cell_index, i, 0 };
              H5Sselect_hyperslab( fileDataspace, H5S_SELECT_SET, start, NULL, count , NULL );

              // Write the chunk
              H5Dwrite(dataset, datatype, memDataspace, fileDataspace, H5P_DEFAULT,
                       output_abundances );

#ifdef HAVE_OPENMP
              omp_unset_lock(&lock);
#endif

            }

          /* Compute the rate of each formation/destruction route for
             each output specie. */

          if (input_params->output.trace_routes)
            {
              for (j = 0; j < input_params->output.n_output_species; j++)
                {
                  int k;
                  int l;
                  for (l = 0; l < N_OUTPUT_ROUTES; l++)
                    {
                      routes[ j*N_OUTPUT_ROUTES + l ].formation.rate = 0;
                      routes[ j*N_OUTPUT_ROUTES + l ].destruction.rate = 0;
                    }
                  for (k = 0; k < network->n_reactions; k++)
                    {
                      /* If the species is a product of the
                         reaction then compute the formation
                         rate. If the rate is greater than the
                         smallest rate in the formation route
                         structure, we add the current reaction
                         number and rate to that structure. */

                      bool specie_in_products = false;
                      int p;
                      for( p = 0; p < MAX_PRODUCTS; p++ )
                        {
                          if( network->reactions[k].products[p] ==  input_params->output.output_species_idx[j])
                            {
                              specie_in_products = true;
                              break;
                            }
                        }
                      if( specie_in_products )
                        {
                          r_t formation_route;
                          double min_rate;
                          unsigned int min_rate_index;
                          if (network->reactions[k].reaction_type == 0)
                            {
                              formation_route.rate = astrochem_mem.params.reac_rates[k];
                              formation_route.rate *=
                               NV_Ith_S (astrochem_mem.y, network->reactions[k].reactants[0]);
                            }
                          else if (network->reactions[k].reaction_type == 23)
                            {
                              formation_route.rate = astrochem_mem.params.reac_rates[k];
                            }
                          else
                            {
                              formation_route.rate = astrochem_mem.params.reac_rates[k];
                              int r;
                              for( r = 0; r < MAX_REACTANTS; r++ )
                                {
                                  if( network->reactions[k].reactants[r] != -1 )
                                    {
                                      formation_route.rate *=
                                       NV_Ith_S (astrochem_mem.y, network->reactions[k].reactants[r]);
                                    }
                                }
                            }
                          formation_route.reaction_no =
                           network->reactions[k].reaction_no;
                          min_rate = routes[ j*N_OUTPUT_ROUTES  ].formation.rate;
                          min_rate_index = 0;
                          for (l = 1; l < N_OUTPUT_ROUTES; l++)
                            {
                              if (routes[ j*N_OUTPUT_ROUTES + l ].formation.rate <
                                  min_rate)
                                {
                                  min_rate =
                                   routes[ j*N_OUTPUT_ROUTES + l ].formation.rate;
                                  min_rate_index = (unsigned int) l;
                                }
                            }
                          if (formation_route.rate > min_rate)
                            {
                              routes[ j*N_OUTPUT_ROUTES + min_rate_index ].formation.rate = formation_route.rate;
                              routes[ j*N_OUTPUT_ROUTES + min_rate_index ].formation.reaction_no = formation_route.reaction_no;
                            }
                        }

                      /* If the species is reactant of the reaction
                         then compute the destruction rate. */
                      bool species_in_reactants = false;
                      int r;
                      for ( r = 0; r < MAX_REACTANTS; r++ )
                        {
                          if ( network->reactions[k].reactants[r] == input_params->output.output_species_idx[j])
                            {
                              species_in_reactants = true;
                              break;
                            }
                        }
                      if( species_in_reactants )
                        {
                          r_t destruction_route;
                          double min_rate;
                          unsigned int min_rate_index;

                          if (network->reactions[k].reaction_type == 0)
                            {
                              destruction_route.rate = astrochem_mem.params.reac_rates[k];
                              destruction_route.rate *=
                               NV_Ith_S (astrochem_mem.y, network->reactions[k].reactants[0]);
                            }
                          else if (network->reactions[k].reaction_type == 23)
                            {
                              destruction_route.rate = astrochem_mem.params.reac_rates[k];
                            }
                          else
                            {
                              destruction_route.rate = astrochem_mem.params.reac_rates[k];
                              for ( r = 0; r < MAX_REACTANTS; r++ )
                                {
                                  if (network->reactions[k].reactants[r] != -1)
                                    {
                                      destruction_route.rate *=
                                       NV_Ith_S (astrochem_mem.y, network->reactions[k].reactants[r]);
                                    }
                                }
                            }
                          destruction_route.reaction_no =
                           network->reactions[k].reaction_no;

                          min_rate = routes[ j*N_OUTPUT_ROUTES  ].destruction.rate;
                          min_rate_index = 0;
                          for (l = 1; l < N_OUTPUT_ROUTES; l++)
                            {
                              if (routes[ j*N_OUTPUT_ROUTES + l ].destruction.rate <
                                  min_rate)
                                {
                                  min_rate =
                                   routes[ j*N_OUTPUT_ROUTES + l ].destruction.rate;
                                  min_rate_index = (unsigned int) l;
                                }
                            }
                          if (destruction_route.rate > min_rate)
                            {
                              routes[ j*N_OUTPUT_ROUTES + min_rate_index ].destruction.rate = destruction_route.rate;
                              routes[ j*N_OUTPUT_ROUTES + min_rate_index ].destruction.reaction_no = destruction_route.reaction_no;
                            }
                        }
                    }
                }
#ifdef HAVE_OPENMP
              omp_set_lock(&lock);
#endif
              // Selecting a chunk of the file
              hsize_t     routeStart[4]={  cell_index, i, 0, 0 };
              H5Sselect_hyperslab( routeFileDataspace, H5S_SELECT_SET, routeStart, NULL, routeCount , NULL );

              int spec_idx;
              for( spec_idx = 0; spec_idx < input_params->output.n_output_species; spec_idx++ )
                {
                  // Writing in each route datasets
                  H5Dwrite( routeDatasets[ spec_idx ], routeDatatype, routeMemDataspace, routeFileDataspace, H5P_DEFAULT,
                            routes );
                }

#ifdef HAVE_OPENMP
              omp_unset_lock(&lock);
#endif
            }
        }

    }
#ifdef HAVE_OPENMP
  omp_set_lock(&lock);
#endif
  // Cleaning up hdf5
  H5Sclose(memDataspace);
  H5Sclose(fileDataspace);
  if (input_params->output.trace_routes)
    {
      H5Sclose(routeMemDataspace);
      H5Sclose(routeFileDataspace);
    }
#ifdef HAVE_OPENMP
  omp_unset_lock(&lock);
#endif
  // Free
  free( output_abundances );
  free( routes );
  free_abundances( abundances );
  solver_close( &astrochem_mem );
  return EXIT_SUCCESS;
}
Example #8
0
int
main (void)
{
  FILE *f;
  net_t network;
  int verbose = 0;

  /* Create the input.ini, source.mdl and network_chm files */

  f = fopen ("network.chm", "w");
  fprintf (f, "# This network file was created by full_solve_test\n");
  fprintf (f, "X -> Y    1e-9    0    0    2    1\n");
  fclose (f);

  /* Read them */
  if( read_network ("network.chm", &network, verbose) )
    {
      return EXIT_FAILURE;
    }

  phys_t phys;
  phys.cosmic = 1.3e-17;
  phys.chi = 1;
  phys.grain_size = 1e-5;
  phys.grain_abundance = 0;

  double abs_err, rel_err;
  abs_err = 1e-15;
  rel_err = 1e-6;

  const char* species[]  = { "X", "Y" };
  const double initial_abundances[] = { 1.0, 0.0 };

  double *abundances;
  alloc_abundances( &network, &abundances ); // Allocate the abundances array; it contains all species.
  set_initial_abundances(species, 2, initial_abundances, &network, abundances); // Set initial abundances

  double density = 1000;
  double av = 20;
  double temperature = 10;

  cell_t cell;
  cell.nh = density;
  cell.av = av;
  cell.tgas = temperature;
  cell.tdust = temperature; // Assume tgas = tdust in this specific case

  astrochem_mem_t astrochem_mem;

  if( solver_init( &cell, &network, &phys, abundances , density, abs_err, rel_err, &astrochem_mem ) != EXIT_SUCCESS )
    {
      return EXIT_FAILURE;
   }
  int i;
  double time = 0;
  for( i = 0; i < 1000 ; i++ )
    {

      time+= 10;
      if( solve( &astrochem_mem, &network, abundances, time, NULL,verbose) != EXIT_SUCCESS )
        {
          return EXIT_FAILURE;
        }
      double x_abundance;
      double y_abundance;
      double x_abs_err;
      double x_rel_err;
      double y_abs_err;
      double y_rel_err;

      x_abundance = 1.0 * exp (-1e-9 *  time);
      y_abundance = 1.0 - x_abundance;
      x_abs_err = fabs( abundances[0] - x_abundance);
      y_abs_err = fabs( abundances[1] - y_abundance);
      x_rel_err = x_abs_err / x_abundance;
      y_rel_err = y_abs_err / y_abundance;

      /* Errors accumulate after each time step, so the actual error
         on the abundance is somewhat larger than the solver
         relative tolerance. */
      if ((x_abs_err > abs_err) && (x_rel_err > rel_err * 5e2))
        {
          fprintf (stderr, "full_solve_test: %s:%d: incorrect abundance at t=%12.15e: expected %12.15e, got %12.15e.\n",
                   __FILE__, __LINE__, time, x_abundance, abundances[0]);
          solver_close( &astrochem_mem );
          free_abundances( abundances );
          free_network (&network);
          return EXIT_FAILURE;
        }

      if ((y_abs_err > abs_err) && (y_rel_err > rel_err * 5e2))
        {
          fprintf (stderr, "full_solve_test: %s:%d: incorrect abundance at t=%12.6e: expected %12.6e, got %12.6e.\n",
                   __FILE__, __LINE__, time, y_abundance, abundances[1]);
          solver_close( &astrochem_mem );
          free_abundances( abundances );
          free_network (&network);
          return EXIT_FAILURE;
        }
    }
  solver_close( &astrochem_mem );
  free_abundances( abundances );
  free_network (&network);
  return EXIT_SUCCESS;
}