/* Function: hypre_CSRMatrixElimCreate Prepare the Ae matrix: count nnz, initialize I, allocate J and data. */ void hypre_CSRMatrixElimCreate(hypre_CSRMatrix *A, hypre_CSRMatrix *Ae, HYPRE_Int nrows, HYPRE_Int *rows, HYPRE_Int ncols, HYPRE_Int *cols, HYPRE_Int *col_mark) { HYPRE_Int i, j, col; HYPRE_Int A_beg, A_end; HYPRE_Int *A_i = hypre_CSRMatrixI(A); HYPRE_Int *A_j = hypre_CSRMatrixJ(A); HYPRE_Int A_rows = hypre_CSRMatrixNumRows(A); hypre_CSRMatrixI(Ae) = hypre_TAlloc(HYPRE_Int, A_rows+1); HYPRE_Int *Ae_i = hypre_CSRMatrixI(Ae); HYPRE_Int nnz = 0; for (i = 0; i < A_rows; i++) { Ae_i[i] = nnz; A_beg = A_i[i]; A_end = A_i[i+1]; if (hypre_BinarySearch(rows, i, nrows) >= 0) { /* full row */ nnz += A_end - A_beg; if (col_mark) { for (j = A_beg; j < A_end; j++) { col_mark[A_j[j]] = 1; } } } else { /* count columns */ for (j = A_beg; j < A_end; j++) { col = A_j[j]; if (hypre_BinarySearch(cols, col, ncols) >= 0) { nnz++; if (col_mark) { col_mark[col] = 1; } } } } } Ae_i[A_rows] = nnz; hypre_CSRMatrixJ(Ae) = hypre_TAlloc(HYPRE_Int, nnz); hypre_CSRMatrixData(Ae) = hypre_TAlloc(HYPRE_Real, nnz); hypre_CSRMatrixNumNonzeros(Ae) = nnz; }
HYPRE_Int hypre_MPI_Allgatherv( void *sendbuf, HYPRE_Int sendcount, hypre_MPI_Datatype sendtype, void *recvbuf, HYPRE_Int *recvcounts, HYPRE_Int *displs, hypre_MPI_Datatype recvtype, hypre_MPI_Comm comm ) { hypre_int *mpi_recvcounts, *mpi_displs, csize; HYPRE_Int i; HYPRE_Int ierr; MPI_Comm_size(comm, &csize); mpi_recvcounts = hypre_TAlloc(hypre_int, csize); mpi_displs = hypre_TAlloc(hypre_int, csize); for (i = 0; i < csize; i++) { mpi_recvcounts[i] = (hypre_int) recvcounts[i]; mpi_displs[i] = (hypre_int) displs[i]; } ierr = (HYPRE_Int) MPI_Allgatherv(sendbuf, (hypre_int)sendcount, sendtype, recvbuf, mpi_recvcounts, mpi_displs, recvtype, comm); hypre_TFree(mpi_recvcounts); hypre_TFree(mpi_displs); return ierr; }
HYPRE_Int HYPRE_SStructSplitCreate( MPI_Comm comm, HYPRE_SStructSolver *solver_ptr ) { hypre_SStructSolver *solver; solver = hypre_TAlloc(hypre_SStructSolver, 1); (solver -> y) = NULL; (solver -> nparts) = 0; (solver -> nvars) = 0; (solver -> smatvec_data) = NULL; (solver -> ssolver_solve) = NULL; (solver -> ssolver_destroy) = NULL; (solver -> ssolver_data) = NULL; (solver -> tol) = 1.0e-06; (solver -> max_iter) = 200; (solver -> zero_guess) = 0; (solver -> num_iterations) = 0; (solver -> rel_norm) = 0; (solver -> ssolver) = HYPRE_SMG; (solver -> matvec_data) = NULL; *solver_ptr = solver; return hypre_error_flag; }
HYPRE_Int hypre_AMESolve(void *esolver) { hypre_AMEData *ame_data = esolver; HYPRE_Int nit; lobpcg_BLASLAPACKFunctions blap_fn; lobpcg_Tolerance lobpcg_tol; HYPRE_Real *residuals; #ifdef HYPRE_USING_ESSL blap_fn.dsygv = dsygv; blap_fn.dpotrf = dpotrf; #else blap_fn.dsygv = hypre_F90_NAME_LAPACK(dsygv,DSYGV); blap_fn.dpotrf = hypre_F90_NAME_LAPACK(dpotrf,DPOTRF); #endif lobpcg_tol.relative = ame_data -> tol; lobpcg_tol.absolute = ame_data -> tol; residuals = hypre_TAlloc(HYPRE_Real, ame_data -> block_size); lobpcg_solve((mv_MultiVectorPtr) ame_data -> eigenvectors, esolver, hypre_AMEMultiOperatorA, esolver, hypre_AMEMultiOperatorM, esolver, hypre_AMEMultiOperatorB, NULL, blap_fn, lobpcg_tol, ame_data -> maxit, ame_data -> print_level, &nit, ame_data -> eigenvalues, NULL, ame_data -> block_size, residuals, NULL, ame_data -> block_size); hypre_TFree(residuals); return hypre_error_flag; }
int hypre_CommInfoCreate( hypre_BoxArrayArray *send_boxes, hypre_BoxArrayArray *recv_boxes, int **send_procs, int **recv_procs, int **send_rboxnums, int **recv_rboxnums, hypre_BoxArrayArray *send_rboxes, hypre_CommInfo **comm_info_ptr ) { int ierr = 0; hypre_CommInfo *comm_info; comm_info = hypre_TAlloc(hypre_CommInfo, 1); hypre_CommInfoSendBoxes(comm_info) = send_boxes; hypre_CommInfoRecvBoxes(comm_info) = recv_boxes; hypre_CommInfoSendProcesses(comm_info) = send_procs; hypre_CommInfoRecvProcesses(comm_info) = recv_procs; hypre_CommInfoSendRBoxnums(comm_info) = send_rboxnums; hypre_CommInfoRecvRBoxnums(comm_info) = recv_rboxnums; hypre_CommInfoSendRBoxes(comm_info) = send_rboxes; hypre_SetIndex(hypre_CommInfoSendStride(comm_info), 1, 1, 1); hypre_SetIndex(hypre_CommInfoRecvStride(comm_info), 1, 1, 1); *comm_info_ptr = comm_info; return ierr; }
void hypre_sort_and_create_inverse_map( HYPRE_Int *in, HYPRE_Int len, HYPRE_Int **out, hypre_UnorderedIntMap *inverse_map) { if (len == 0) { return; } #ifdef HYPRE_PROFILE hypre_profile_times[HYPRE_TIMER_ID_MERGE] -= hypre_MPI_Wtime(); #endif HYPRE_Int *temp = hypre_TAlloc(HYPRE_Int, len); hypre_merge_sort(in, temp, len, out); hypre_UnorderedIntMapCreate(inverse_map, 2*len, 16*hypre_NumThreads()); HYPRE_Int i; #pragma omp parallel for HYPRE_SMP_SCHEDULE for (i = 0; i < len; i++) { HYPRE_Int old = hypre_UnorderedIntMapPutIfAbsent(inverse_map, (*out)[i], i); assert(old == HYPRE_HOPSCOTCH_HASH_EMPTY); #ifdef DBG_MERGE_SORT if (hypre_UnorderedIntMapGet(inverse_map, (*out)[i]) != i) { fprintf(stderr, "%d %d\n", i, (*out)[i]); assert(false); } #endif } #ifdef DBG_MERGE_SORT std::unordered_map<HYPRE_Int, HYPRE_Int> inverse_map2(len); for (HYPRE_Int i = 0; i < len; ++i) { inverse_map2[(*out)[i]] = i; if (hypre_UnorderedIntMapGet(inverse_map, (*out)[i]) != i) { fprintf(stderr, "%d %d\n", i, (*out)[i]); assert(false); } } assert(hypre_UnorderedIntMapSize(inverse_map) == len); #endif if (*out == in) { hypre_TFree(temp); } else { hypre_TFree(in); } #ifdef HYPRE_PROFILE hypre_profile_times[HYPRE_TIMER_ID_MERGE] += hypre_MPI_Wtime(); #endif }
void hypre_UnorderedIntSetCreate( hypre_UnorderedIntSet *s, HYPRE_Int inCapacity, HYPRE_Int concurrencyLevel) { s->segmentMask = NearestPowerOfTwo(concurrencyLevel) - 1; if (inCapacity < s->segmentMask + 1) { inCapacity = s->segmentMask + 1; } //ADJUST INPUT ............................ HYPRE_Int adjInitCap = NearestPowerOfTwo(inCapacity+4096); HYPRE_Int num_buckets = adjInitCap + HYPRE_HOPSCOTCH_HASH_INSERT_RANGE + 1; s->bucketMask = adjInitCap - 1; HYPRE_Int i; //ALLOCATE THE SEGMENTS ................... #ifdef HYPRE_CONCURRENT_HOPSCOTCH s->segments = hypre_TAlloc(hypre_HopscotchSegment, s->segmentMask + 1); for (i = 0; i <= s->segmentMask; ++i) { InitSegment(&s->segments[i]); } #endif s->hopInfo = hypre_TAlloc(hypre_uint, num_buckets); s->key = hypre_TAlloc(HYPRE_Int, num_buckets); s->hash = hypre_TAlloc(HYPRE_Int, num_buckets); #ifdef HYPRE_CONCURRENT_HOPSCOTCH #pragma omp parallel for #endif for (i = 0; i < num_buckets; ++i) { s->hopInfo[i] = 0; s->hash[i] = HYPRE_HOPSCOTCH_HASH_EMPTY; } }
hypre_BoxArray * hypre_BoxArrayCreate( int size ) { hypre_BoxArray *box_array; box_array = hypre_TAlloc(hypre_BoxArray, 1); hypre_BoxArrayBoxes(box_array) = hypre_CTAlloc(hypre_Box, size); hypre_BoxArraySize(box_array) = size; hypre_BoxArrayAllocSize(box_array) = size; return box_array; }
hypre_Box * hypre_BoxCreate( ) { hypre_Box *box; #if 1 box = hypre_TAlloc(hypre_Box, 1); #else box = hypre_BoxAlloc(); #endif return box; }
HYPRE_Int hypre_InitMemoryDebugDML( HYPRE_Int id ) { HYPRE_Int *iptr; /* do this to get the Debug Malloc Library started/initialized */ iptr = hypre_TAlloc(HYPRE_Int, 1); hypre_TFree(iptr); dmalloc_logpath = dmalloc_logpath_memory; hypre_sprintf(dmalloc_logpath, "dmalloc.log.%04d", id); return 0; }
HYPRE_Int HYPRE_SStructGraphSetFEMSparsity( HYPRE_SStructGraph graph, HYPRE_Int part, HYPRE_Int nsparse, HYPRE_Int *sparsity ) { HYPRE_Int *fem_sparse_i; HYPRE_Int *fem_sparse_j; HYPRE_Int s; hypre_SStructGraphFEMPNSparse(graph, part) = nsparse; fem_sparse_i = hypre_TAlloc(HYPRE_Int, nsparse); fem_sparse_j = hypre_TAlloc(HYPRE_Int, nsparse); for (s = 0; s < nsparse; s++) { fem_sparse_i[s] = sparsity[2*s]; fem_sparse_j[s] = sparsity[2*s+1]; } hypre_SStructGraphFEMPSparseI(graph, part) = fem_sparse_i; hypre_SStructGraphFEMPSparseJ(graph, part) = fem_sparse_j; return hypre_error_flag; }
HYPRE_Int hypre_MPI_Scatterv(void *sendbuf, HYPRE_Int *sendcounts, HYPRE_Int *displs, hypre_MPI_Datatype sendtype, void *recvbuf, HYPRE_Int recvcount, hypre_MPI_Datatype recvtype, HYPRE_Int root, hypre_MPI_Comm comm ) { hypre_int *mpi_sendcounts = NULL; hypre_int *mpi_displs = NULL; hypre_int csize, croot; HYPRE_Int i; HYPRE_Int ierr; MPI_Comm_size(comm, &csize); MPI_Comm_rank(comm, &croot); if (croot == (hypre_int) root) { mpi_sendcounts = hypre_TAlloc(hypre_int, csize); mpi_displs = hypre_TAlloc(hypre_int, csize); for (i = 0; i < csize; i++) { mpi_sendcounts[i] = (hypre_int) sendcounts[i]; mpi_displs[i] = (hypre_int) displs[i]; } } ierr = (HYPRE_Int) MPI_Scatterv(sendbuf, mpi_sendcounts, mpi_displs, sendtype, recvbuf, (hypre_int) recvcount, recvtype, (hypre_int) root, comm); hypre_TFree(mpi_sendcounts); hypre_TFree(mpi_displs); return ierr; }
int hypre_RankLinkCreate( int rank, hypre_RankLink **rank_link_ptr) { hypre_RankLink *rank_link; rank_link = hypre_TAlloc(hypre_RankLink, 1); hypre_RankLinkRank(rank_link) = rank; hypre_RankLinkNext(rank_link) = NULL; *rank_link_ptr = rank_link; return 0; }
void hypre_UnorderedIntMapCreate( hypre_UnorderedIntMap *m, HYPRE_Int inCapacity, HYPRE_Int concurrencyLevel) { m->segmentMask = NearestPowerOfTwo(concurrencyLevel) - 1; if (inCapacity < m->segmentMask + 1) { inCapacity = m->segmentMask + 1; } //ADJUST INPUT ............................ HYPRE_Int adjInitCap = NearestPowerOfTwo(inCapacity+4096); HYPRE_Int num_buckets = adjInitCap + HYPRE_HOPSCOTCH_HASH_INSERT_RANGE + 1; m->bucketMask = adjInitCap - 1; HYPRE_Int i; //ALLOCATE THE SEGMENTS ................... #ifdef HYPRE_CONCURRENT_HOPSCOTCH m->segments = hypre_TAlloc(hypre_HopscotchSegment, m->segmentMask + 1); for (i = 0; i <= m->segmentMask; i++) { InitSegment(&m->segments[i]); } #endif m->table = hypre_TAlloc(hypre_HopscotchBucket, num_buckets); #ifdef HYPRE_CONCURRENT_HOPSCOTCH #pragma omp parallel for #endif for (i = 0; i < num_buckets; i++) { InitBucket(&m->table[i]); } }
int HYPRE_SStructGraphCreate( MPI_Comm comm, HYPRE_SStructGrid grid, HYPRE_SStructGraph *graph_ptr ) { int ierr = 0; hypre_SStructGraph *graph; int nparts; hypre_SStructStencil ***stencils; hypre_SStructPGrid **pgrids; int nvars; int part, var; graph = hypre_TAlloc(hypre_SStructGraph, 1); hypre_SStructGraphComm(graph) = comm; hypre_SStructGraphNDim(graph) = hypre_SStructGridNDim(grid); hypre_SStructGridRef(grid, &hypre_SStructGraphGrid(graph)); nparts = hypre_SStructGridNParts(grid); hypre_SStructGraphNParts(graph) = nparts; pgrids = hypre_SStructGridPGrids(grid); hypre_SStructGraphPGrids(graph) = pgrids; stencils = hypre_TAlloc(hypre_SStructStencil **, nparts); for (part = 0; part < nparts; part++) { nvars = hypre_SStructPGridNVars(pgrids[part]); stencils[part] = hypre_TAlloc(hypre_SStructStencil *, nvars); for (var = 0; var < nvars; var++) { stencils[part][var] = NULL; } } hypre_SStructGraphStencils(graph) = stencils; hypre_SStructGraphNUVEntries(graph) = 0; hypre_SStructGraphAUVEntries(graph) = 0; hypre_SStructGraphIUVEntries(graph) = NULL; hypre_SStructGraphUVEntries(graph) = NULL; hypre_SStructGraphTotUEntries(graph) = 0; hypre_SStructGraphRefCount(graph) = 1; hypre_SStructGraphObjectType(graph) = HYPRE_SSTRUCT; *graph_ptr = graph; return ierr; }
hypre_StructStencil * hypre_StructStencilCreate( HYPRE_Int dim, HYPRE_Int size, hypre_Index *shape ) { hypre_StructStencil *stencil; stencil = hypre_TAlloc(hypre_StructStencil, 1); hypre_StructStencilShape(stencil) = shape; hypre_StructStencilSize(stencil) = size; hypre_StructStencilDim(stencil) = dim; hypre_StructStencilRefCount(stencil) = 1; return stencil; }
HYPRE_Int hypre_CreateBinaryTree(HYPRE_Int myid, HYPRE_Int num_procs, hypre_BinaryTree *tree) { HYPRE_Int i, proc, size=0; HYPRE_Int *tmp_child_id; HYPRE_Int num=0, parent = 0; /* initialize*/ proc = myid; /*how many children can a processor have?*/ for (i = 1; i < num_procs; i *= 2) { size++; } /* allocate space */ tmp_child_id = hypre_TAlloc(HYPRE_Int, size); /* find children and parent */ for (i = 1; i < num_procs; i *= 2) { if ( (proc % 2) == 0) { if( (myid + i) < num_procs ) { tmp_child_id[num] = myid + i; num++; } proc /= 2; } else { parent = myid - i; break; } } hypre_BinaryTreeParentId(tree) = parent; hypre_BinaryTreeNumChild(tree) = num; hypre_BinaryTreeChildIds(tree) = tmp_child_id; return hypre_error_flag; }
/*-------------------------------------------------------------------------- * hypre_MaxwellOffProcRowCreate *--------------------------------------------------------------------------*/ hypre_MaxwellOffProcRow * hypre_MaxwellOffProcRowCreate(HYPRE_Int ncols) { hypre_MaxwellOffProcRow *OffProcRow; HYPRE_Int *cols; double *data; OffProcRow= hypre_CTAlloc(hypre_MaxwellOffProcRow, 1); (OffProcRow -> ncols)= ncols; cols= hypre_TAlloc(HYPRE_Int, ncols); data= hypre_TAlloc(double, ncols); (OffProcRow -> cols)= cols; (OffProcRow -> data)= data; return OffProcRow; }
HYPRE_Int hypre_MPI_Group_incl( hypre_MPI_Group group, HYPRE_Int n, HYPRE_Int *ranks, hypre_MPI_Group *newgroup ) { hypre_int *mpi_ranks; HYPRE_Int i; HYPRE_Int ierr; mpi_ranks = hypre_TAlloc(hypre_int, n); for (i = 0; i < n; i++) { mpi_ranks[i] = (hypre_int) ranks[i]; } ierr = (HYPRE_Int) MPI_Group_incl(group, (hypre_int)n, mpi_ranks, newgroup); hypre_TFree(mpi_ranks); return ierr; }
HYPRE_Int *hypre_UnorderedIntSetCopyToArray( hypre_UnorderedIntSet *s, HYPRE_Int *len ) { HYPRE_Int prefix_sum_workspace[hypre_NumThreads() + 1]; HYPRE_Int *ret_array = NULL; #ifdef HYPRE_CONCURRENT_HOPSCOTCH #pragma omp parallel #endif { HYPRE_Int n = s->bucketMask + HYPRE_HOPSCOTCH_HASH_INSERT_RANGE; HYPRE_Int i_begin, i_end; hypre_GetSimpleThreadPartition(&i_begin, &i_end, n); HYPRE_Int cnt = 0; HYPRE_Int i; for (i = i_begin; i < i_end; i++) { if (HYPRE_HOPSCOTCH_HASH_EMPTY != s->hash[i]) cnt++; } hypre_prefix_sum(&cnt, len, prefix_sum_workspace); #ifdef HYPRE_CONCURRENT_HOPSCOTCH #pragma omp barrier #pragma omp master #endif { ret_array = hypre_TAlloc(HYPRE_Int, *len); } #ifdef HYPRE_CONCURRENT_HOPSCOTCH #pragma omp barrier #endif for (i = i_begin; i < i_end; i++) { if (HYPRE_HOPSCOTCH_HASH_EMPTY != s->hash[i]) ret_array[cnt++] = s->key[i]; } } return ret_array; }
int hypre_ComputeInfoCreate( hypre_CommInfo *comm_info, hypre_BoxArrayArray *indt_boxes, hypre_BoxArrayArray *dept_boxes, hypre_ComputeInfo **compute_info_ptr ) { int ierr = 0; hypre_ComputeInfo *compute_info; compute_info = hypre_TAlloc(hypre_ComputeInfo, 1); hypre_ComputeInfoCommInfo(compute_info) = comm_info; hypre_ComputeInfoIndtBoxes(compute_info) = indt_boxes; hypre_ComputeInfoDeptBoxes(compute_info) = dept_boxes; hypre_SetIndex(hypre_ComputeInfoStride(compute_info), 1, 1, 1); *compute_info_ptr = compute_info; return ierr; }
HYPRE_Int hypre_CommInfoCreate( hypre_BoxArrayArray *send_boxes, hypre_BoxArrayArray *recv_boxes, HYPRE_Int **send_procs, HYPRE_Int **recv_procs, HYPRE_Int **send_rboxnums, HYPRE_Int **recv_rboxnums, hypre_BoxArrayArray *send_rboxes, hypre_BoxArrayArray *recv_rboxes, HYPRE_Int boxes_match, hypre_CommInfo **comm_info_ptr ) { hypre_CommInfo *comm_info; comm_info = hypre_TAlloc(hypre_CommInfo, 1); hypre_CommInfoNDim(comm_info) = hypre_BoxArrayArrayNDim(send_boxes); hypre_CommInfoSendBoxes(comm_info) = send_boxes; hypre_CommInfoRecvBoxes(comm_info) = recv_boxes; hypre_CommInfoSendProcesses(comm_info) = send_procs; hypre_CommInfoRecvProcesses(comm_info) = recv_procs; hypre_CommInfoSendRBoxnums(comm_info) = send_rboxnums; hypre_CommInfoRecvRBoxnums(comm_info) = recv_rboxnums; hypre_CommInfoSendRBoxes(comm_info) = send_rboxes; hypre_CommInfoRecvRBoxes(comm_info) = recv_rboxes; hypre_CommInfoNumTransforms(comm_info) = 0; hypre_CommInfoCoords(comm_info) = NULL; hypre_CommInfoDirs(comm_info) = NULL; hypre_CommInfoSendTransforms(comm_info) = NULL; hypre_CommInfoRecvTransforms(comm_info) = NULL; hypre_CommInfoBoxesMatch(comm_info) = boxes_match; hypre_SetIndex(hypre_CommInfoSendStride(comm_info), 1); hypre_SetIndex(hypre_CommInfoRecvStride(comm_info), 1); *comm_info_ptr = comm_info; return hypre_error_flag; }
HYPRE_Int hypre_MPI_Type_struct( HYPRE_Int count, HYPRE_Int *array_of_blocklengths, hypre_MPI_Aint *array_of_displacements, hypre_MPI_Datatype *array_of_types, hypre_MPI_Datatype *newtype ) { hypre_int *mpi_array_of_blocklengths; HYPRE_Int i; HYPRE_Int ierr; mpi_array_of_blocklengths = hypre_TAlloc(hypre_int, count); for (i = 0; i < count; i++) { mpi_array_of_blocklengths[i] = (hypre_int) array_of_blocklengths[i]; } ierr = (HYPRE_Int) MPI_Type_struct((hypre_int)count, mpi_array_of_blocklengths, array_of_displacements, array_of_types, newtype); hypre_TFree(mpi_array_of_blocklengths); return ierr; }
/* square of coeff. of variation */ if (deviation[d]/(mean[d]*mean[d]) > .1) { dxyz_flag= 1; break; } } hypre_TFree(mean); hypre_TFree(deviation); } grid_l = hypre_TAlloc(hypre_StructGrid *, max_levels); hypre_StructGridRef(grid, &grid_l[0]); P_grid_l = hypre_TAlloc(hypre_StructGrid *, max_levels); P_grid_l[0] = NULL; cdir_l = hypre_TAlloc(HYPRE_Int, max_levels); active_l = hypre_TAlloc(HYPRE_Int, max_levels); relax_weights = hypre_CTAlloc(double, max_levels); hypre_SetIndex(coarsen, 1, 1, 1); /* forces relaxation on finest grid */ for (l = 0; ; l++) { /* determine cdir */ min_dxyz = dxyz[0] + dxyz[1] + dxyz[2] + 1; cdir = -1; alpha = 0.0; for (d = 0; d < dim; d++) { if ((hypre_BoxIMaxD(cbox, d) > hypre_BoxIMinD(cbox, d)) && (dxyz[d] < min_dxyz)) { min_dxyz = dxyz[d];
HYPRE_Int hypre_StructCoarsen( hypre_StructGrid *fgrid, hypre_Index index, hypre_Index stride, HYPRE_Int prune, hypre_StructGrid **cgrid_ptr ) { hypre_StructGrid *cgrid; MPI_Comm comm; HYPRE_Int ndim; hypre_BoxArray *my_boxes; hypre_Index periodic; hypre_Index ilower, iupper; hypre_Box *box; hypre_Box *new_box; hypre_Box *bounding_box; HYPRE_Int i, j, myid, count; HYPRE_Int info_size, max_nentries; HYPRE_Int num_entries; HYPRE_Int *fids, *cids; hypre_Index new_dist; hypre_IndexRef max_distance; HYPRE_Int proc, id; HYPRE_Int coarsen_factor, known; HYPRE_Int num, last_proc; #if 0 hypre_StructAssumedPart *fap = NULL, *cap = NULL; #endif hypre_BoxManager *fboxman, *cboxman; hypre_BoxManEntry *entries; hypre_BoxManEntry *entry; void *entry_info = NULL; #if TIME_DEBUG HYPRE_Int tindex; char new_title[80]; hypre_sprintf(new_title,"Coarsen.%d",s_coarsen_num); tindex = hypre_InitializeTiming(new_title); s_coarsen_num++; hypre_BeginTiming(tindex); #endif hypre_SetIndex(ilower, 0); hypre_SetIndex(iupper, 0); /* get relevant information from the fine grid */ fids = hypre_StructGridIDs(fgrid); fboxman = hypre_StructGridBoxMan(fgrid); comm = hypre_StructGridComm(fgrid); ndim = hypre_StructGridNDim(fgrid); max_distance = hypre_StructGridMaxDistance(fgrid); /* initial */ hypre_MPI_Comm_rank(comm, &myid ); /* create new coarse grid */ hypre_StructGridCreate(comm, ndim, &cgrid); /* coarsen my boxes and create the coarse grid ids (same as fgrid) */ my_boxes = hypre_BoxArrayDuplicate(hypre_StructGridBoxes(fgrid)); cids = hypre_TAlloc(HYPRE_Int, hypre_BoxArraySize(my_boxes)); for (i = 0; i < hypre_BoxArraySize(my_boxes); i++) { box = hypre_BoxArrayBox(my_boxes, i); hypre_StructCoarsenBox(box, index, stride); cids[i] = fids[i]; } /* prune? */ /* zero volume boxes are needed when forming P and P^T */ if (prune) { count = 0; hypre_ForBoxI(i, my_boxes) { box = hypre_BoxArrayBox(my_boxes, i); if (hypre_BoxVolume(box)) { hypre_CopyBox(box, hypre_BoxArrayBox(my_boxes, count)); cids[count] = cids[i]; count++; } } hypre_BoxArraySetSize(my_boxes, count); }
/* Assume that we are given a fine and coarse topology and the coarse degrees of freedom (DOFs) have been chosen. Assume also, that the global interpolation matrix dof_DOF has a prescribed nonzero pattern. Then, the fine degrees of freedom can be split into 4 groups (here "i" stands for "interior"): NODEidof - dofs which are interpolated only from the DOF in one coarse vertex EDGEidof - dofs which are interpolated only from the DOFs in one coarse edge FACEidof - dofs which are interpolated only from the DOFs in one coarse face ELEMidof - dofs which are interpolated only from the DOFs in one coarse element The interpolation operator dof_DOF can be build in 4 steps, by consequently filling-in the rows corresponding to the above groups. The code below uses harmonic extension to extend the interpolation from one group to the next. */ HYPRE_Int hypre_ND1AMGeInterpolation (hypre_ParCSRMatrix * Aee, hypre_ParCSRMatrix * ELEM_idof, hypre_ParCSRMatrix * FACE_idof, hypre_ParCSRMatrix * EDGE_idof, hypre_ParCSRMatrix * ELEM_FACE, hypre_ParCSRMatrix * ELEM_EDGE, HYPRE_Int num_OffProcRows, hypre_MaxwellOffProcRow ** OffProcRows, hypre_IJMatrix * IJ_dof_DOF) { HYPRE_Int ierr = 0; HYPRE_Int i, j, k; HYPRE_Int *offproc_rnums, *swap; hypre_ParCSRMatrix * dof_DOF = hypre_IJMatrixObject(IJ_dof_DOF); hypre_ParCSRMatrix * ELEM_DOF = ELEM_EDGE; hypre_ParCSRMatrix * ELEM_FACEidof; hypre_ParCSRMatrix * ELEM_EDGEidof; hypre_CSRMatrix *A, *P; HYPRE_Int numELEM = hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(ELEM_EDGE)); HYPRE_Int getrow_ierr; HYPRE_Int three_dimensional_problem; MPI_Comm comm= hypre_ParCSRMatrixComm(Aee); HYPRE_Int myproc; hypre_MPI_Comm_rank(comm, &myproc); #if 0 hypre_IJMatrix * ij_dof_DOF = hypre_CTAlloc(hypre_IJMatrix, 1); /* Convert dof_DOF to IJ matrix, so we can use AddToValues */ hypre_IJMatrixComm(ij_dof_DOF) = hypre_ParCSRMatrixComm(dof_DOF); hypre_IJMatrixRowPartitioning(ij_dof_DOF) = hypre_ParCSRMatrixRowStarts(dof_DOF); hypre_IJMatrixColPartitioning(ij_dof_DOF) = hypre_ParCSRMatrixColStarts(dof_DOF); hypre_IJMatrixObject(ij_dof_DOF) = dof_DOF; hypre_IJMatrixAssembleFlag(ij_dof_DOF) = 1; #endif /* sort the offproc rows to get quicker comparison for later */ if (num_OffProcRows) { offproc_rnums= hypre_TAlloc(HYPRE_Int, num_OffProcRows); swap = hypre_TAlloc(HYPRE_Int, num_OffProcRows); for (i= 0; i< num_OffProcRows; i++) { offproc_rnums[i]=(OffProcRows[i] -> row); swap[i] = i; } } if (num_OffProcRows > 1) { hypre_qsort2i(offproc_rnums, swap, 0, num_OffProcRows-1); } if (FACE_idof == EDGE_idof) three_dimensional_problem = 0; else three_dimensional_problem = 1; /* ELEM_FACEidof = ELEM_FACE x FACE_idof */ if (three_dimensional_problem) ELEM_FACEidof = hypre_ParMatmul(ELEM_FACE, FACE_idof); /* ELEM_EDGEidof = ELEM_EDGE x EDGE_idof */ ELEM_EDGEidof = hypre_ParMatmul(ELEM_EDGE, EDGE_idof); /* Loop over local coarse elements */ k = hypre_ParCSRMatrixFirstRowIndex(ELEM_EDGE); for (i = 0; i < numELEM; i++, k++) { HYPRE_Int size1, size2; HYPRE_Int *col_ind0, *col_ind1, *col_ind2; HYPRE_Int num_DOF, *DOF0, *DOF; HYPRE_Int num_idof, *idof0, *idof; HYPRE_Int num_bdof, *bdof; double *boolean_data; /* Determine the coarse DOFs */ hypre_ParCSRMatrixGetRow (ELEM_DOF, k, &num_DOF, &DOF0, &boolean_data); DOF= hypre_TAlloc(HYPRE_Int, num_DOF); for (j= 0; j< num_DOF; j++) { DOF[j]= DOF0[j]; } hypre_ParCSRMatrixRestoreRow (ELEM_DOF, k, &num_DOF, &DOF0, &boolean_data); qsort0(DOF,0,num_DOF-1); /* Find the fine dofs interior for the current coarse element */ hypre_ParCSRMatrixGetRow (ELEM_idof, k, &num_idof, &idof0, &boolean_data); idof= hypre_TAlloc(HYPRE_Int, num_idof); for (j= 0; j< num_idof; j++) { idof[j]= idof0[j]; } hypre_ParCSRMatrixRestoreRow (ELEM_idof, k, &num_idof, &idof0, &boolean_data); /* Sort the interior dofs according to their global number */ qsort0(idof,0,num_idof-1); /* Find the fine dofs on the boundary of the current coarse element */ if (three_dimensional_problem) { hypre_ParCSRMatrixGetRow (ELEM_FACEidof, k, &size1, &col_ind0, &boolean_data); col_ind1= hypre_TAlloc(HYPRE_Int, size1); for (j= 0; j< size1; j++) { col_ind1[j]= col_ind0[j]; } hypre_ParCSRMatrixRestoreRow (ELEM_FACEidof, k, &size1, &col_ind0, &boolean_data); } else size1 = 0; hypre_ParCSRMatrixGetRow (ELEM_EDGEidof, k, &size2, &col_ind0, &boolean_data); col_ind2= hypre_TAlloc(HYPRE_Int, size2); for (j= 0; j< size2; j++) { col_ind2[j]= col_ind0[j]; } hypre_ParCSRMatrixRestoreRow (ELEM_EDGEidof, k, &size2, &col_ind0, &boolean_data); /* Merge and sort the boundary dofs according to their global number */ num_bdof = size1 + size2; bdof = hypre_CTAlloc(HYPRE_Int, num_bdof); if (three_dimensional_problem) memcpy(bdof, col_ind1, size1*sizeof(HYPRE_Int)); memcpy(bdof+size1, col_ind2, size2*sizeof(HYPRE_Int)); qsort0(bdof,0,num_bdof-1); /* A = extract_rows(Aee, idof) */ A = hypre_CSRMatrixCreate (num_idof, num_idof + num_bdof, num_idof * (num_idof + num_bdof)); hypre_CSRMatrixInitialize(A); { HYPRE_Int *I = hypre_CSRMatrixI(A); HYPRE_Int *J = hypre_CSRMatrixJ(A); double *data = hypre_CSRMatrixData(A); HYPRE_Int *tmp_J; double *tmp_data; I[0] = 0; for (j = 0; j < num_idof; j++) { getrow_ierr= hypre_ParCSRMatrixGetRow (Aee, idof[j], &I[j+1], &tmp_J, &tmp_data); if (getrow_ierr <0) hypre_printf("getrow Aee off proc[%d] = \n",myproc); memcpy(J, tmp_J, I[j+1]*sizeof(HYPRE_Int)); memcpy(data, tmp_data, I[j+1]*sizeof(double)); J+= I[j+1]; data+= I[j+1]; hypre_ParCSRMatrixRestoreRow (Aee, idof[j], &I[j+1], &tmp_J, &tmp_data); I[j+1] += I[j]; } } /* P = extract_rows(dof_DOF, idof+bdof) */ P = hypre_CSRMatrixCreate (num_idof + num_bdof, num_DOF, (num_idof + num_bdof) * num_DOF); hypre_CSRMatrixInitialize(P); { HYPRE_Int *I = hypre_CSRMatrixI(P); HYPRE_Int *J = hypre_CSRMatrixJ(P); double *data = hypre_CSRMatrixData(P); HYPRE_Int m; HYPRE_Int *tmp_J; double *tmp_data; I[0] = 0; for (j = 0; j < num_idof; j++) { getrow_ierr= hypre_ParCSRMatrixGetRow (dof_DOF, idof[j], &I[j+1], &tmp_J, &tmp_data); if (getrow_ierr >= 0) { memcpy(J, tmp_J, I[j+1]*sizeof(HYPRE_Int)); memcpy(data, tmp_data, I[j+1]*sizeof(double)); J+= I[j+1]; data+= I[j+1]; hypre_ParCSRMatrixRestoreRow (dof_DOF, idof[j], &I[j+1], &tmp_J, &tmp_data); I[j+1] += I[j]; } else /* row offproc */ { hypre_ParCSRMatrixRestoreRow (dof_DOF, idof[j], &I[j+1], &tmp_J, &tmp_data); /* search for OffProcRows */ m= 0; while (m < num_OffProcRows) { if (offproc_rnums[m] == idof[j]) { break; } else { m++; } } I[j+1]= (OffProcRows[swap[m]] -> ncols); tmp_J = (OffProcRows[swap[m]] -> cols); tmp_data= (OffProcRows[swap[m]] -> data); memcpy(J, tmp_J, I[j+1]*sizeof(HYPRE_Int)); memcpy(data, tmp_data, I[j+1]*sizeof(double)); J+= I[j+1]; data+= I[j+1]; I[j+1] += I[j]; } } for ( ; j < num_idof + num_bdof; j++) { getrow_ierr= hypre_ParCSRMatrixGetRow (dof_DOF, bdof[j-num_idof], &I[j+1], &tmp_J, &tmp_data); if (getrow_ierr >= 0) { memcpy(J, tmp_J, I[j+1]*sizeof(HYPRE_Int)); memcpy(data, tmp_data, I[j+1]*sizeof(double)); J+= I[j+1]; data+= I[j+1]; hypre_ParCSRMatrixRestoreRow (dof_DOF, bdof[j-num_idof], &I[j+1], &tmp_J, &tmp_data); I[j+1] += I[j]; } else /* row offproc */ { hypre_ParCSRMatrixRestoreRow (dof_DOF, bdof[j-num_idof], &I[j+1], &tmp_J, &tmp_data); /* search for OffProcRows */ m= 0; while (m < num_OffProcRows) { if (offproc_rnums[m] == bdof[j-num_idof]) { break; } else { m++; } } if (m>= num_OffProcRows)hypre_printf("here the mistake\n"); I[j+1]= (OffProcRows[swap[m]] -> ncols); tmp_J = (OffProcRows[swap[m]] -> cols); tmp_data= (OffProcRows[swap[m]] -> data); memcpy(J, tmp_J, I[j+1]*sizeof(HYPRE_Int)); memcpy(data, tmp_data, I[j+1]*sizeof(double)); J+= I[j+1]; data+= I[j+1]; I[j+1] += I[j]; } } } /* Pi = Aii^{-1} Aib Pb */ hypre_HarmonicExtension (A, P, num_DOF, DOF, num_idof, idof, num_bdof, bdof); /* Insert Pi in dof_DOF */ { HYPRE_Int * ncols = hypre_CTAlloc(HYPRE_Int, num_idof); for (j = 0; j < num_idof; j++) ncols[j] = num_DOF; hypre_IJMatrixAddToValuesParCSR (IJ_dof_DOF, num_idof, ncols, idof, hypre_CSRMatrixJ(P), hypre_CSRMatrixData(P)); hypre_TFree(ncols); } hypre_TFree(DOF); hypre_TFree(idof); if (three_dimensional_problem) { hypre_TFree(col_ind1); } hypre_TFree(col_ind2); hypre_TFree(bdof); hypre_CSRMatrixDestroy(A); hypre_CSRMatrixDestroy(P); } #if 0 hypre_TFree(ij_dof_DOF); #endif if (three_dimensional_problem) hypre_ParCSRMatrixDestroy(ELEM_FACEidof); hypre_ParCSRMatrixDestroy(ELEM_EDGEidof); if (num_OffProcRows) { hypre_TFree(offproc_rnums); hypre_TFree(swap); } return ierr; }
HYPRE_Int HYPRE_SStructSplitSetup( HYPRE_SStructSolver solver, HYPRE_SStructMatrix A, HYPRE_SStructVector b, HYPRE_SStructVector x ) { hypre_SStructVector *y; HYPRE_Int nparts; HYPRE_Int *nvars; void ****smatvec_data; HYPRE_Int (***ssolver_solve)(); HYPRE_Int (***ssolver_destroy)(); void ***ssolver_data; HYPRE_Int ssolver = (solver -> ssolver); MPI_Comm comm; hypre_SStructGrid *grid; hypre_SStructPMatrix *pA; hypre_SStructPVector *px; hypre_SStructPVector *py; hypre_StructMatrix *sA; hypre_StructVector *sx; hypre_StructVector *sy; HYPRE_StructMatrix sAH; HYPRE_StructVector sxH; HYPRE_StructVector syH; HYPRE_Int (*ssolve)(); HYPRE_Int (*sdestroy)(); void *sdata; HYPRE_Int part, vi, vj; comm = hypre_SStructVectorComm(b); grid = hypre_SStructVectorGrid(b); HYPRE_SStructVectorCreate(comm, grid, &y); HYPRE_SStructVectorInitialize(y); HYPRE_SStructVectorAssemble(y); nparts = hypre_SStructMatrixNParts(A); nvars = hypre_TAlloc(HYPRE_Int, nparts); smatvec_data = hypre_TAlloc(void ***, nparts); ssolver_solve = (HYPRE_Int (***)()) hypre_MAlloc((sizeof(HYPRE_Int (**)()) * nparts)); ssolver_destroy = (HYPRE_Int (***)()) hypre_MAlloc((sizeof(HYPRE_Int (**)()) * nparts)); ssolver_data = hypre_TAlloc(void **, nparts); for (part = 0; part < nparts; part++) { pA = hypre_SStructMatrixPMatrix(A, part); px = hypre_SStructVectorPVector(x, part); py = hypre_SStructVectorPVector(y, part); nvars[part] = hypre_SStructPMatrixNVars(pA); smatvec_data[part] = hypre_TAlloc(void **, nvars[part]); ssolver_solve[part] = (HYPRE_Int (**)()) hypre_MAlloc((sizeof(HYPRE_Int (*)()) * nvars[part])); ssolver_destroy[part] = (HYPRE_Int (**)()) hypre_MAlloc((sizeof(HYPRE_Int (*)()) * nvars[part])); ssolver_data[part] = hypre_TAlloc(void *, nvars[part]); for (vi = 0; vi < nvars[part]; vi++) { smatvec_data[part][vi] = hypre_TAlloc(void *, nvars[part]); for (vj = 0; vj < nvars[part]; vj++) { sA = hypre_SStructPMatrixSMatrix(pA, vi, vj); sx = hypre_SStructPVectorSVector(px, vj); smatvec_data[part][vi][vj] = NULL; if (sA != NULL) { smatvec_data[part][vi][vj] = hypre_StructMatvecCreate(); hypre_StructMatvecSetup(smatvec_data[part][vi][vj], sA, sx); } } sA = hypre_SStructPMatrixSMatrix(pA, vi, vi); sx = hypre_SStructPVectorSVector(px, vi); sy = hypre_SStructPVectorSVector(py, vi); sAH = (HYPRE_StructMatrix) sA; sxH = (HYPRE_StructVector) sx; syH = (HYPRE_StructVector) sy; switch(ssolver) { default: /* If no solver is matched, use Jacobi, but throw and error */ if (ssolver != HYPRE_Jacobi) { hypre_error(HYPRE_ERROR_GENERIC); } /* don't break */ case HYPRE_Jacobi: HYPRE_StructJacobiCreate(comm, (HYPRE_StructSolver *)&sdata); HYPRE_StructJacobiSetMaxIter(sdata, 1); HYPRE_StructJacobiSetTol(sdata, 0.0); if (solver -> zero_guess) { HYPRE_StructJacobiSetZeroGuess(sdata); } HYPRE_StructJacobiSetup(sdata, sAH, syH, sxH); ssolve = HYPRE_StructJacobiSolve; sdestroy = HYPRE_StructJacobiDestroy; break; case HYPRE_SMG: HYPRE_StructSMGCreate(comm, (HYPRE_StructSolver *)&sdata); HYPRE_StructSMGSetMemoryUse(sdata, 0); HYPRE_StructSMGSetMaxIter(sdata, 1); HYPRE_StructSMGSetTol(sdata, 0.0); if (solver -> zero_guess) { HYPRE_StructSMGSetZeroGuess(sdata); } HYPRE_StructSMGSetNumPreRelax(sdata, 1); HYPRE_StructSMGSetNumPostRelax(sdata, 1); HYPRE_StructSMGSetLogging(sdata, 0); HYPRE_StructSMGSetPrintLevel(sdata, 0); HYPRE_StructSMGSetup(sdata, sAH, syH, sxH); ssolve = HYPRE_StructSMGSolve; sdestroy = HYPRE_StructSMGDestroy; break; case HYPRE_PFMG: HYPRE_StructPFMGCreate(comm, (HYPRE_StructSolver *)&sdata); HYPRE_StructPFMGSetMaxIter(sdata, 1); HYPRE_StructPFMGSetTol(sdata, 0.0); if (solver -> zero_guess) { HYPRE_StructPFMGSetZeroGuess(sdata); } HYPRE_StructPFMGSetRelaxType(sdata, 1); HYPRE_StructPFMGSetNumPreRelax(sdata, 1); HYPRE_StructPFMGSetNumPostRelax(sdata, 1); HYPRE_StructPFMGSetLogging(sdata, 0); HYPRE_StructPFMGSetPrintLevel(sdata, 0); HYPRE_StructPFMGSetup(sdata, sAH, syH, sxH); ssolve = HYPRE_StructPFMGSolve; sdestroy = HYPRE_StructPFMGDestroy; break; } ssolver_solve[part][vi] = ssolve; ssolver_destroy[part][vi] = sdestroy; ssolver_data[part][vi] = sdata; } } (solver -> y) = y; (solver -> nparts) = nparts; (solver -> nvars) = nvars; (solver -> smatvec_data) = smatvec_data; (solver -> ssolver_solve) = ssolver_solve; (solver -> ssolver_destroy) = ssolver_destroy; (solver -> ssolver_data) = ssolver_data; if ((solver -> tol) > 0.0) { hypre_SStructMatvecCreate(&(solver -> matvec_data)); hypre_SStructMatvecSetup((solver -> matvec_data), A, x); } return hypre_error_flag; }
HYPRE_Int HYPRE_SStructGridCreate( MPI_Comm comm, HYPRE_Int ndim, HYPRE_Int nparts, HYPRE_SStructGrid *grid_ptr ) { hypre_SStructGrid *grid; hypre_SStructPGrid **pgrids; hypre_SStructPGrid *pgrid; HYPRE_Int *nneighbors; hypre_SStructNeighbor **neighbors; hypre_Index **nbor_offsets; HYPRE_Int *fem_nvars; HYPRE_Int **fem_vars; hypre_Index **fem_offsets; HYPRE_Int i; grid = hypre_TAlloc(hypre_SStructGrid, 1); hypre_SStructGridComm(grid) = comm; hypre_SStructGridNDim(grid) = ndim; hypre_SStructGridNParts(grid) = nparts; pgrids = hypre_TAlloc(hypre_SStructPGrid *, nparts); nneighbors = hypre_TAlloc(HYPRE_Int, nparts); neighbors = hypre_TAlloc(hypre_SStructNeighbor *, nparts); nbor_offsets = hypre_TAlloc(hypre_Index *, nparts); fem_nvars = hypre_TAlloc(HYPRE_Int, nparts); fem_vars = hypre_TAlloc(HYPRE_Int *, nparts); fem_offsets = hypre_TAlloc(hypre_Index *, nparts); for (i = 0; i < nparts; i++) { hypre_SStructPGridCreate(comm, ndim, &pgrid); pgrids[i] = pgrid; nneighbors[i] = 0; neighbors[i] = NULL; nbor_offsets[i] = NULL; fem_nvars[i] = 0; fem_vars[i] = NULL; fem_offsets[i] = NULL; } hypre_SStructGridPGrids(grid) = pgrids; hypre_SStructGridNNeighbors(grid) = nneighbors; hypre_SStructGridNeighbors(grid) = neighbors; hypre_SStructGridNborOffsets(grid) = nbor_offsets; hypre_SStructGridNUCVars(grid) = 0; hypre_SStructGridUCVars(grid) = NULL; hypre_SStructGridFEMNVars(grid) = fem_nvars; hypre_SStructGridFEMVars(grid) = fem_vars; hypre_SStructGridFEMOffsets(grid) = fem_offsets; hypre_SStructGridBoxManagers(grid) = NULL; hypre_SStructGridNborBoxManagers(grid) = NULL; /* miscellaneous */ hypre_SStructGridLocalSize(grid) = 0; hypre_SStructGridGlobalSize(grid) = 0; hypre_SStructGridRefCount(grid) = 1; /* GEC0902 ghost addition to the grid */ hypre_SStructGridGhlocalSize(grid) = 0; *grid_ptr = grid; return hypre_error_flag; }
HYPRE_Int ndim = hypre_SStructGridNDim(grid); HYPRE_Int nucvars = hypre_SStructGridNUCVars(grid); hypre_SStructUCVar **ucvars = hypre_SStructGridUCVars(grid); hypre_SStructUCVar *ucvar; HYPRE_Int memchunk = 1000; HYPRE_Int i; /* allocate more space if necessary */ if ((nucvars % memchunk) == 0) { ucvars = hypre_TReAlloc(ucvars, hypre_SStructUCVar *, (nucvars + memchunk)); } ucvar = hypre_TAlloc(hypre_SStructUCVar, 1); hypre_SStructUCVarUVars(ucvar) = hypre_TAlloc(hypre_SStructUVar, nvars); hypre_SStructUCVarPart(ucvar) = part; hypre_CopyToCleanIndex(index, ndim, hypre_SStructUCVarCell(ucvar)); hypre_SStructUCVarNUVars(ucvar) = nvars; for (i = 0; i < nvars; i++) { hypre_SStructUCVarType(ucvar, i) = vartypes[i]; hypre_SStructUCVarRank(ucvar, i) = -1; /* don't know, yet */ hypre_SStructUCVarProc(ucvar, i) = -1; /* don't know, yet */ } ucvars[nucvars] = ucvar; nucvars++; hypre_SStructGridNUCVars(grid) = nucvars; hypre_SStructGridUCVars(grid) = ucvars;
int hypre_SStructPMatrixCreate( MPI_Comm comm, hypre_SStructPGrid *pgrid, hypre_SStructStencil **stencils, hypre_SStructPMatrix **pmatrix_ptr ) { hypre_SStructPMatrix *pmatrix; int nvars; int **smaps; hypre_StructStencil ***sstencils; hypre_StructMatrix ***smatrices; int **symmetric; hypre_StructStencil *sstencil; int *vars; hypre_Index *sstencil_shape; int sstencil_size; int new_dim; int *new_sizes; hypre_Index **new_shapes; int size; hypre_StructGrid *sgrid; int vi, vj; int i, j, k; pmatrix = hypre_TAlloc(hypre_SStructPMatrix, 1); hypre_SStructPMatrixComm(pmatrix) = comm; hypre_SStructPMatrixPGrid(pmatrix) = pgrid; hypre_SStructPMatrixStencils(pmatrix) = stencils; nvars = hypre_SStructPGridNVars(pgrid); hypre_SStructPMatrixNVars(pmatrix) = nvars; /* create sstencils */ smaps = hypre_TAlloc(int *, nvars); sstencils = hypre_TAlloc(hypre_StructStencil **, nvars); new_sizes = hypre_TAlloc(int, nvars); new_shapes = hypre_TAlloc(hypre_Index *, nvars); size = 0; for (vi = 0; vi < nvars; vi++) { sstencils[vi] = hypre_TAlloc(hypre_StructStencil *, nvars); for (vj = 0; vj < nvars; vj++) { sstencils[vi][vj] = NULL; new_sizes[vj] = 0; } sstencil = hypre_SStructStencilSStencil(stencils[vi]); vars = hypre_SStructStencilVars(stencils[vi]); sstencil_shape = hypre_StructStencilShape(sstencil); sstencil_size = hypre_StructStencilSize(sstencil); smaps[vi] = hypre_TAlloc(int, sstencil_size); for (i = 0; i < sstencil_size; i++) { j = vars[i]; new_sizes[j]++; } for (vj = 0; vj < nvars; vj++) { if (new_sizes[vj]) { new_shapes[vj] = hypre_TAlloc(hypre_Index, new_sizes[vj]); new_sizes[vj] = 0; } } for (i = 0; i < sstencil_size; i++) { j = vars[i]; k = new_sizes[j]; hypre_CopyIndex(sstencil_shape[i], new_shapes[j][k]); smaps[vi][i] = k; new_sizes[j]++; } new_dim = hypre_StructStencilDim(sstencil); for (vj = 0; vj < nvars; vj++) { if (new_sizes[vj]) { sstencils[vi][vj] = hypre_StructStencilCreate(new_dim, new_sizes[vj], new_shapes[vj]); } size = hypre_max(size, new_sizes[vj]); } } hypre_SStructPMatrixSMaps(pmatrix) = smaps; hypre_SStructPMatrixSStencils(pmatrix) = sstencils; hypre_TFree(new_sizes); hypre_TFree(new_shapes); /* create smatrices */ smatrices = hypre_TAlloc(hypre_StructMatrix **, nvars); for (vi = 0; vi < nvars; vi++) { smatrices[vi] = hypre_TAlloc(hypre_StructMatrix *, nvars); for (vj = 0; vj < nvars; vj++) { smatrices[vi][vj] = NULL; if (sstencils[vi][vj] != NULL) { sgrid = hypre_SStructPGridSGrid(pgrid, vi); smatrices[vi][vj] = hypre_StructMatrixCreate(comm, sgrid, sstencils[vi][vj]); } } } hypre_SStructPMatrixSMatrices(pmatrix) = smatrices; /* create symmetric */ symmetric = hypre_TAlloc(int *, nvars); for (vi = 0; vi < nvars; vi++) { symmetric[vi] = hypre_TAlloc(int, nvars); for (vj = 0; vj < nvars; vj++) { symmetric[vi][vj] = 0; } } hypre_SStructPMatrixSymmetric(pmatrix) = symmetric; hypre_SStructPMatrixSEntriesSize(pmatrix) = size; hypre_SStructPMatrixSEntries(pmatrix) = hypre_TAlloc(int, size); hypre_SStructPMatrixRefCount(pmatrix) = 1; *pmatrix_ptr = pmatrix; return hypre_error_flag; }