| /*BHEADER********************************************************************** |
| * (c) 1997 The Regents of the University of California |
| * |
| * See the file COPYRIGHT_and_DISCLAIMER for a complete copyright |
| * notice, contact person, and disclaimer. |
| * |
| * $Revision$ |
| *********************************************************************EHEADER*/ |
| /****************************************************************************** |
| * |
| * Member functions for hypre_StructMatrix class. |
| * |
| *****************************************************************************/ |
| |
| #include "headers.h" |
| |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixExtractPointerByIndex |
| * Returns pointer to data for stencil entry coresponding to |
| * `index' in `matrix'. If the index does not exist in the matrix's |
| * stencil, the NULL pointer is returned. |
| *--------------------------------------------------------------------------*/ |
| |
| double * |
| hypre_StructMatrixExtractPointerByIndex( hypre_StructMatrix *matrix, |
| int b, |
| hypre_Index index ) |
| { |
| hypre_StructStencil *stencil; |
| int rank; |
| |
| stencil = hypre_StructMatrixStencil(matrix); |
| rank = hypre_StructStencilElementRank( stencil, index ); |
| |
| if ( rank >= 0 ) |
| return hypre_StructMatrixBoxData(matrix, b, rank); |
| else |
| return NULL; /* error - invalid index */ |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixCreate |
| *--------------------------------------------------------------------------*/ |
| |
| hypre_StructMatrix * |
| hypre_StructMatrixCreate( MPI_Comm comm, |
| hypre_StructGrid *grid, |
| hypre_StructStencil *user_stencil ) |
| { |
| hypre_StructMatrix *matrix; |
| |
| int i; |
| |
| matrix = hypre_CTAlloc(hypre_StructMatrix, 1); |
| |
| hypre_StructMatrixComm(matrix) = comm; |
| hypre_StructGridRef(grid, &hypre_StructMatrixGrid(matrix)); |
| hypre_StructMatrixUserStencil(matrix) = |
| hypre_StructStencilRef(user_stencil); |
| hypre_StructMatrixDataAlloced(matrix) = 1; |
| hypre_StructMatrixRefCount(matrix) = 1; |
| |
| /* set defaults */ |
| hypre_StructMatrixSymmetric(matrix) = 0; |
| for (i = 0; i < 6; i++) |
| hypre_StructMatrixNumGhost(matrix)[i] = 0; |
| |
| return matrix; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixRef |
| *--------------------------------------------------------------------------*/ |
| |
| hypre_StructMatrix * |
| hypre_StructMatrixRef( hypre_StructMatrix *matrix ) |
| { |
| hypre_StructMatrixRefCount(matrix) ++; |
| |
| return matrix; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixDestroy |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixDestroy( hypre_StructMatrix *matrix ) |
| { |
| int i; |
| int ierr = 0; |
| |
| if (matrix) |
| { |
| hypre_StructMatrixRefCount(matrix) --; |
| if (hypre_StructMatrixRefCount(matrix) == 0) |
| { |
| if (hypre_StructMatrixDataAlloced(matrix)) |
| { |
| hypre_SharedTFree(hypre_StructMatrixData(matrix)); |
| } |
| hypre_CommPkgDestroy(hypre_StructMatrixCommPkg(matrix)); |
| |
| hypre_ForBoxI(i, hypre_StructMatrixDataSpace(matrix)) |
| hypre_TFree(hypre_StructMatrixDataIndices(matrix)[i]); |
| hypre_TFree(hypre_StructMatrixDataIndices(matrix)); |
| |
| hypre_BoxArrayDestroy(hypre_StructMatrixDataSpace(matrix)); |
| |
| hypre_TFree(hypre_StructMatrixSymmElements(matrix)); |
| hypre_StructStencilDestroy(hypre_StructMatrixUserStencil(matrix)); |
| hypre_StructStencilDestroy(hypre_StructMatrixStencil(matrix)); |
| hypre_StructGridDestroy(hypre_StructMatrixGrid(matrix)); |
| |
| hypre_TFree(matrix); |
| } |
| } |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixInitializeShell |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixInitializeShell( hypre_StructMatrix *matrix ) |
| { |
| int ierr = 0; |
| |
| hypre_StructGrid *grid; |
| |
| hypre_StructStencil *user_stencil; |
| hypre_StructStencil *stencil; |
| hypre_Index *stencil_shape; |
| int stencil_size; |
| int num_values; |
| int *symm_elements; |
| |
| int *num_ghost; |
| int extra_ghost[] = {0, 0, 0, 0, 0, 0}; |
| |
| hypre_BoxArray *data_space; |
| hypre_BoxArray *boxes; |
| hypre_Box *box; |
| hypre_Box *data_box; |
| |
| int **data_indices; |
| int data_size; |
| int data_box_volume; |
| |
| int i, j, d; |
| |
| grid = hypre_StructMatrixGrid(matrix); |
| |
| /*----------------------------------------------------------------------- |
| * Set up stencil and num_values: |
| * The stencil is a "symmetrized" version of the user's stencil |
| * as computed by hypre_StructStencilSymmetrize. |
| * |
| * The `symm_elements' array is used to determine what data is |
| * explicitely stored (symm_elements[i] < 0) and what data does is |
| * not explicitely stored (symm_elements[i] >= 0), but is instead |
| * stored as the transpose coefficient at a neighboring grid point. |
| *-----------------------------------------------------------------------*/ |
| |
| if (hypre_StructMatrixStencil(matrix) == NULL) |
| { |
| user_stencil = hypre_StructMatrixUserStencil(matrix); |
| |
| hypre_StructStencilSymmetrize(user_stencil, &stencil, &symm_elements); |
| |
| stencil_shape = hypre_StructStencilShape(stencil); |
| stencil_size = hypre_StructStencilSize(stencil); |
| |
| if (!hypre_StructMatrixSymmetric(matrix)) |
| { |
| /* store all element data */ |
| for (i = 0; i < stencil_size; i++) |
| symm_elements[i] = -1; |
| num_values = stencil_size; |
| } |
| else |
| { |
| num_values = (stencil_size + 1) / 2; |
| } |
| |
| hypre_StructMatrixStencil(matrix) = stencil; |
| hypre_StructMatrixSymmElements(matrix) = symm_elements; |
| hypre_StructMatrixNumValues(matrix) = num_values; |
| } |
| |
| /*----------------------------------------------------------------------- |
| * Set ghost-layer size for symmetric storage |
| * - All stencil coeffs are to be available at each point in the |
| * grid, as well as in the user-specified ghost layer. |
| *-----------------------------------------------------------------------*/ |
| |
| num_ghost = hypre_StructMatrixNumGhost(matrix); |
| stencil = hypre_StructMatrixStencil(matrix); |
| stencil_shape = hypre_StructStencilShape(stencil); |
| stencil_size = hypre_StructStencilSize(stencil); |
| symm_elements = hypre_StructMatrixSymmElements(matrix); |
| |
| for (i = 0; i < stencil_size; i++) |
| { |
| if (symm_elements[i] >= 0) |
| { |
| for (d = 0; d < 3; d++) |
| { |
| extra_ghost[2*d] = |
| hypre_max(extra_ghost[2*d], -hypre_IndexD(stencil_shape[i], d)); |
| extra_ghost[2*d + 1] = |
| hypre_max(extra_ghost[2*d + 1], hypre_IndexD(stencil_shape[i], d)); |
| } |
| } |
| } |
| |
| for (d = 0; d < 3; d++) |
| { |
| num_ghost[2*d] += extra_ghost[2*d]; |
| num_ghost[2*d + 1] += extra_ghost[2*d + 1]; |
| } |
| |
| /*----------------------------------------------------------------------- |
| * Set up data_space |
| *-----------------------------------------------------------------------*/ |
| |
| if (hypre_StructMatrixDataSpace(matrix) == NULL) |
| { |
| boxes = hypre_StructGridBoxes(grid); |
| data_space = hypre_BoxArrayCreate(hypre_BoxArraySize(boxes)); |
| |
| hypre_ForBoxI(i, boxes) |
| { |
| box = hypre_BoxArrayBox(boxes, i); |
| data_box = hypre_BoxArrayBox(data_space, i); |
| |
| hypre_CopyBox(box, data_box); |
| for (d = 0; d < 3; d++) |
| { |
| hypre_BoxIMinD(data_box, d) -= num_ghost[2*d]; |
| hypre_BoxIMaxD(data_box, d) += num_ghost[2*d + 1]; |
| } |
| } |
| |
| hypre_StructMatrixDataSpace(matrix) = data_space; |
| } |
| |
| /*----------------------------------------------------------------------- |
| * Set up data_indices array and data-size |
| *-----------------------------------------------------------------------*/ |
| |
| if (hypre_StructMatrixDataIndices(matrix) == NULL) |
| { |
| data_space = hypre_StructMatrixDataSpace(matrix); |
| data_indices = hypre_CTAlloc(int *, hypre_BoxArraySize(data_space)); |
| |
| data_size = 0; |
| hypre_ForBoxI(i, data_space) |
| { |
| data_box = hypre_BoxArrayBox(data_space, i); |
| data_box_volume = hypre_BoxVolume(data_box); |
| |
| data_indices[i] = hypre_CTAlloc(int, stencil_size); |
| |
| /* set pointers for "stored" coefficients */ |
| for (j = 0; j < stencil_size; j++) |
| { |
| if (symm_elements[j] < 0) |
| { |
| data_indices[i][j] = data_size; |
| data_size += data_box_volume; |
| } |
| } |
| |
| /* set pointers for "symmetric" coefficients */ |
| for (j = 0; j < stencil_size; j++) |
| { |
| if (symm_elements[j] >= 0) |
| { |
| data_indices[i][j] = data_indices[i][symm_elements[j]] + |
| hypre_BoxOffsetDistance(data_box, stencil_shape[j]); |
| } |
| } |
| } |
| |
| hypre_StructMatrixDataIndices(matrix) = data_indices; |
| hypre_StructMatrixDataSize(matrix) = data_size; |
| } |
| |
| /*----------------------------------------------------------------------- |
| * Set total number of nonzero coefficients |
| *-----------------------------------------------------------------------*/ |
| |
| hypre_StructMatrixGlobalSize(matrix) = |
| hypre_StructGridGlobalSize(grid) * stencil_size; |
| |
| /*----------------------------------------------------------------------- |
| * Return |
| *-----------------------------------------------------------------------*/ |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixInitializeData |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixInitializeData( hypre_StructMatrix *matrix, |
| double *data ) |
| { |
| int ierr = 0; |
| |
| hypre_BoxArray *data_boxes; |
| hypre_Box *data_box; |
| hypre_Index loop_size; |
| hypre_Index index; |
| hypre_IndexRef start; |
| hypre_Index stride; |
| double *datap; |
| int datai; |
| int i; |
| int loopi, loopj, loopk; |
| |
| hypre_StructMatrixData(matrix) = data; |
| hypre_StructMatrixDataAlloced(matrix) = 0; |
| |
| /*------------------------------------------------- |
| * If the matrix has a diagonal, set these entries |
| * to 1 everywhere. This reduces the complexity of |
| * many computations by eliminating divide-by-zero |
| * in the ghost region. |
| *-------------------------------------------------*/ |
| |
| hypre_SetIndex(index, 0, 0, 0); |
| hypre_SetIndex(stride, 1, 1, 1); |
| |
| data_boxes = hypre_StructMatrixDataSpace(matrix); |
| hypre_ForBoxI(i, data_boxes) |
| { |
| datap = hypre_StructMatrixExtractPointerByIndex(matrix, i, index); |
| |
| if (datap) |
| { |
| data_box = hypre_BoxArrayBox(data_boxes, i); |
| start = hypre_BoxIMin(data_box); |
| |
| hypre_BoxGetSize(data_box, loop_size); |
| |
| hypre_BoxLoop1Begin(loop_size, |
| data_box, start, stride, datai); |
| #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,datai |
| #include "hypre_box_smp_forloop.h" |
| hypre_BoxLoop1For(loopi, loopj, loopk, datai) |
| { |
| datap[datai] = 1.0; |
| } |
| hypre_BoxLoop1End(datai); |
| } |
| } |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixInitialize |
| *--------------------------------------------------------------------------*/ |
| int |
| hypre_StructMatrixInitialize( hypre_StructMatrix *matrix ) |
| { |
| int ierr = 0; |
| |
| double *data; |
| |
| ierr = hypre_StructMatrixInitializeShell(matrix); |
| |
| data = hypre_SharedCTAlloc(double, hypre_StructMatrixDataSize(matrix)); |
| hypre_StructMatrixInitializeData(matrix, data); |
| hypre_StructMatrixDataAlloced(matrix) = 1; |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixSetValues |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixSetValues( hypre_StructMatrix *matrix, |
| hypre_Index grid_index, |
| int num_stencil_indices, |
| int *stencil_indices, |
| double *values, |
| int add_to ) |
| { |
| int ierr = 0; |
| |
| hypre_BoxArray *boxes; |
| hypre_Box *box; |
| |
| double *matp; |
| |
| int i, s; |
| |
| boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(matrix)); |
| |
| hypre_ForBoxI(i, boxes) |
| { |
| box = hypre_BoxArrayBox(boxes, i); |
| |
| if ((hypre_IndexX(grid_index) >= hypre_BoxIMinX(box)) && |
| (hypre_IndexX(grid_index) <= hypre_BoxIMaxX(box)) && |
| (hypre_IndexY(grid_index) >= hypre_BoxIMinY(box)) && |
| (hypre_IndexY(grid_index) <= hypre_BoxIMaxY(box)) && |
| (hypre_IndexZ(grid_index) >= hypre_BoxIMinZ(box)) && |
| (hypre_IndexZ(grid_index) <= hypre_BoxIMaxZ(box)) ) |
| { |
| if (add_to) |
| { |
| for (s = 0; s < num_stencil_indices; s++) |
| { |
| matp = hypre_StructMatrixBoxDataValue(matrix, i, |
| stencil_indices[s], |
| grid_index); |
| *matp += values[s]; |
| } |
| } |
| else |
| { |
| for (s = 0; s < num_stencil_indices; s++) |
| { |
| matp = hypre_StructMatrixBoxDataValue(matrix, i, |
| stencil_indices[s], |
| grid_index); |
| *matp = values[s]; |
| } |
| } |
| } |
| } |
| |
| return(ierr); |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixSetBoxValues |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixSetBoxValues( hypre_StructMatrix *matrix, |
| hypre_Box *value_box, |
| int num_stencil_indices, |
| int *stencil_indices, |
| double *values, |
| int add_to ) |
| { |
| int ierr = 0; |
| |
| hypre_BoxArray *grid_boxes; |
| hypre_Box *grid_box; |
| hypre_BoxArray *box_array; |
| hypre_Box *box; |
| |
| hypre_BoxArray *data_space; |
| hypre_Box *data_box; |
| hypre_IndexRef data_start; |
| hypre_Index data_stride; |
| int datai; |
| double *datap; |
| |
| hypre_Box *dval_box; |
| hypre_Index dval_start; |
| hypre_Index dval_stride; |
| int dvali; |
| |
| hypre_Index loop_size; |
| |
| int i, s; |
| int loopi, loopj, loopk; |
| |
| /*----------------------------------------------------------------------- |
| * Set up `box_array' by intersecting `box' with the grid boxes |
| *-----------------------------------------------------------------------*/ |
| |
| grid_boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(matrix)); |
| box_array = hypre_BoxArrayCreate(hypre_BoxArraySize(grid_boxes)); |
| box = hypre_BoxCreate(); |
| hypre_ForBoxI(i, grid_boxes) |
| { |
| grid_box = hypre_BoxArrayBox(grid_boxes, i); |
| hypre_IntersectBoxes(value_box, grid_box, box); |
| hypre_CopyBox(box, hypre_BoxArrayBox(box_array, i)); |
| } |
| hypre_BoxDestroy(box); |
| |
| /*----------------------------------------------------------------------- |
| * Set the matrix coefficients |
| *-----------------------------------------------------------------------*/ |
| |
| if (box_array) |
| { |
| data_space = hypre_StructMatrixDataSpace(matrix); |
| hypre_SetIndex(data_stride, 1, 1, 1); |
| |
| dval_box = hypre_BoxDuplicate(value_box); |
| hypre_BoxIMinD(dval_box, 0) *= num_stencil_indices; |
| hypre_BoxIMaxD(dval_box, 0) *= num_stencil_indices; |
| hypre_BoxIMaxD(dval_box, 0) += num_stencil_indices - 1; |
| hypre_SetIndex(dval_stride, num_stencil_indices, 1, 1); |
| |
| hypre_ForBoxI(i, box_array) |
| { |
| box = hypre_BoxArrayBox(box_array, i); |
| data_box = hypre_BoxArrayBox(data_space, i); |
| |
| /* if there was an intersection */ |
| if (box) |
| { |
| data_start = hypre_BoxIMin(box); |
| hypre_CopyIndex(data_start, dval_start); |
| hypre_IndexD(dval_start, 0) *= num_stencil_indices; |
| |
| for (s = 0; s < num_stencil_indices; s++) |
| { |
| datap = hypre_StructMatrixBoxData(matrix, i, |
| stencil_indices[s]); |
| |
| hypre_BoxGetSize(box, loop_size); |
| |
| if (add_to) |
| { |
| hypre_BoxLoop2Begin(loop_size, |
| data_box,data_start,data_stride,datai, |
| dval_box,dval_start,dval_stride,dvali); |
| #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,datai,dvali |
| #include "hypre_box_smp_forloop.h" |
| hypre_BoxLoop2For(loopi, loopj, loopk, datai, dvali) |
| { |
| datap[datai] += values[dvali]; |
| } |
| hypre_BoxLoop2End(datai, dvali); |
| } |
| else |
| { |
| hypre_BoxLoop2Begin(loop_size, |
| data_box,data_start,data_stride,datai, |
| dval_box,dval_start,dval_stride,dvali); |
| #define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,datai,dvali |
| #include "hypre_box_smp_forloop.h" |
| hypre_BoxLoop2For(loopi, loopj, loopk, datai, dvali) |
| { |
| datap[datai] = values[dvali]; |
| } |
| hypre_BoxLoop2End(datai, dvali); |
| } |
| |
| hypre_IndexD(dval_start, 0) ++; |
| } |
| } |
| } |
| |
| hypre_BoxDestroy(dval_box); |
| } |
| |
| hypre_BoxArrayDestroy(box_array); |
| |
| return(ierr); |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixAssemble |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixAssemble( hypre_StructMatrix *matrix ) |
| { |
| int ierr = 0; |
| |
| int *num_ghost = hypre_StructMatrixNumGhost(matrix); |
| |
| hypre_BoxArrayArray *send_boxes; |
| hypre_BoxArrayArray *recv_boxes; |
| int **send_processes; |
| int **recv_processes; |
| |
| hypre_Index unit_stride; |
| |
| hypre_CommPkg *comm_pkg; |
| |
| hypre_CommHandle *comm_handle; |
| |
| /*----------------------------------------------------------------------- |
| * If the CommPkg has not been set up, set it up |
| *-----------------------------------------------------------------------*/ |
| |
| comm_pkg = hypre_StructMatrixCommPkg(matrix); |
| |
| if (!comm_pkg) |
| { |
| hypre_SetIndex(unit_stride, 1, 1, 1); |
| |
| hypre_CreateCommInfoFromNumGhost(hypre_StructMatrixGrid(matrix), |
| num_ghost, |
| &send_boxes, &recv_boxes, |
| &send_processes, &recv_processes); |
| |
| comm_pkg = hypre_CommPkgCreate(send_boxes, recv_boxes, |
| unit_stride, unit_stride, |
| hypre_StructMatrixDataSpace(matrix), |
| hypre_StructMatrixDataSpace(matrix), |
| send_processes, recv_processes, |
| hypre_StructMatrixNumValues(matrix), |
| hypre_StructMatrixComm(matrix), |
| hypre_StructGridPeriodic( |
| hypre_StructMatrixGrid(matrix))); |
| |
| hypre_StructMatrixCommPkg(matrix) = comm_pkg; |
| } |
| |
| /*----------------------------------------------------------------------- |
| * Update the ghost data |
| *-----------------------------------------------------------------------*/ |
| |
| hypre_InitializeCommunication(comm_pkg, |
| hypre_StructMatrixData(matrix), |
| hypre_StructMatrixData(matrix), |
| &comm_handle); |
| hypre_FinalizeCommunication(comm_handle); |
| |
| return(ierr); |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixSetNumGhost |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixSetNumGhost( hypre_StructMatrix *matrix, |
| int *num_ghost ) |
| { |
| int ierr = 0; |
| int i; |
| |
| for (i = 0; i < 6; i++) |
| hypre_StructMatrixNumGhost(matrix)[i] = num_ghost[i]; |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixPrint |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixPrint( char *filename, |
| hypre_StructMatrix *matrix, |
| int all ) |
| { |
| int ierr = 0; |
| |
| FILE *file; |
| char new_filename[255]; |
| |
| hypre_StructGrid *grid; |
| hypre_BoxArray *boxes; |
| |
| hypre_StructStencil *stencil; |
| hypre_Index *stencil_shape; |
| |
| int num_values; |
| |
| hypre_BoxArray *data_space; |
| |
| int *symm_elements; |
| |
| int i, j; |
| |
| int myid; |
| |
| /*---------------------------------------- |
| * Open file |
| *----------------------------------------*/ |
| |
| #ifdef HYPRE_USE_PTHREADS |
| #if MPI_Comm_rank == hypre_thread_MPI_Comm_rank |
| #undef MPI_Comm_rank |
| #endif |
| #endif |
| |
| MPI_Comm_rank(hypre_StructMatrixComm(matrix), &myid); |
| |
| sprintf(new_filename, "%s.%05d", filename, myid); |
| |
| if ((file = fopen(new_filename, "w")) == NULL) |
| { |
| printf("Error: can't open output file %s\n", new_filename); |
| exit(1); |
| } |
| |
| /*---------------------------------------- |
| * Print header info |
| *----------------------------------------*/ |
| |
| fprintf(file, "StructMatrix\n"); |
| |
| fprintf(file, "\nSymmetric: %d\n", hypre_StructMatrixSymmetric(matrix)); |
| |
| /* print grid info */ |
| fprintf(file, "\nGrid:\n"); |
| grid = hypre_StructMatrixGrid(matrix); |
| hypre_StructGridPrint(file, grid); |
| |
| /* print stencil info */ |
| fprintf(file, "\nStencil:\n"); |
| stencil = hypre_StructMatrixStencil(matrix); |
| stencil_shape = hypre_StructStencilShape(stencil); |
| |
| num_values = hypre_StructMatrixNumValues(matrix); |
| symm_elements = hypre_StructMatrixSymmElements(matrix); |
| fprintf(file, "%d\n", num_values); |
| j = 0; |
| for (i = 0; i < hypre_StructStencilSize(stencil); i++) |
| { |
| if (symm_elements[i] < 0) |
| { |
| fprintf(file, "%d: %d %d %d\n", j++, |
| hypre_IndexX(stencil_shape[i]), |
| hypre_IndexY(stencil_shape[i]), |
| hypre_IndexZ(stencil_shape[i])); |
| } |
| } |
| |
| /*---------------------------------------- |
| * Print data |
| *----------------------------------------*/ |
| |
| data_space = hypre_StructMatrixDataSpace(matrix); |
| |
| if (all) |
| boxes = data_space; |
| else |
| boxes = hypre_StructGridBoxes(grid); |
| |
| fprintf(file, "\nData:\n"); |
| hypre_PrintBoxArrayData(file, boxes, data_space, num_values, |
| hypre_StructMatrixData(matrix)); |
| |
| /*---------------------------------------- |
| * Close file |
| *----------------------------------------*/ |
| |
| fflush(file); |
| fclose(file); |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixMigrate |
| *--------------------------------------------------------------------------*/ |
| |
| int |
| hypre_StructMatrixMigrate( hypre_StructMatrix *from_matrix, |
| hypre_StructMatrix *to_matrix ) |
| { |
| hypre_BoxArrayArray *send_boxes; |
| hypre_BoxArrayArray *recv_boxes; |
| int **send_processes; |
| int **recv_processes; |
| |
| hypre_Index unit_stride; |
| |
| hypre_CommPkg *comm_pkg; |
| hypre_CommHandle *comm_handle; |
| |
| int ierr = 0; |
| |
| /*------------------------------------------------------ |
| * Set up hypre_CommPkg |
| *------------------------------------------------------*/ |
| |
| hypre_SetIndex(unit_stride, 1, 1, 1); |
| |
| hypre_CreateCommInfoFromGrids(hypre_StructMatrixGrid(from_matrix), |
| hypre_StructMatrixGrid(to_matrix), |
| &send_boxes, &recv_boxes, |
| &send_processes, &recv_processes); |
| |
| comm_pkg = hypre_CommPkgCreate(send_boxes, recv_boxes, |
| unit_stride, unit_stride, |
| hypre_StructMatrixDataSpace(from_matrix), |
| hypre_StructMatrixDataSpace(to_matrix), |
| send_processes, recv_processes, |
| hypre_StructMatrixNumValues(from_matrix), |
| hypre_StructMatrixComm(from_matrix), |
| hypre_StructGridPeriodic( |
| hypre_StructMatrixGrid(from_matrix))); |
| /* is this correct for periodic? */ |
| |
| /*----------------------------------------------------------------------- |
| * Migrate the matrix data |
| *-----------------------------------------------------------------------*/ |
| |
| hypre_InitializeCommunication(comm_pkg, |
| hypre_StructMatrixData(from_matrix), |
| hypre_StructMatrixData(to_matrix), |
| &comm_handle); |
| hypre_FinalizeCommunication(comm_handle); |
| |
| return ierr; |
| } |
| |
| /*-------------------------------------------------------------------------- |
| * hypre_StructMatrixRead |
| *--------------------------------------------------------------------------*/ |
| |
| hypre_StructMatrix * |
| hypre_StructMatrixRead( MPI_Comm comm, |
| char *filename, |
| int *num_ghost ) |
| { |
| FILE *file; |
| char new_filename[255]; |
| |
| hypre_StructMatrix *matrix; |
| |
| hypre_StructGrid *grid; |
| hypre_BoxArray *boxes; |
| int dim; |
| |
| hypre_StructStencil *stencil; |
| hypre_Index *stencil_shape; |
| int stencil_size; |
| |
| int num_values; |
| |
| hypre_BoxArray *data_space; |
| |
| int symmetric; |
| |
| int i, idummy; |
| |
| int myid; |
| |
| /*---------------------------------------- |
| * Open file |
| *----------------------------------------*/ |
| |
| #ifdef HYPRE_USE_PTHREADS |
| #if MPI_Comm_rank == hypre_thread_MPI_Comm_rank |
| #undef MPI_Comm_rank |
| #endif |
| #endif |
| |
| MPI_Comm_rank(comm, &myid ); |
| |
| sprintf(new_filename, "%s.%05d", filename, myid); |
| |
| if ((file = fopen(new_filename, "r")) == NULL) |
| { |
| printf("Error: can't open output file %s\n", new_filename); |
| exit(1); |
| } |
| |
| /*---------------------------------------- |
| * Read header info |
| *----------------------------------------*/ |
| |
| fscanf(file, "StructMatrix\n"); |
| |
| fscanf(file, "\nSymmetric: %d\n", &symmetric); |
| |
| /* read grid info */ |
| fscanf(file, "\nGrid:\n"); |
| hypre_StructGridRead(comm,file,&grid); |
| |
| /* read stencil info */ |
| fscanf(file, "\nStencil:\n"); |
| dim = hypre_StructGridDim(grid); |
| fscanf(file, "%d\n", &stencil_size); |
| stencil_shape = hypre_CTAlloc(hypre_Index, stencil_size); |
| for (i = 0; i < stencil_size; i++) |
| { |
| fscanf(file, "%d: %d %d %d\n", &idummy, |
| &hypre_IndexX(stencil_shape[i]), |
| &hypre_IndexY(stencil_shape[i]), |
| &hypre_IndexZ(stencil_shape[i])); |
| } |
| stencil = hypre_StructStencilCreate(dim, stencil_size, stencil_shape); |
| |
| /*---------------------------------------- |
| * Initialize the matrix |
| *----------------------------------------*/ |
| |
| matrix = hypre_StructMatrixCreate(comm, grid, stencil); |
| hypre_StructMatrixSymmetric(matrix) = symmetric; |
| hypre_StructMatrixSetNumGhost(matrix, num_ghost); |
| hypre_StructMatrixInitialize(matrix); |
| |
| /*---------------------------------------- |
| * Read data |
| *----------------------------------------*/ |
| |
| boxes = hypre_StructGridBoxes(grid); |
| data_space = hypre_StructMatrixDataSpace(matrix); |
| num_values = hypre_StructMatrixNumValues(matrix); |
| |
| fscanf(file, "\nData:\n"); |
| hypre_ReadBoxArrayData(file, boxes, data_space, num_values, |
| hypre_StructMatrixData(matrix)); |
| |
| /*---------------------------------------- |
| * Assemble the matrix |
| *----------------------------------------*/ |
| |
| hypre_StructMatrixAssemble(matrix); |
| |
| /*---------------------------------------- |
| * Close file |
| *----------------------------------------*/ |
| |
| fclose(file); |
| |
| return matrix; |
| } |
| |