double rhs_1st_equation (double x, double t, Gas_parameters * parameters) { return g_t (x, t) + .5 * ( 2 * u_exact (x, t) * g_x (x, t) + g_exact(x, t) * u_x (x, t) + (2 - g_exact (x, t)) * u_x (x, t)); }
/* RHS initializes the right hand side "vector". */ void rhs(int matrix_size, int matrix_size2, double *f_, int block_size) { double (*f)[matrix_size][matrix_size] = (double (*)[matrix_size][matrix_size])f_; int i,ii; int j,jj; double x; double y; // The "boundary" entries of F store the boundary values of the solution. // The "interior" entries of F store the right hand sides of the Poisson equation. #pragma omp parallel #pragma omp master //for collapse(2) for (j = 0; j < matrix_size; j+=block_size) for (i = 0; i < matrix_size; i+=block_size) #pragma omp task firstprivate(block_size,i,j,matrix_size) private(ii,jj,x,y) for (jj=j; jj<j+block_size; ++jj) { y = (double) (jj) / (double) (matrix_size - 1); for (ii=i; ii<i+block_size; ++ii) { x = (double) (ii) / (double) (matrix_size - 1); if (ii == 0 || ii == matrix_size - 1 || jj == 0 || jj == matrix_size - 1) (*f)[ii][jj] = u_exact(x, y); else (*f)[ii][jj] = - uxxyy_exact(x, y); } } }
/* RHS initializes the right hand side "vector". */ void rhs(int nx, int ny, double *f, int block_size) { int i,ii; int j,jj; double x; double y; // The "boundary" entries of F store the boundary values of the solution. // The "interior" entries of F store the right hand sides of the Poisson equation. #pragma omp parallel { #pragma omp single for (j = 0; j < ny; j+=block_size) { for (i = 0; i < nx; i+=block_size) { #pragma omp task firstprivate(block_size,i,j,nx,ny) private(ii,jj,x,y) for (jj=j; jj<j+block_size; ++jj) { y = (double) (jj) / (double) (ny - 1); for (ii=i; ii<i+block_size; ++ii) { x = (double) (ii) / (double) (nx - 1); if (ii == 0 || ii == nx - 1 || jj == 0 || jj == ny - 1) (f)[ii * ny + jj] = u_exact(x, y); else (f)[ii * ny + jj] = - uxxyy_exact(x, y); } } } } } }
double FD::ErrorRMS() { double sum = 0; for(int i = 0; i < N; i ++) { double exact = u_exact(i,M); sum +=(data[M][i]-exact)*(data[M][i]-exact)/exact/exact; } sum = sum/(1+N); sum = sqrt(sum); return sum; }
double FD :: MaxPointwiseError() { double max = 0; for(int i = 1; i < M+1;i++) for(int j = 1; j < N; j++) { double exact = u_exact(j, i ); if(abs(exact-data[i][j])>max) max = abs(exact-data[i][j]); } return max; }
void error_norm(double rms[]) { //--------------------------------------------------------------------- //--------------------------------------------------------------------- //--------------------------------------------------------------------- // this function computes the norm of the difference between the // computed solution and the exact solution //--------------------------------------------------------------------- int c, i, j, k, m, ii, jj, kk, d, error; double xi, eta, zeta, u_exact[5], rms_work[5], add; for (m = 1; m <= 5; m++) { rms_work(m) = 0.0e0; } for (c = 1; c <= ncells; c++) { kk = 0; for (k = cell_low(3,c); k <= cell_high(3,c); k++) { zeta = (double)(k) * dnzm1; jj = 0; for (j = cell_low(2,c); j <= cell_high(2,c); j++) { eta = (double)(j) * dnym1; ii = 0; for (i = cell_low(1,c); i <= cell_high(1,c); i++) { xi = (double)(i) * dnxm1; exact_solution(xi, eta, zeta, u_exact); for (m = 1; m <= 5; m++) { add = u(m,ii,jj,kk,c)-u_exact(m); rms_work(m) = rms_work(m) + add*add; } ii = ii + 1; } jj = jj + 1; } kk = kk + 1; } } RCCE_allreduce((char*)rms_work, (char*)rms, 5, RCCE_DOUBLE, RCCE_SUM, RCCE_COMM_WORLD); for (m = 1; m <= 5; m++) { for (d = 1; d <= 3; d++) { rms(m) = rms(m) / (double)(grid_points(d)-2); } rms(m) = sqrt(rms(m)); } return; }
void calc_error ( int nx, int ny, int nz, double u[], double f[], double xlo, double ylo, double zlo, double xhi, double yhi, double zhi ) { double error_max, error_l2; int i, j, k, i_max=-1, j_max=-1, k_max = -1; double u_true, u_true_norm; double x, y, z, dx, dy, dz, term; dx = (xhi - xlo) / ( double ) ( nx - 1 ); dy = (yhi - ylo) / ( double ) ( ny - 1 ); dz = (yhi - ylo) / ( double ) ( nz - 1 ); error_max = 0.0; error_l2 = 0.0; /* print statements below are commented out but may help in debugging */ //printf(" i j k x y z uexact ucomp error\n"); for ( k = 0; k < nz; k++ ) { z = zlo + k * dz; for ( j = 0; j < ny; j++ ) { y = ylo + j * dy; for ( i = 0; i < nx; i++ ) { x = xlo + i * dx; u_true = u_exact ( x, y, z ); term = U(i,j,k) - u_true; //printf(" %d %d %d %12.5e %12.5e %12.5e %12.5e %12.5e %12.5e \n",i,j,k,x,y,z,u_true,U(i,j,k),term); error_l2 = error_l2 + term*term; if (ABS(term) > error_max){ error_max = ABS(term); } } /* end for i */ } /* end for j */ } /* end for k */ error_l2 = sqrt(dx*dy*dz*error_l2); printf ( "\n max Error in computed soln: %12.5e \n", error_max ); printf ( " l2 norm of Error on %4d by %4d by %4d grid\n (dx %12.5e dy %12.5e dz %12.5e): %12.5e\n", nx,ny,nz,dx,dy,dz,error_l2 ); return; }
void rhs ( int nx, int ny, double f[NX][NY] ) /******************************************************************************/ /* * Purpose: * RHS initializes the right hand side "vector". * Discussion: * It is convenient for us to set up RHS as a 2D array. However, each * entry of RHS is really the right hand side of a linear system of the * form * A * U = F * In cases where U(I,J) is a boundary value, then the equation is simply * U(I,J) = F(i,j) * and F(I,J) holds the boundary data. * Otherwise, the equation has the form * (1/DX^2) * ( U(I+1,J)+U(I-1,J)+U(I,J-1)+U(I,J+1)-4*U(I,J) ) = F(I,J) * where DX is the spacing and F(I,J) is the value at X(I), Y(J) of * pi^2 * ( x^2 + y^2 ) * sin ( pi * x * y ) * Licensing: * This code is distributed under the GNU LGPL license. * Modified: * 28 October 2011 * Author: * John Burkardt * Parameters: * Input, int NX, NY, the X and Y grid dimensions. * Output, double F[NX][NY], the initialized right hand side data. * */ { double fnorm; int i; int j; double x; double y; /* * The "boundary" entries of F store the boundary values of the solution. * The "interior" entries of F store the right hand sides of the Poisson equation. * */ for ( j = 0; j < ny; j++ ) { y = ( double ) ( j ) / ( double ) ( ny - 1 ); for ( i = 0; i < nx; i++ ) { x = ( double ) ( i ) / ( double ) ( nx - 1 ); if ( i == 0 || i == nx - 1 || j == 0 || j == ny - 1 ) { f[i][j] = u_exact ( x, y ); } else { f[i][j] = - uxxyy_exact ( x, y ); } } } fnorm = r8mat_rms ( nx, ny, f ); printf ( " RMS of F = %g\n", fnorm ); return; }
int main ( int argc, char *argv[] ) /******************************************************************************/ /* * Purpose: * MAIN is the main program for POISSON_OPENMP. * Discussion: * POISSON_OPENMP is a program for solving the Poisson problem. * This program uses OpenMP for parallel execution. * The Poisson equation * - DEL^2 U(X,Y) = F(X,Y) * is solved on the unit square [0,1] x [0,1] using a grid of NX by * NX evenly spaced points. The first and last points in each direction * are boundary points. * The boundary conditions and F are set so that the exact solution is * U(x,y) = sin ( pi * x * y ) * so that * - DEL^2 U(x,y) = pi^2 * ( x^2 + y^2 ) * sin ( pi * x * y ) * The Jacobi iteration is repeatedly applied until convergence is detected. * For convenience in writing the discretized equations, we assume that NX = NY. * Licensing: * This code is distributed under the GNU LGPL license. * Modified: * 14 December 2011 * Author: * John Burkardt * */ { int converged; double diff; double dx; double dy; double error; double f[NX][NY]; int i; int id; int itnew; int itold; int j; int jt; int jt_max = 20; int nx = NX; int ny = NY; double tolerance = 0.000001; double u[NX][NY]; double u_norm; double udiff[NX][NY]; double uexact[NX][NY]; double unew[NX][NY]; double unew_norm; double wtime; double x; double y; dx = 1.0 / ( double ) ( nx - 1 ); dy = 1.0 / ( double ) ( ny - 1 ); /* * Print a message. * */ timestamp ( ); printf ( "\n" ); printf ( "POISSON_OPENMP:\n" ); printf ( " C version\n" ); printf ( " A program for solving the Poisson equation.\n" ); printf ( "\n" ); printf ( " Use OpenMP for parallel execution.\n" ); // printf ( " The number of processors is %d\n", omp_get_num_procs ( ) ); { // id = omp_get_thread_num ( ); // if ( id == 0 ) //{ // printf ( " The maximum number of threads is %d\n", omp_get_num_threads ( ) ); // } } printf ( "\n" ); printf ( " -DEL^2 U = F(X,Y)\n" ); printf ( "\n" ); printf ( " on the rectangle 0 <= X <= 1, 0 <= Y <= 1.\n" ); printf ( "\n" ); printf ( " F(X,Y) = pi^2 * ( x^2 + y^2 ) * sin ( pi * x * y )\n" ); printf ( "\n" ); printf ( " The number of interior X grid points is %d\n", nx ); printf ( " The number of interior Y grid points is %d\n", ny ); printf ( " The X grid spacing is %f\n", dx ); printf ( " The Y grid spacing is %f\n", dy ); /* * Set the right hand side array F. * */ rhs ( nx, ny, f ); /* * Set the initial solution estimate UNEW. * We are "allowed" to pick up the boundary conditions exactly. * */ for ( j = 0; j < ny; j++ ) { for ( i = 0; i < nx; i++ ) { if ( i == 0 || i == nx - 1 || j == 0 || j == ny - 1 ) { unew[i][j] = f[i][j]; } else { unew[i][j] = 0.0; } } } unew_norm = r8mat_rms ( nx, ny, unew ); /* * Set up the exact solution UEXACT. * */ for ( j = 0; j < ny; j++ ) { y = ( double ) ( j ) / ( double ) ( ny - 1 ); for ( i = 0; i < nx; i++ ) { x = ( double ) ( i ) / ( double ) ( nx - 1 ); uexact[i][j] = u_exact ( x, y ); } } u_norm = r8mat_rms ( nx, ny, uexact ); printf ( " RMS of exact solution = %g\n", u_norm ); /* * Do the iteration. * */ converged = 0; printf ( "\n" ); printf ( " Step ||Unew|| ||Unew-U|| ||Unew-Exact||\n" ); printf ( "\n" ); for ( j = 0; j < ny; j++ ) { for ( i = 0; i < nx; i++ ) { udiff[i][j] = unew[i][j] - uexact[i][j]; } } error = r8mat_rms ( nx, ny, udiff ); printf ( " %4d %14g %14g\n", 0, unew_norm, error ); //wtime = omp_get_wtime ( ); itnew = 0; for ( ; ; ) { itold = itnew; itnew = itold + 500; /* * SWEEP carries out 500 Jacobi steps in parallel before we come * back to check for convergence. * */ sweep ( nx, ny, dx, dy, f, itold, itnew, u, unew ); /* * Check for convergence. * */ u_norm = unew_norm; unew_norm = r8mat_rms ( nx, ny, unew ); for ( j = 0; j < ny; j++ ) { for ( i = 0; i < nx; i++ ) { udiff[i][j] = unew[i][j] - u[i][j]; } } diff = r8mat_rms ( nx, ny, udiff ); for ( j = 0; j < ny; j++ ) { for ( i = 0; i < nx; i++ ) { udiff[i][j] = unew[i][j] - uexact[i][j]; } } error = r8mat_rms ( nx, ny, udiff ); printf ( " %4d %14g %14g %14g\n", itnew, unew_norm, diff, error ); if ( diff <= tolerance ) { converged = 1; break; } } if ( converged ) { printf ( " The iteration has converged.\n" ); } else { printf ( " The iteration has NOT converged.\n" ); } //wtime = omp_get_wtime ( ) - wtime; printf ( "\n" ); printf ( " Elapsed seconds = %g\n", wtime ); /* * Terminate. * */ printf ( "\n" ); printf ( "POISSON_OPENMP:\n" ); printf ( " Normal end of execution.\n" ); printf ( "\n" ); timestamp ( ); return 0; }
double error_f(double x, double y, gsl_vector *solution) { return fabs(reconstruct_at(solution,x,y)-u_exact(x,y)); }
void init_prob ( int nx, int ny, int nz, double f[], double u[], double xlo, double ylo, double zlo, double xhi, double yhi, double zhi ) { int i, j, k; double x, y, z, dx, dy, dz; dx = (xhi - xlo) / ( double ) ( nx - 1 ); dy = (yhi - ylo) / ( double ) ( ny - 1 ); dz = (zhi - zlo) / ( double ) ( nz - 1 ); /* Set the boundary conditions. For this simple test use exact solution in bcs */ j = 0; // low y bc y = ylo; for ( k = 0; k < nz; k++ ) { z = zlo + k*dz; for ( i = 0; i < nx; i++ ) { x = xlo + i * dx; U(i,j,k) = u_exact ( x, y, z ); // notese que cuando aca se habla de ijk, en realidad es una macro que asigna la posicion necesaria } } j = ny - 1; // hi y y = yhi; for ( k = 0; k < nz; k++ ) { z = zlo + k*dz; for ( i = 0; i < nx; i++ ) { x = xlo + i * dx; U(i,j,k) = u_exact ( x, y, z ); } } i = 0; // low x x = xlo; for ( k = 0; k < nz; k++ ) { z = zlo + k*dx; for ( j = 0; j < ny; j++ ) { y = ylo + j * dy; U(i,j,k) = u_exact ( x, y, z ); } } i = nx - 1; // hi x x = xhi; for ( k = 0; k < nz; k++ ) { z = zlo + k*dx; for ( j = 0; j < ny; j++ ) { y = ylo + j * dy; U(i,j,k) = u_exact ( x, y, z ); } } k = 0; // low z z = zlo; for ( j = 0; j < ny; j++ ) { y = ylo + j * dy; for ( i = 0; i < nx; i++) { x = xlo + i * dx; U(i,j,k) = u_exact ( x, y, z ); } } k = nz - 1; // hi z z = zhi; for ( j = 0; j < ny; j++ ) { y = ylo + j * dy; for ( i = 0; i < nx; i++) { x = xlo + i * dx; U(i,j,k) = u_exact ( x, y, z ); } } omp_set_num_threads(7); #pragma omp parallel for default(none)\ shared(nx, ny, nz, dx, dy, dz, u, f, xlo, ylo, zlo) private(i, j, k, z, y, x) /* Set the right hand side */ for ( k = 0; k < nz; k++ ){ z = zlo + k * dz; for ( j = 0; j < ny; j++ ){ y = ylo + j * dy; for ( i = 0; i < nx; i++ ) { x = xlo + i * dx; F(i,j,k) = uxx_exact ( x, y, z ) + uyy_exact ( x, y, z ) + uzz_exact( x, y, z ); } } } return; }
double rhs_2nd_equation (double x, double t, Gas_parameters * parameters) { return u_t (x, t) + u_exact (x, t) * u_x (x, t) + parameters->p_ro * g_x (x, t) - parameters->viscosity * exp (-g_exact (x, t)) * u_xx (x, t); }
void check_params( struct user_parameters* params, int matrix_size, int block_size, double dx, double dy, double *f_, int niter, double *u_, double *unew_) { double x, y; int i, j; double *udiff_ =(double*)malloc(matrix_size * matrix_size * sizeof(double)); double (*udiff)[matrix_size][matrix_size] = (double (*)[matrix_size][matrix_size])udiff_; double (*unew)[matrix_size][matrix_size] = (double (*)[matrix_size][matrix_size])unew_; double (*u)[matrix_size][matrix_size] = (double (*)[matrix_size][matrix_size])u_; double (*f)[matrix_size][matrix_size] = (double (*)[matrix_size][matrix_size])f_; // Check for convergence. for (j = 0; j < matrix_size; j++) { y = (double) (j) / (double) (matrix_size - 1); for (i = 0; i < matrix_size; i++) { x = (double) (i) / (double) (matrix_size - 1); (*udiff)[i][j] = (*unew)[i][j] - u_exact(x, y); if( (*udiff)[i][j] > 1.0E-6 ) { printf("error: %d, %d: %f\n", i, j, (*udiff)[i][j]); } } } double error = r8mat_rms(matrix_size, matrix_size, udiff_); double error1; // Set the right hand side array F. rhs(matrix_size, matrix_size, f_, block_size); for (j = 0; j < matrix_size; j++) { for (i = 0; i < matrix_size; i++) { if (i == 0 || i == matrix_size - 1 || j == 0 || j == matrix_size - 1) { (*unew)[i][j] = (*f)[i][j]; (*u)[i][j] = (*f)[i][j]; } else { (*unew)[i][j] = 0.0; (*u)[i][j] = 0.0; } } } sweep_seq(matrix_size, matrix_size, dx, dy, f_, 0, niter, u_, unew_); // Check for convergence. for (j = 0; j < matrix_size; j++) { y = (double) (j) / (double) (matrix_size - 1); for (i = 0; i < matrix_size; i++) { x = (double) (i) / (double) (matrix_size - 1); (*udiff)[i][j] = (*unew)[i][j] - u_exact(x, y); if( (*udiff)[i][j] > 1.0E-6 ) { printf("error: %d, %d: %f\n", i, j, (*udiff)[i][j]); } } } error1 = r8mat_rms(matrix_size, matrix_size, udiff_); params->succeed = fabs(error - error1) < 1.0E-6; if(!params->succeed) { printf("error = %f, error1 = %f\n", error, error1); } free(udiff_); }
double run(struct user_parameters* params) { int matrix_size = params->matrix_size; if (matrix_size <= 0) { matrix_size = 512; params->matrix_size = matrix_size; } int block_size = params->blocksize; if (block_size <= 0) { block_size = 128; params->blocksize = block_size; } int niter = params->titer; if (niter <= 0) { niter = 4; params->titer = niter; } double dx; double dy; double error; int ii,i; int jj,j; int nx = matrix_size; int ny = matrix_size; double *f = (double *)malloc(nx * nx * sizeof(double)); double *u = (double *)malloc(nx * nx * sizeof(double)); double *unew = (double *)malloc(nx * ny * sizeof(double)); /* test if valid */ if ( (nx % block_size) || (ny % block_size) ) { params->succeed = 0; params->string2display = "*****ERROR: blocsize must divide NX and NY"; return 0; } /// INITIALISATION dx = 1.0 / (double) (nx - 1); dy = 1.0 / (double) (ny - 1); // Set the right hand side array F. rhs(nx, ny, f, block_size); /* Set the initial solution estimate UNEW. We are "allowed" to pick up the boundary conditions exactly. */ #pragma omp parallel { #pragma omp single for (j = 0; j < ny; j+= block_size) { for (i = 0; i < nx; i+= block_size) { #pragma omp task firstprivate(i,j) private(ii,jj) for (jj=j; jj<j+block_size; ++jj) { for (ii=i; ii<i+block_size; ++ii) { if (ii == 0 || ii == nx - 1 || jj == 0 || jj == ny - 1) { (unew)[ii * ny + jj] = (f)[ii * ny + jj]; } else { (unew)[ii * ny + jj] = 0.0; } } } } } } /// KERNEL INTENSIVE COMPUTATION START_TIMER; sweep(nx, ny, dx, dy, f, 0, niter, u, unew, block_size); END_TIMER; if(params->check) { double x; double y; double *udiff = (double *)malloc(nx * ny * sizeof(double)); /// CHECK OUTPUT // Check for convergence. for (j = 0; j < ny; j++) { y = (double) (j) / (double) (ny - 1); for (i = 0; i < nx; i++) { x = (double) (i) / (double) (nx - 1); (udiff)[i * ny + j] = (unew)[i * ny + j] - u_exact(x, y); } } error = r8mat_rms(nx, ny, udiff); double error1; // Set the right hand side array F. rhs(nx, ny, f, block_size); /* Set the initial solution estimate UNEW. We are "allowed" to pick up the boundary conditions exactly. */ for (j = 0; j < ny; j++) { for (i = 0; i < nx; i++) { if (i == 0 || i == nx - 1 || j == 0 || j == ny - 1) { (unew)[i * ny + j] = (f)[i * ny + j]; } else { (unew)[i * ny + j] = 0.0; } } } sweep_seq(nx, ny, dx, dy, f, 0, niter, u, unew); // Check for convergence. for (j = 0; j < ny; j++) { y = (double) (j) / (double) (ny - 1); for (i = 0; i < nx; i++) { x = (double) (i) / (double) (nx - 1); (udiff)[i * ny + j] = (unew)[i * ny + j] - u_exact(x, y); } } error1 = r8mat_rms(nx, ny, udiff); params->succeed = fabs(error - error1) < 1.0E-6; free(udiff); } free(f); free(u); free(unew); return TIMER; }