Exemplo n.º 1
0
/**
 * The main operation reads the configuration file, initializes the scenario and
 * contains the main loop. So here are the individual steps of the algorithm:
 *
 * - read the program configuration file using read_parameters()
 * - set up the matrices (arrays) needed using the matrix() command
 * - create the initial setup init_uvp(), init_flag(), output_uvp()
 * - perform the main loop
 * - trailer: destroy memory allocated and do some statistics
 *
 * The layout of the grid is described by the first figure below, the enumeration
 * of the whole grid is given by the second figure. All the unknowns correspond
 * to a two dimensional degree of freedom layout, so they are not stored in
 * arrays, but in a matrix.
 *
 * @image html grid.jpg
 *
 * @image html whole-grid.jpg
 *
 * Within the main loop the following big steps are done (for some of the 
 * operations a definition is defined already within uvp.h):
 *
 * - calculate_dt() Determine the maximal time step size.
 * - boundaryvalues() Set the boundary values for the next time step.
 * - calculate_fg() Determine the values of F and G (diffusion and confection).
 *   This is the right hand side of the pressure equation and used later on for
 *   the time step transition.
 * - calculate_rs()
 * - Iterate the pressure poisson equation until the residual becomes smaller
 *   than eps or the maximal number of iterations is performed. Within the
 *   iteration loop the operation sor() is used.
 * - calculate_uv() Calculate the velocity at the next time step.
 */
