#include "pargrid.h" /*+ worker - Solve a sparse matrix problem associated with a grid Input Parameters: grid - the given grid procinfo - the processor information (in BlockSolve format) +*/ void worker(par_grid *grid, BSprocinfo *procinfo) { int i, num_iter; BSspmat *A; BSpar_mat *pA, *f_pA; BScomm *Acomm, *f_comm; FLOAT shifted_diag, residual; FLOAT *x, *rhs, t; /* number grid to use in matrix assembly */ num_grid3d(grid,procinfo); /* now call the routines to set up the matrix */ A = get_mat(grid,procinfo); /* Set symmetry and storage scheme to be used */ BSset_mat_symmetric(A,grid->symmetric); BSset_mat_icc_storage(A,grid->icc_storage); /* permute the matrix */ pA = BSmain_perm(procinfo,A); CHKERR(0); /* diagonally scale the matrix */ BSscale_diag(pA,pA->diag,procinfo); CHKERR(0); /* set up the communication structure for triangular matrix solution */ Acomm = BSsetup_forward(pA,procinfo); CHKERR(0); /* now factor the matrix */ /* set the initial diagonal to 1.0 */ shifted_diag = 1.0; /* get a copy of the sparse matrix */ f_pA = BScopy_par_mat(pA); CHKERR(0); /* set up a communication structure for factorization */ f_comm = BSsetup_factor(f_pA,procinfo); CHKERR(0); /* factor the matrix until successful */ while (BSfactor(f_pA,f_comm,procinfo) != 0) { CHKERR(0); /* recopy the nonzeroes */ BScopy_nz(pA,f_pA); CHKERR(0); /* increment the diagonal shift */ shifted_diag += 0.1; BSset_diag(f_pA,shifted_diag,procinfo); CHKERR(0); } CHKERR(0); /* set up the rhs and the x vector */ rhs = (FLOAT *) MALLOC(sizeof(FLOAT)*A->num_rows); x = (FLOAT *) MALLOC(sizeof(FLOAT)*A->num_rows); t = A->global_num_rows; t = 1.0/sqrt(t); for (i=0;inum_rows;i++) { rhs[i] = t; x[i] = 0.0; } /* solve it */ BSctx_set_max_it(procinfo,100); BSctx_set_method(procinfo,CG); BSctx_set_tol(procinfo,1.0e-5); num_iter = BSpar_solve(pA,f_pA,Acomm,rhs,x,&residual,procinfo); CHKERR(0); if (procinfo->my_id == 0) { printf("Took %d iterations: residual = %e\n",num_iter,residual); } FREE(rhs); FREE(x); /* free the grid */ free_grid(grid); /* free the spmat */ BSfree_spmat(A); /* free the par mat, etc. */ BSfree_par_mat(pA); BSfree_copy_par_mat(f_pA); BSfree_comm(Acomm); BSfree_comm(f_comm); }