/*! \fn int Check_Custom_Boundary(int *flags, struct parameters P) * \brief Check for custom boundary conditions and set boundary flags. */ int Grid3D::Check_Custom_Boundary(int *flags, struct parameters P) { /*check if any boundary is a custom boundary*/ /*if yes, then return 1*/ /*if no, then return 0*/ /*additionally, set a flag for each boundary*/ if(H.nx>1) { *(flags+0) = P.xl_bcnd; *(flags+1) = P.xu_bcnd; } if(H.ny>1) { *(flags+2) = P.yl_bcnd; *(flags+3) = P.yu_bcnd; } if(H.nz>1) { *(flags+4) = P.zl_bcnd; *(flags+5) = P.zu_bcnd; } for (int i=0; i<6; i++) { if (!( (flags[i]>=0)&&(flags[i]<=5) ) ) { chprintf("Invalid boundary conditions. Must select between 1 (periodic), 2 (reflective), 3 (transmissive), 4 (custom), 5 (mpi).\n"); chexit(-1); } if (flags[i] == 4) { /*custom boundaries*/ return 1; } } /*no custom boundaries*/ return 0; }
int main(int argc, char *argv[]) { // timing variables double start_total, stop_total, start_step, stop_step; #ifdef CPU_TIME double stop_init, init_min, init_max, init_avg; double start_bound, stop_bound, bound_min, bound_max, bound_avg; double start_hydro, stop_hydro, hydro_min, hydro_max, hydro_avg; double init, bound, hydro; init = bound = hydro = 0; #endif //CPU_TIME // start the total time start_total = get_time(); /* Initialize MPI communication */ #ifdef MPI_CHOLLA InitializeChollaMPI(&argc, &argv); #endif /*MPI_CHOLLA*/ // declare Cfl coefficient and initial inverse timestep Real C_cfl = 0.4; // CFL coefficient 0 < C_cfl < 0.5 Real dti = 0; // inverse time step, 1.0 / dt // input parameter variables char *param_file; struct parameters P; int nfile = 0; // number of output files Real outtime = 0; // current output time // read in command line arguments if (argc != 2) { chprintf("usage: %s <parameter_file>\n", argv[0]); chexit(0); } else { param_file = argv[1]; } // create the grid Grid3D G; // read in the parameters parse_params (param_file, &P); // and output to screen chprintf ("Parameter values: nx = %d, ny = %d, nz = %d, tout = %f, init = %s, boundaries = %d %d %d %d %d %d\n", P.nx, P.ny, P.nz, P.tout, P.init, P.xl_bcnd, P.xu_bcnd, P.yl_bcnd, P.yu_bcnd, P.zl_bcnd, P.zu_bcnd); chprintf ("Output directory: %s\n", P.outdir); // initialize the grid G.Initialize(&P); chprintf("Local number of grid cells: %d %d %d %d\n", G.H.nx_real, G.H.ny_real, G.H.nz_real, G.H.n_cells); // Set initial conditions and calculate first dt chprintf("Setting initial conditions...\n"); G.Set_Initial_Conditions(P, C_cfl); chprintf("Dimensions of each cell: dx = %f dy = %f dz = %f\n", G.H.dx, G.H.dy, G.H.dz); chprintf("Ratio of specific heats gamma = %f\n",gama); chprintf("Nstep = %d Timestep = %f Simulation time = %f\n", G.H.n_step, G.H.dt, G.H.t); // set main variables for Read_Grid inital conditions if (strcmp(P.init, "Read_Grid") == 0) { outtime += G.H.t; nfile = P.nfile; dti = 1.0 / G.H.dt; } // set boundary conditions (assign appropriate values to ghost cells) chprintf("Setting boundary conditions...\n"); G.Set_Boundary_Conditions(P); chprintf("Boundary conditions set.\n"); #ifdef OUTPUT // write the initial conditions to file chprintf("Writing initial conditions to file...\n"); WriteData(G, P, nfile); // add one to the output file count nfile++; #endif //OUTPUT // increment the next output time outtime += P.outstep; #ifdef CPU_TIME stop_init = get_time(); init = stop_init - start_total; #ifdef MPI_CHOLLA init_min = ReduceRealMin(init); init_max = ReduceRealMax(init); init_avg = ReduceRealAvg(init); chprintf("Init min: %9.4f max: %9.4f avg: %9.4f\n", init_min, init_max, init_avg); #else printf("Init %9.4f\n", init); #endif //MPI_CHOLLA #endif //CPU_TIME // Evolve the grid, one timestep at a time chprintf("Starting caclulations.\n"); while (G.H.t < P.tout) //while (G.H.n_step < 1) { // get the start time start_step = get_time(); // calculate the timestep G.set_dt(C_cfl, dti); if (G.H.t + G.H.dt > outtime) { G.H.dt = outtime - G.H.t; } // Advance the grid by one timestep #ifdef CPU_TIME start_hydro = get_time(); #endif //CPU_TIME dti = G.Update_Grid(); #ifdef CPU_TIME stop_hydro = get_time(); hydro = stop_hydro - start_hydro; #ifdef MPI_CHOLLA hydro_min = ReduceRealMin(hydro); hydro_max = ReduceRealMax(hydro); hydro_avg = ReduceRealAvg(hydro); #endif //MPI_CHOLLA #endif //CPU_TIME // update the time G.H.t += G.H.dt; // add one to the timestep count G.H.n_step++; // set boundary conditions for next time step #ifdef CPU_TIME start_bound = get_time(); #endif //CPU_TIME G.Set_Boundary_Conditions(P); #ifdef CPU_TIME stop_bound = get_time(); bound = stop_bound - start_bound; #ifdef MPI_CHOLLA bound_min = ReduceRealMin(bound); bound_max = ReduceRealMax(bound); bound_avg = ReduceRealAvg(bound); #endif //MPI_CHOLLA #endif //CPU_TIME #ifdef CPU_TIME #ifdef MPI_CHOLLA chprintf("hydro min: %9.4f max: %9.4f avg: %9.4f\n", hydro_min, hydro_max, hydro_avg); chprintf("bound min: %9.4f max: %9.4f avg: %9.4f\n", bound_min, bound_max, bound_avg); #endif //MPI_CHOLLA #endif //CPU_TIME // get the time to compute the total timestep stop_step = get_time(); stop_total = get_time(); G.H.t_wall = stop_total-start_total; #ifdef MPI_CHOLLA G.H.t_wall = ReduceRealMax(G.H.t_wall); #endif chprintf("n_step: %d sim time: %10.7f sim timestep: %7.4e timestep time = %9.3f ms total time = %9.4f s\n", G.H.n_step, G.H.t, G.H.dt, (stop_step-start_step)*1000, G.H.t_wall); if (G.H.t == outtime) { #ifdef OUTPUT /*output the grid data*/ WriteData(G, P, nfile); // add one to the output file count nfile++; #endif //OUTPUT // update to the next output time outtime += P.outstep; } } /*end loop over timesteps*/ // free the grid G.Reset(); #ifdef MPI_CHOLLA MPI_Finalize(); #endif /*MPI_CHOLLA*/ return 0; }