int main(int argn, char** args){
	double Re,UI,VI,PI,GX,GY, 				/* problem dependent quantities */
		xlength,ylength,dx,dy,			 	/* geometry data */
		t=0,t_end,dt,tau,dt_value,			/* time stepping data */
		alpha,omg,eps,res;		 			/* pressure iteration data */
	int it, itermax, n=0, imax, jmax;		/* max iterations, iteration step and # of interior cells */
	double **U, **V, **F, **G, **P, **RS;

	/* Read the problem parameters */
	read_parameters("data/cavity100-2.dat", &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy,
			&imax, &jmax, &alpha, &omg, &tau, &itermax, &eps, &dt_value);

	/*	Allocate space for matrices */
	U = matrix(0, imax, 0, jmax+1);
	F = matrix(0, imax, 0, jmax+1);
	V = matrix(0, imax+1, 0, jmax);
	G = matrix(0, imax+1, 0, jmax);
	P = matrix(0, imax+1, 0, jmax+1);
	RS= matrix(0, imax+1, 0, jmax+1);

	/*	Assign initial values to u, v, p */
	init_uvp(UI, VI, PI, imax, jmax, U, V, P);

	while (t < t_end){
		/* Select δt according to (14) */
		calculate_dt(Re, tau, &dt, dx, dy, imax, jmax, U, V);

		/* Set boundary values for u and v according to (15),(16) */
		boundaryvalues(imax, jmax, U, V);

		/* Compute F (n) and G (n) according to (10),(11),(18) */
		calculate_fg(Re, GX, GY, alpha, dt, dx, dy, imax, jmax, U, V, F, G);

		/* Compute the right-hand side rs of the pressure equation (12) */
		calculate_rs(dt, dx, dy, imax, jmax, F, G, RS);

		it = 0; res=DBL_MAX;
		while (it < itermax && res > eps){
			/* Perform a SOR iteration according to (19) using the provided function and retrieve the residual res */
			sor(omg, dx, dy, imax, jmax, P, RS, &res);
			it++;
		}

		/* Compute u (n+1) and v (n+1) according to (8),(9) */
		calculate_uv(dt,dx,dy,imax,jmax,U,V,F,G,P);

		t+=dt; n++;
	}

	/* Output of u, v, p for visualization */
	write_vtkFile("visualization/cavity", n, xlength, ylength, imax, jmax, dx, dy, U, V, P);

	/* Freeing memory */
	free_matrix(U, 0, imax, 0, jmax+1);
	free_matrix(F, 0, imax, 0, jmax+1);
	free_matrix(V, 0, imax+1, 0, jmax);
	free_matrix(G, 0, imax+1, 0, jmax);
	free_matrix(P, 0, imax+1, 0, jmax+1);
	free_matrix(RS, 0, imax+1, 0, jmax+1);

	return -1;
}
Exemplo n.º 2
0
int main(int argc, char** args){
	
	double Re, UI, VI, PI, GX, GY, t_end, xlength, ylength, dt, dx, dy, alpha, omg, tau, eps, dt_value, t, res, dp, nu;
	double **U, **V, **P, **F, **G, **RS;
	double **K, **E;					/* turbulent kinetic energy k, dissipation rate epsilon*/
	double Fu, Fv;						/* force integration variables */
	double KI, EI, cn, ce, c1, c2; 			/* K and E: Initial values for k and epsilon */

	int n, it, imax, jmax, itermax, pb, boundaries[4];
	int fluid_cells;		/* Number of fluid cells in our geometry */
	int **Flag;			/* Flagflield matrix */
	
	char vtkname[200];
	char pgm[200];
	char problem[10];		/* Problem name */
	char fname[200];

	if(argc<2){
		printf("No parameter file specified. Terminating...\n");
		exit(1);
	}

	sprintf(fname, "%s%s", CONFIGS_FOLDER, args[1]);
	printf("%s\n",fname);
	read_parameters(fname, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax, &jmax, &alpha, &omg, &itermax, &eps, boundaries, &dp, &pb, &KI, &EI, &cn, &ce, &c1, &c2, pgm, &nu, problem);

	/* Allocate Flag matrix */
	Flag = imatrix( 0, imax+1, 0, jmax+1 );

	U = matrix ( 0 , imax+1 , 0 , jmax+1 );
	V = matrix ( 0 , imax+1 , 0 , jmax+1 );
	P = matrix ( 0 , imax+1 , 0 , jmax+1 );

	F = matrix ( 0 , imax , 0 , jmax );
	G = matrix ( 0 , imax , 0 , jmax );
	RS = matrix ( 0 , imax , 0 , jmax );

	K = matrix ( 0 , imax+1 , 0 , jmax+1 );
	E = matrix ( 0 , imax+1 , 0 , jmax+1 );
	
	/* Initialize values to the Flag, u, v and p */
	init_flag(CONFIGS_FOLDER,pgm, imax, jmax, &fluid_cells, Flag );
	init_uvp(UI, VI, PI, KI, EI, imax, jmax, U, V, P, K, E, Flag, problem );

	printf("Problem: %s\n", problem );
	printf( "xlength = %f, ylength = %f\n", xlength, ylength );
	printf( "imax = %d, jmax = %d\n", imax, jmax );
	printf( "dt = %f, dx = %f, dy = %f\n", dt, dx, dy);
	printf( "Number of fluid cells = %d\n", fluid_cells );
	printf( "Reynolds number: %f\n\n", Re);

	t=.0;
	n=0;

	while( t <= t_end ){
		boundaryvalues( imax, jmax, U, V, K, E, boundaries, Flag );

		/* special inflow boundaries, including k and eps */
		spec_boundary_val( problem, imax, jmax, U, V, K, E, Re, dp, cn, ylength);

		/* calculate new values for k and eps */
		comp_KAEP(Re, nu, cn, ce, c1, c2, alpha, dt, dx, dy, imax, jmax, U, V, K, E, GX, GY, Flag);


		/* calculate new values for F and G */
		calculate_fg( Re, GX, GY, alpha, dt, dx, dy, imax, jmax, U, V, F, G, K, E, nu, cn, Flag );

		/* calculate right hand side */
		calculate_rs( dt, dx, dy, imax, jmax, F, G, RS, Flag );

		it = 0;
		res = 10000.0;
		while( it < itermax && fabs(res) > eps ){
			sor( omg, dx, dy, imax, jmax, fluid_cells, P, RS, Flag, &res, problem, dp );
			it++;
		}

		printf("[%5d: %f] dt: %f, sor iterations: %4d \n", n, t, dt, it);

		/* calculate new values for u and v */
		calculate_uv( dt, dx, dy, imax, jmax, U, V, F, G, P, Flag );

		t += dt;
		n++;
	}

	sprintf(vtkname, "%s%s", VISUA_FOLDER,  args[1]);
	write_vtkFile( vtkname, 1, xlength, ylength, imax, jmax, dx, dy, U, V, P, K, E, Flag);
	
	comp_surface_force( Re, dx, dy, imax, jmax, U, V, P, Flag, &Fu, &Fv);

	printf( "\nProblem: %s\n", problem );
	printf( "xlength = %f, ylength = %f\n", xlength, ylength );
	printf( "imax = %d, jmax = %d\n", imax, jmax );
	printf( "dt = %f, dx = %f, dy = %f\n", dt, dx, dy);
	printf( "Number of fluid cells = %d\n", fluid_cells );
	printf( "Reynolds number: %f\n", Re);
	printf( "Drag force = %f Lift force = %f\n", Fu, Fv);

	/* free memory */
	free_matrix(U,0,imax+1,0,jmax+1);
	free_matrix(V,0,imax+1,0,jmax+1);
	free_matrix(P,0,imax+1,0,jmax+1);
	free_matrix(K,0,imax+1,0,jmax+1);
	free_matrix(E,0,imax+1,0,jmax+1);
	
	free_matrix(F,0,imax,0,jmax);
	free_matrix(G,0,imax,0,jmax);
	free_matrix(RS,0,imax,0,jmax);

	free_imatrix(Flag,0,imax+1,0,jmax+1);

	return 0;
}
Exemplo n.º 3
0
int main(int argn, char** args){
 	if (argn !=2 ) {
        	printf("When running the simulation, please give a valid scenario file name!\n");
        	return 1;
        }
	//set the scenario
	char *filename = NULL;
	filename = args[1];

	//initialize variables
	double t = 0; /*time start*/
	int it, n = 0; /*iteration and time step counter*/
	double res; /*residual for SOR*/
		/*arrays*/
	double **U, **V, **P;
	double **RS, **F, **G;
	int **Flag; //additional data structure for arbitrary geometry
		/*those to be read in from the input file*/
	double Re, UI, VI, PI, GX, GY, t_end, xlength, ylength, dt, dx, dy, alpha, omg, tau, eps, dt_value;
	int  imax, jmax, itermax;

	double presLeft, presRight, presDelta; //for pressure stuff
	int wl, wr, wt, wb;
	char problem[32];
	double vel; //in case of a given inflow or wall velocity

	//read the parameters, using problem.dat, including wl, wr, wt, wb
	read_parameters(filename, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax,
			&jmax, &alpha, &omg, &tau, &itermax, &eps, &dt_value, &wl, &wr, &wt, &wb, problem, &presLeft, &presRight, &presDelta, &vel);

	int pics = dt_value/dt; //just a helping variable for outputing vtk


	//allocate memory, including Flag
	U = matrix(0, imax+1, 0, jmax+1);
	V = matrix(0, imax+1, 0, jmax+1);
	P = matrix(0, imax+1, 0, jmax+1);
	RS = matrix(1, imax, 1, jmax);
	F = matrix(0, imax, 1, jmax);
	G = matrix(1, imax, 0, jmax);
	Flag = imatrix(0, imax+1, 0, jmax+1); // or Flag = imatrix(1, imax, 1, jmax);

	int kmax = 20; //test no slip boundary value function
	double ***U3d  = (double ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(double*)) ); //test no slip boundary value function
	double ***V3d  = (double ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(double*)) ); //test no slip boundary value function
	double ***W3d  = (double ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(double*)) ); //test no slip boundary value function
	int ***Flag3d  = (int ***) malloc((size_t)((imax+1)*(jmax+1)*(kmax+1) * sizeof(int*)) ); //test no slip boundary value function

	//initialisation, including **Flag
	init_flag(problem, imax, jmax, presDelta, Flag);
	init_uvp(UI, VI, PI, imax, jmax, U, V, P, problem);

	//going through all time steps
	while(t < t_end){
		//adaptive time stepping
		calculate_dt(Re, tau, &dt, dx, dy, imax, jmax, U, V);
		
		//setting bound.values
		boundaryvalues(imax, jmax, U, V, P, wl, wr, wt, wb, F, G, problem, Flag, vel); //including P, wl, wr, wt, wb, F, G, problem

                //test no slip boundary value function
                for(int i=1; i<=imax; i++){
                        for(int j=1; j<=jmax; j++){
                                for(int k=1; k<=kmax; k++){
                                        boundaryvalues_no_slip(i, j, k, U3d, V3d, W3d, Flag3d); //test no slip boundary value function
                                }
                        }
		}
		
		//computing F, G and right hand side of pressue eq.
		calculate_fg(Re, GX, GY, alpha, dt, dx, dy, imax, jmax, U, V, F, G, Flag);
		calculate_rs(dt, dx, dy, imax, jmax, F, G, RS);
		
		//iteration counter
		it = 0;
		
		do{
			//
			//perform SOR iteration, at same time set bound.values for P and new residual value
			sor(omg, dx, dy, imax, jmax, P, RS, &res, Flag, presLeft, presRight);

			it++;
		}while(it<itermax && res>eps);
/*		if (it == itermax) {
			printf("Warning: sor while loop exits because it reaches the itermax. res = %f, time =%f\n", res, t);
		}
*/		//calculate U and V of this time step
		calculate_uv(dt, dx, dy, imax, jmax, U, V, F, G, P, Flag);
		
		//indent time and number of time steps
		n++;
		t += dt;
		
		//output of pics for animation
		if (n%pics==0 ){
			write_vtkFile(filename, n, xlength, ylength, imax, jmax, dx, dy, U, V, P);
		}
	}
	//output of U, V, P at the end for visualization
	//write_vtkFile("DrivenCavity", n, xlength, ylength, imax, jmax, dx, dy, U, V, P);

	//free memory
	free_matrix(U, 0, imax+1, 0, jmax+1);
	free_matrix(V, 0, imax+1, 0, jmax+1);
	free_matrix(P, 0, imax+1, 0, jmax+1);
	free_matrix(RS, 1, imax, 1, jmax);
	free_matrix(F, 0, imax, 1, jmax);
	free_matrix(G, 1, imax, 0, jmax);
	free_imatrix(Flag, 0, imax+1, 0, jmax+1);

	free(U3d);
	free(V3d);
	free(W3d);
	free(Flag3d);
	return -1;
}
Exemplo n.º 4
0
int main(int argn, char** args){

	double **U, **V, **P, **F, **G, **RS;
	const char *szFileName = "dam_break.dat";
	double Re, UI, VI, PI, GX, GY, t_end, xlength, ylength, dt, dx, dy, alpha, omg, tau, eps, dt_value;
	double res = 0, t = 0, n = 0;
	int imax, jmax, itermax, it;

	
	/* Additional data structures for VOF */
	double **fluidFraction;
	double **fluidFraction_alt;
	int **flagField;
	double **dFdx, **dFdy;
	int **pic;
	char output_dirname[60];
	double epsilon = 1e-10;
	
	/* Read the program configuration file using read_parameters() */
	read_parameters(szFileName, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax, &jmax, &alpha, &omg, &tau, &itermax, &eps, &dt_value);        

	/* Set up the matrices (arrays) needed using the matrix() command */
	U = matrix(0, imax  , 0, jmax+1);
	V = matrix(0, imax+1, 0, jmax  );
	P = matrix(0, imax+1, 0, jmax+1);
	F = matrix(0, imax  , 0, jmax+1);
	G = matrix(0, imax+1, 0, jmax  );
	RS= matrix(0, imax+1, 0, jmax+1);
	flagField = imatrix(0, imax+1, 0, jmax+1);
	fluidFraction = matrix(0, imax+1, 0, jmax+1);
	fluidFraction_alt = matrix(0, imax+1, 0, jmax+1);
	dFdx = matrix(0, imax+1, 0, jmax+1);
	dFdy = matrix(0, imax+1, 0, jmax+1);


	/*create a directory*/
	strcpy(output_dirname, "dam_break/dam_break");
	mkdir("dam_break", 0777);
	
	/* Read pgm file with domain and initial setting */
	pic = read_pgm("dam_break.pgm");
	init_fluidFraction(pic, fluidFraction,fluidFraction_alt, imax, jmax);
	
	/* Assign initial values to u, v, p */
	init_uvp(UI, VI, PI, imax, jmax, U, V, P);

		/* Set valid values for the fluid fraction */
		adjust_fluidFraction(fluidFraction, flagField, epsilon, imax, jmax);

	while(t <= t_end){   
	
		/*Select δt*/
		calculate_dt(Re, tau, &dt, dx, dy, imax, jmax, U, V);
		
		/* Set boundary values for u and v */
/*		boundaryvalues(imax, jmax, U, V, flagField, dx, dy);
*/		
		/* Compute F(n) and G(n) */
		calculate_fg(Re, GX, GY, alpha, dt, dx, dy, imax, jmax, U, V, F, G, flagField);
		
		/* Compute the right-hand side rs of the pressure equation */
		calculate_rs(dt, dx, dy, imax, jmax, F, G, RS, flagField);



		
				
		
		/* Determine the orientation of the free surfaces */

		calculate_freeSurfaceOrientation(fluidFraction, flagField, dFdx, dFdy, dx, dy, imax, jmax);

		
		/* Perform SOR iterations */
		it=0;
		res = 1e6;
		while(it < itermax && res > eps){
			sor(omg, dx, dy, imax, jmax, P, RS, fluidFraction, flagField, dFdx, dFdy, &res);
			it++;
		}

		
		/* Compute u(n+1) and v(n+1) */
		calculate_uv(dt, dx, dy, imax, jmax, U, V, F, G, P, flagField);

		boundaryvalues(imax, jmax, U, V, flagField, dx, dy);
		
		/* Compute fluidFraction(n+1) */
		calculate_fluidFraction(fluidFraction,fluidFraction_alt, flagField, U, V, dFdx, dFdy, imax, jmax, dx, dy, dt);

		boundaryvalues(imax, jmax, U, V, flagField, dx, dy);
		/* Set valid values for the fluid fraction */
		adjust_fluidFraction(fluidFraction, flagField, epsilon, imax, jmax);

		boundaryvalues(imax, jmax, U, V, flagField, dx, dy);


		if((int)n % 10 == 0) {
			write_vtkFile(output_dirname, n, xlength, ylength, imax, jmax, dx, dy, U, V, P, fluidFraction, flagField);
		}
		
		/* Print out simulation time and whether SOR converged */
		printf("Time: %.4f", t);
		if(res > eps) {printf("\t*** Did not converge (res=%f, eps=%f)", res, eps);return -1;}
		printf("\n");
		
		t = t + dt;
		n++;
	
	}
	

	free_matrix(U , 0, imax  , 0, jmax+1);
	free_matrix(V , 0, imax+1, 0, jmax  );
	free_matrix(P , 0, imax+1, 0, jmax+1);
	free_matrix(F , 0, imax  , 0, jmax+1);
	free_matrix(G , 0, imax+1, 0, jmax  );
	free_matrix(RS, 0, imax+1, 0, jmax+1);
	
	return -1;
	
}
Exemplo n.º 5
0
int main(int argn, char** args){

	double **U, **V, **P, **F, **G, **RS;
	int **Flag;
	char problem[60];
	char parameters_filename[60];
	char pgm[60];
	char output_dirname[60];
	double Re, UI, VI, PI, GX, GY, t_end, xlength, ylength, dt, dx, dy, alpha, omg, tau, eps, dt_value, dp;
	double res = 0, t = 0, n = 0;
	int imax, jmax, itermax, it;
	int wl, wr, wt, wb;
	int timestepsPerPlotting;
	char old_output_filename[128];
	struct dirent *old_outputfile;
	DIR *output_dir;
	/* Variables for parallel program */
	int iproc, jproc, myrank, il, ir, jb, jt, rank_l, rank_r, rank_b, rank_t, omg_i, omg_j, num_proc;
	double min_dt;
	double *bufSend, *bufRecv;
	double totalTime = 0;
	struct timespec previousTime, currentTime;
	
	MPI_Init(&argn, &args);
	MPI_Comm_size(MPI_COMM_WORLD, &num_proc);

	/* Read name of the problem from the command line arguments */
	if(argn > 1) {
		strcpy(problem, args[1]);
	} else {
		printf("\n=== ERROR: Please provide the name of the problem\n=== e.g. Run ./sim problem_name if there is a problem_name.dat file.\n\n");
		MPI_Finalize();
		return 1;
	}

	/* Generate input filename based on problem name */
	strcpy(parameters_filename, problem);
	strcat(parameters_filename, ".dat");

	/* Read the program configuration file using read_parameters() */
	read_parameters(parameters_filename, pgm, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax, &jmax, &alpha, &omg, &tau, &itermax, &eps, &dt_value, problem, &dp, &wl, &wr, &wt, &wb, &timestepsPerPlotting, &iproc, &jproc);
	printf("%s\n", pgm);
	
	/* Check if the number of processes is correct */
	if(iproc * jproc != num_proc) {
		printf("\n=== ERROR: Number of processes is incorrect (iproc=%d, jproc=%d, -np=%d) ===\n\n", iproc, jproc, num_proc);
		MPI_Finalize();
		return 1;
	}

	/* Create folder with the name of the problem */
	strcpy(output_dirname, problem);
	strcat(output_dirname, "/");
	strcat(output_dirname, problem);
	mkdir(problem, 0777);
	output_dir = opendir(problem);

	/* Delete existing files in output folder*/
	while((old_outputfile = readdir(output_dir))) {
		sprintf(old_output_filename, "%s/%s", problem, old_outputfile->d_name);
		remove(old_output_filename);
	}
	
	/* Determine subdomain and neighbours for each process */
	init_parallel(iproc, jproc, imax, jmax, &myrank, &il, &ir, &jb, &jt, &rank_l, &rank_r, &rank_b, &rank_t, &omg_i, &omg_j, num_proc);

	/* Set up the matrices (arrays) needed using the matrix() command */
	U = matrix(il-2, ir+1, jb-1, jt+1);
	V = matrix(il-1, ir+1, jb-2, jt+1);
	P = matrix(il-1, ir+1, jb-1, jt+1);
	F = matrix(il-2, ir+1, jb-1, jt+1);
	G = matrix(il-1, ir+1, jb-2, jt+1);
	RS= matrix(il, ir, jb, jt);
	Flag = imatrix(il-1, ir+1, jb-1, jt+1);
	
	/* Assign initial values to u, v, p */
	init_uvp(UI, VI, PI, il, ir, jb, jt, U, V, P);
	
	/* Allocate memory for buffers */
	bufSend = malloc(max(ir-il+3, jt-jb+3) * sizeof(double));
	bufRecv = malloc(max(ir-il+3, jt-jb+3) * sizeof(double));
	
	/* Initialize lower part of the domain with UI = 0 for the flow_over_step problem */
	/* (this code might be moved to somewhere else later) */
	if(strcmp(problem, "flow_over_step") == 0) {
		init_matrix(U, il, ir, jb, min(jmax/2, jt), 0);
	}

	/* Initialization of flag field */
	init_flag(pgm, imax, jmax, il, ir, jb, jt, Flag, dp);
	
	if(myrank == 0) {
		clock_gettime(CLOCK_MONOTONIC, &currentTime);
	}

	while(t <= t_end){
	
		/* Select δt */
		calculate_dt(Re, tau, &dt, dx, dy, il, ir, jb, jt, U, V);
		MPI_Allreduce(&dt, &min_dt, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);

		dt = min_dt;
		
		/* Set boundary values for u and v */
		boundaryvalues(il, ir, jb, jt, imax, jmax, U, V, wl, wr, wt, wb, Flag);
	
		/* Set special boundary values */
		spec_boundary_val(problem, il, ir, jb, jt, imax, jmax, U, V, P, Re, xlength, ylength, dp);

		/* Compute F(n) and G(n) */
		calculate_fg(Re, GX, GY, alpha, dt, dx, dy, il, ir, jb, jt, imax, jmax, U, V, F, G, Flag);
		
		/* Compute the right-hand side rs of the pressure equation */
		calculate_rs(dt, dx, dy, il, ir, jb, jt, imax, jmax, F, G, RS);
		
		/* Perform SOR iterations */
		it = 0;
		res = 1e6;
		while(it < itermax && res > eps){
			sor(omg, dx, dy, dp, il, ir, jb, jt, imax, jmax, rank_l, rank_r, rank_b, rank_t, P, RS, &res, Flag, bufSend, bufRecv);
			it++;
		}
		
		/* Compute u(n+1) and v(n+1) */
		calculate_uv(dt, dx, dy, il, ir, jb, jt, imax, jmax, U, V, F, G, P, Flag);
		
		/* Exchange velocity strips */
		uv_com(U, V, il, ir, jb, jt, rank_l, rank_r, rank_b, rank_t, bufSend, bufRecv);
		
		t = t + dt;
		n++;
		
		/* Generate snapshot for current timestep */
		if((int) n % timestepsPerPlotting == 0) {
			write_vtkFile(output_dirname, myrank, n, xlength, ylength, il, ir, jb, jt, imax, jmax, dx, dy, U, V, P);
		}
		
		/* Print out simulation time and whether the SOR converged */
		if(myrank == 0) {
			/* Print simulation time */
			printf("Time: %.4f", t);
			/* Print runtime */
			previousTime = currentTime;
			clock_gettime(CLOCK_MONOTONIC, &currentTime);
			totalTime += (double)currentTime.tv_sec + 1e-9 * currentTime.tv_nsec - (double)previousTime.tv_sec - 1e-9 * previousTime.tv_nsec;
			printf("\tRuntime: %.3f s (avg runtime/step: %.3f s)", totalTime, totalTime/n);
			if(res > eps) printf("\tDid not converge (res=%f, eps=%f)", res, eps);
			printf("\n");
		}

	}
	
	/* Close the output folder */
	closedir(output_dir);
	
	/* Tell user where to find the output */
	if(myrank == 0) {
		printf("Please find the output in the folder \"%s\".\n", problem);
	}
	
	/* Free allocated memory */
	free_matrix(U, il-2, ir+1, jb-1, jt+1);
	free_matrix(V, il-1, ir+1, jb-2, jt+1);
	free_matrix(P, il-1, ir+1, jb-1, jt+1);
	free_matrix(F, il-2, ir+1, jb-1, jt+1);
	free_matrix(G, il-1, ir+1, jb-2, jt+1);
	free_matrix(RS, il, ir, jb, jt);
	free_imatrix(Flag, il-1, ir+1, jb-1, jt+1);
	free(bufSend);
	free(bufRecv);
	
	MPI_Barrier(MPI_COMM_WORLD);
	MPI_Finalize();
	
	return 0;
	
}
Exemplo n.º 6
0
Arquivo: main.c Projeto: Xodion/CFD
/**
 * The main operation reads the configuration file, initializes the scenario and
 * contains the main loop. So here are the individual steps of the algorithm:
 *
 * - read the program configuration file using read_parameters()
 * - set up the matrices (arrays) needed using the matrix() command
 * - create the initial setup init_uvp(), init_flag(), output_uvp()
 * - perform the main loop
 * - trailer: destroy memory allocated and do some statistics
 *
 * The layout of the grid is decribed by the first figure below, the enumeration
 * of the whole grid is given by the second figure. All the unknowns corresond
 * to a two dimensional degree of freedom layout, so they are not stored in
 * arrays, but in a matrix.
 *
 * @image html grid.jpg
 *
 * @image html whole-grid.jpg
 *
 * Within the main loop the following big steps are done (for some of the
 * operations a definition is defined already within uvp.h):
 *
 * - calculate_dt() Determine the maximal time step size.
 * - boundaryvalues() Set the boundary values for the next time step.
 * - calculate_fg() Determine the values of F and G (diffusion and confection).
 *   This is the right hand side of the pressure equation and used later on for
 *   the time step transition.
 * - calculate_rs()
 * - Iterate the pressure poisson equation until the residual becomes smaller
 *   than eps or the maximal number of iterations is performed. Within the
 *   iteration loop the operation sor() is used.
 * - calculate_uv() Calculate the velocity at the next time step.
 */
