hypre_SStructPMatrix * hypre_SysPFMGCreateInterpOp( hypre_SStructPMatrix *A, hypre_SStructPGrid *cgrid, HYPRE_Int cdir ) { hypre_SStructPMatrix *P; hypre_Index *stencil_shape; HYPRE_Int stencil_size; HYPRE_Int ndim; HYPRE_Int nvars; hypre_SStructStencil **P_stencils; HYPRE_Int i,s; /* set up stencil_shape */ stencil_size = 2; stencil_shape = hypre_CTAlloc(hypre_Index, stencil_size); for (i = 0; i < stencil_size; i++) { hypre_SetIndex3(stencil_shape[i], 0, 0, 0); } hypre_IndexD(stencil_shape[0], cdir) = -1; hypre_IndexD(stencil_shape[1], cdir) = 1; /* set up P_stencils */ ndim = hypre_StructStencilNDim(hypre_SStructPMatrixSStencil(A, 0, 0)); nvars = hypre_SStructPMatrixNVars(A); P_stencils = hypre_CTAlloc(hypre_SStructStencil *, nvars); for (s = 0; s < nvars; s++) { HYPRE_SStructStencilCreate(ndim, stencil_size, &P_stencils[s]); for (i = 0; i < stencil_size; i++) { HYPRE_SStructStencilSetEntry(P_stencils[s], i, stencil_shape[i], s); } } /* create interpolation matrix */ hypre_SStructPMatrixCreate(hypre_SStructPMatrixComm(A), cgrid, P_stencils, &P); hypre_TFree(stencil_shape); return P; }
hypre_SStructPMatrix * hypre_SysPFMGCreateRAPOp( hypre_SStructPMatrix *R, hypre_SStructPMatrix *A, hypre_SStructPMatrix *P, hypre_SStructPGrid *coarse_grid, HYPRE_Int cdir ) { hypre_SStructPMatrix *RAP; HYPRE_Int ndim; HYPRE_Int nvars; hypre_SStructVariable vartype; hypre_SStructStencil **RAP_stencils; hypre_StructMatrix *RAP_s; hypre_StructMatrix *R_s; hypre_StructMatrix *A_s; hypre_StructMatrix *P_s; hypre_Index **RAP_shapes; hypre_StructStencil *sstencil; hypre_Index *shape; HYPRE_Int s; HYPRE_Int *sstencil_sizes; HYPRE_Int stencil_size; hypre_StructGrid *cgrid; HYPRE_Int vi,vj; HYPRE_Int sten_cntr; HYPRE_Int P_stored_as_transpose = 0; ndim = hypre_StructStencilDim(hypre_SStructPMatrixSStencil(A, 0, 0)); nvars = hypre_SStructPMatrixNVars(A); vartype = hypre_SStructPGridVarType(coarse_grid, 0); cgrid = hypre_SStructPGridVTSGrid(coarse_grid, vartype); RAP_stencils = hypre_CTAlloc(hypre_SStructStencil *, nvars); RAP_shapes = hypre_CTAlloc(hypre_Index *, nvars); sstencil_sizes = hypre_CTAlloc(HYPRE_Int, nvars); /*-------------------------------------------------------------------------- * Symmetry within a block is exploited, but not symmetry of the form * A_{vi,vj} = A_{vj,vi}^T. *--------------------------------------------------------------------------*/ for (vi = 0; vi < nvars; vi++) { R_s = hypre_SStructPMatrixSMatrix(R, vi, vi); stencil_size = 0; for (vj = 0; vj < nvars; vj++) { A_s = hypre_SStructPMatrixSMatrix(A, vi, vj); P_s = hypre_SStructPMatrixSMatrix(P, vj, vj); sstencil_sizes[vj] = 0; if (A_s != NULL) { RAP_s = hypre_SemiCreateRAPOp(R_s, A_s, P_s, cgrid, cdir, P_stored_as_transpose); /* Just want stencil for RAP */ hypre_StructMatrixInitializeShell(RAP_s); sstencil = hypre_StructMatrixStencil(RAP_s); shape = hypre_StructStencilShape(sstencil); sstencil_sizes[vj] = hypre_StructStencilSize(sstencil); stencil_size += sstencil_sizes[vj]; RAP_shapes[vj] = hypre_CTAlloc(hypre_Index, sstencil_sizes[vj]); for (s = 0; s < sstencil_sizes[vj]; s++) { hypre_CopyIndex(shape[s],RAP_shapes[vj][s]); } hypre_StructMatrixDestroy(RAP_s); } } HYPRE_SStructStencilCreate(ndim, stencil_size, &RAP_stencils[vi]); sten_cntr = 0; for (vj = 0; vj < nvars; vj++) { if (sstencil_sizes[vj] > 0) { for (s = 0; s < sstencil_sizes[vj]; s++) { HYPRE_SStructStencilSetEntry(RAP_stencils[vi], sten_cntr, RAP_shapes[vj][s], vj); sten_cntr++; } hypre_TFree(RAP_shapes[vj]); } } } /* create RAP Pmatrix */ hypre_SStructPMatrixCreate(hypre_SStructPMatrixComm(A), coarse_grid, RAP_stencils, &RAP); hypre_TFree(RAP_shapes); hypre_TFree(sstencil_sizes); return RAP; }