int main(int argc, char** argv) { int i, j, N, flag; Matrix A=NULL, Q=NULL; Vector b, grid, e, lambda=NULL; double time, sum, h, tol=1e-6; int rank, size; int mpi_top_coords; int mpi_top_sizes; init_app(argc, argv, &rank, &size); if (argc < 3) { printf("need two parameters, N and flag [and tolerance]\n"); printf(" - N is the problem size (in each direction\n"); printf(" - flag = 1 -> Matrix-free Gauss-Jacobi iterations\n"); printf(" - flag = 2 -> Matrix-free red-black Gauss-Seidel iterations\n"); printf(" - flag = 3 -> Matrix-free CG iterations\n"); printf(" - flag = 4 -> Matrix-free additive schwarz preconditioned+Cholesky CG iterations\n"); printf(" - flag = 5 -> Matrix-free additive schwarz preconditioned+CG CG iterations\n"); return 1; } N=atoi(argv[1]); flag=atoi(argv[2]); if (argc > 3) tol=atof(argv[3]); if (N < 0) { if (rank == 0) printf("invalid problem size given\n"); close_app(); return 2; } if (flag < 0 || flag > 5) { if (rank == 0) printf("invalid flag given\n"); close_app(); return 3; } if (flag == 2 && (N-1)%2 != 0 && ((N-1)/size) % 2 != 0) { if (rank == 0) printf("need an even size (per process) for red-black iterations\n"); close_app(); return 4; } // setup topology mpi_top_coords = 0; mpi_top_sizes = 0; MPI_Dims_create(size, 1, &mpi_top_sizes); int periodic = 0; MPI_Comm comm; MPI_Cart_create(MPI_COMM_WORLD, 1, &mpi_top_sizes, &periodic, 0, &comm); MPI_Cart_coords(comm, rank, 1, &mpi_top_coords); b = createVectorMPI(N+1, &comm, 1, 1); e = createVectorMPI(N+1, &comm, 1, 1); grid = equidistantMesh(0.0, 1.0, N); h = 1.0/N; evalMeshDispl(b, grid, source); scaleVector(b, pow(h, 2)); evalMeshDispl(e, grid, exact); axpy(b, e, alpha); b->data[0] = b->data[b->len-1] = 0.0; if (flag == 4) { int size = b->len; if (b->comm_rank == 0) size--; if (b->comm_rank == b->comm_size-1) size--; A1D = createMatrix(size, size); A1Dfactored = 0; diag(A1D, -1, -1.0); diag(A1D, 0, 2.0+alpha); diag(A1D, 1, -1.0); } int its=-1; char method[128]; time = WallTime(); if (flag == 1) { its=GaussJacobiPoisson1D(b, tol, 1000000); sprintf(method,"Gauss-Jacobi"); } if (flag == 2) { its=GaussSeidelPoisson1Drb(b, tol, 1000000); sprintf(method,"Gauss-Seidel"); } if (flag == 3) { its=cgMatrixFree(Poisson1D, b, tol); sprintf(method,"CG"); } if (flag == 4 || flag == 5) { its=pcgMatrixFree(Poisson1D, Poisson1DPre, b, tol); sprintf(method,"PCG"); } if (rank == 0) { printf("%s used %i iterations\n", method, its); printf("elapsed: %f\n", WallTime()-time); } evalMeshDispl(e, grid, exact); axpy(b,e,-1.0); b->data[0] = b->data[b->len-1] = 0.0; h = maxNorm(b); if (rank == 0) printf("max error: %e\n", h); if (A) freeMatrix(A); if (Q) freeMatrix(Q); freeVector(grid); freeVector(b); freeVector(e); if (lambda) freeVector(lambda); if (A1D) freeMatrix(A1D); MPI_Comm_free(&comm); close_app(); return 0; }
int main(int argc, char** argv) { int rank, size; init_app(argc, argv, &rank, &size); if (argc < 2) { printf("usage: %s <N> [L]\n",argv[0]); close_app(); return 1; } /* the total number of grid points in each spatial direction is (N+1) */ /* the total number of degrees-of-freedom in each spatial direction is (N-1) */ int N = atoi(argv[1]); int M = N-1; double L=1.0; if (argc > 2) L = atof(argv[2]); double h = L/N; Vector grid = createVector(M); for (int i=0;i<M;++i) grid->data[i] = (i+1)*h; int coords[2] = {0}; int sizes[2] = {1}; #ifdef HAVE_MPI sizes[0] = sizes[1] = 0; MPI_Dims_create(size,2,sizes); int periodic[2]; periodic[0] = periodic[1] = 0; MPI_Comm comm; MPI_Cart_create(MPI_COMM_WORLD,2,sizes,periodic,0,&comm); MPI_Cart_coords(comm,rank,2,coords); #endif int* len[2]; int* displ[2]; splitVector(M, sizes[0], &len[0], &displ[0]); splitVector(M, sizes[1], &len[1], &displ[1]); #ifdef HAVE_MPI Matrix u = createMatrixMPI(len[0][coords[0]]+2, len[1][coords[1]]+2, M, M, &comm); #else Matrix u = createMatrix(M+2, M+2); #endif evalMeshDispl(u, grid, grid, poisson_source, displ[0][coords[0]], displ[1][coords[1]]); scaleVector(u->as_vec, h*h); double time = WallTime(); GS(u, 1e-6, 5000); evalMesh2Displ(u, grid, grid, exact_solution, -1.0, displ[0][coords[0]], displ[1][coords[1]]); double max = maxNorm(u->as_vec); if (rank == 0) { printf("elapsed: %f\n", WallTime()-time); printf("max: %f\n", max); } freeMatrix(u); freeVector(grid); for (int i=0;i<2;++i) { free(len[i]); free(displ[i]); } close_app(); return 0; }