int main(int argn, char** args)
{
    double **U, **V, **P, **R, **F, **G;
    double t = 0.0;
    double t_end, xlength, ylength, tau, omg, alpha, eps, Re, GX, GY, PI, UI, VI, dx, dy, dt, res, dt_value;
    int n, imax, jmax, itermax, it, i, outputCount;
    double nextOutput;
    bool outputSpecified = false;

    char* paraviewOutput = "./Paraview/cavity100";
    char* inputFile = "./cavity100.dat";

    /* statistics */
    int sumIter, maxIter, minIter;
    double minTimeStep, maxTimestep;
    clock_t begin, end;
    double time_spent;
    sumIter = 0;
    maxIter = 0;
    maxTimestep = 0;


    begin = clock();

    /* Parse command line arguments */
    if (argn > 2)
    {
        for (i = 1; i < argn; i++)
        {
            if (strcmp(args[i], "-i") == 0)
            {
                inputFile = args[i + 1];
                if (!outputSpecified)
                    paraviewOutput = "./Paraview/sim";
            }

            if (strcmp(args[i], "-o") == 0)
            {
                paraviewOutput = args[i + 1];
                outputSpecified = true;
            }


        }
    }
    else if (argn == 2)
    {
        /* input file is the single argument besides fctn-name */
        inputFile = args[1];
    }

    /* Initialization */
    read_parameters(inputFile, &Re, &UI, &VI, &PI, &GX, &GY, &t_end, &xlength, &ylength, &dt, &dx, &dy, &imax, &jmax, &alpha, &omg, &tau, &itermax, &eps, &dt_value);
    U = matrix(0, imax, 0, jmax + 1);
    V = matrix(0, imax + 1, 0, jmax);
    P = matrix(0, imax + 1, 0, jmax + 1);
    R = matrix(0, imax + 1, 0, jmax + 1);
    F = matrix(0, imax, 0, jmax);
    G = matrix(0, imax, 0, jmax);
    n = 0;
    nextOutput = dt_value;


    init_uvp(UI, VI, PI, imax, jmax, U, V, P);
    minIter = itermax;
    minTimeStep = t_end;
    write_vtkFile(paraviewOutput,0,xlength,ylength,imax,jmax,dx,dy,U,V,P);
    outputCount = 1;
    while (t < t_end)
    {
        calculate_dt(Re, tau, &dt, dx, dy, imax, jmax, U, V);
        if (dt < minTimeStep)
            minTimeStep = dt;
        if (dt > maxTimestep)
            maxTimestep = dt;
        boundaryvalues(imax, jmax, U, V);
        calculate_fg(Re, GX, GY, alpha, dt, dy, dy, imax, jmax, U, V, F, G);
        calculate_rs(dt, dx, dy, imax, jmax, F, G, R);
        it = 0;
        while(++it < itermax)
        {
            sor(omg, dx, dy, imax, jmax, P, R, &res);
            if (res <= eps)
                break;
        }
        if (res > eps)
            fprintf(stderr, "WARNING: SOR did not converge in timestep %d, residual: %f\n", n + 1, res);
        if (it > maxIter)
            maxIter = it;
        if (it < minIter)
            minIter = it;
        sumIter += it;
        calculate_uv(dt, dx, dy, imax, jmax, U, V, F, G, P);
        t = t + dt;
        n++;
        if (t >= nextOutput)
        {
            write_vtkFile(paraviewOutput,outputCount,xlength,ylength,imax,jmax,dx,dy,U,V,P);
            nextOutput += dt_value;
            outputCount++;
        }

    }
    end = clock();
    time_spent = (double) (end - begin) / CLOCKS_PER_SEC;

    /* print statistics */
    printf("Simulation took %f seconds\n", time_spent);
    printf("Number of timesteps: %d\n", n);
    printf("Min. timestep: %f     Max. timestep: %f    Avg. timestep: %f\n", minTimeStep, maxTimestep, t_end/n);
    printf("Min. # iterations: %d     Max. # iterations: %d     Avg: %f\n", minIter, maxIter, sumIter/(double) n);

    /* Free memory */
    free_matrix(U, 0, imax, 0, jmax + 1);
    free_matrix(V, 0, imax + 1, 0, jmax);
    free_matrix(P, 0, imax + 1, 0, jmax + 1);
    free_matrix(R, 0, imax, 0 ,jmax);
    free_matrix(F, 0, imax, 0, jmax);
    free_matrix(G, 0, imax, 0, jmax);


    return 0;
}