📄 az_tools.c
字号:
{ int blk_col; if (blk_size > 0) blk_col = column / blk_size; else blk_col = AZ_find_closest_not_larger(column, cnptr, max_blocks); return blk_col;} /* find_block_col *//******************************************************************************//******************************************************************************//******************************************************************************/int AZ_find_block_in_row(int bindx[], int bnptr[], int blk_row, int blk_col, int indx[], int no_elements, double val[], int blk_space, int nz_space)/******************************************************************************* Search the block row 'blk_row' looking for the block column 'blk_col'. If it is not found, create it (and initialize it to all zeros). Return the value 'index' where indx[index] points to the start of the block (blk_row,blk_col). Author: Ray S. Tuminaro, SNL, 1422 ======= Return code: int, index (see explanation above). ============ Parameter list: =============== val, bindx, indx, bnptr: Sparse matrix arrays. See User's Guide. blk_row, blk_col: Block indices of the block for which we are looking. no_elements: Number of elements in current block. blk_space: Length of storage allocated for bindx[] and indx[]. An error message will be printed if we try to write past these arrays. nz_space: Length of storage allocated for val[]. An error message will be printed if we try to write past this array.*******************************************************************************/{ /* local variables */ int ii, k; char *yo = "find_block_in_row: "; /**************************** execution begins ******************************/ /* look in row 'blk_row' for 'blk_col' */ for (k = bnptr[blk_row]; k < bnptr[blk_row + 1]; k++) { if (bindx[k] == blk_col) return k; } /* block was not found so let us create a new block */ if (bnptr[blk_row + 1] + 2 >= blk_space) { (void) fprintf(stderr, "%sERROR: not enough space for block ptrs (indx)\n", yo); exit(-1); } if (indx[bnptr[blk_row + 1]] + no_elements >= nz_space) { (void) fprintf(stderr, "%sERROR: not enough space for nonzeros (val)\n", yo); exit(-1); } /* create the block (blk_row, blk_col) */ bindx[bnptr[blk_row + 1]] = blk_col; indx[bnptr[blk_row + 1] + 1] = no_elements + indx[bnptr[blk_row + 1]]; for (ii = 0; ii < no_elements; ii++) val[ii+indx[bnptr[blk_row + 1]]] = 0.0; bnptr[blk_row + 1]++; return (bnptr[blk_row + 1] - 1);} /* find_block_in_row *//******************************************************************************//******************************************************************************//******************************************************************************/void AZ_add_new_ele(int cnptr[], int col, int blk_row, int bindx[], int bnptr[], int indx[], double val[], int row, double new_ele, int maxcols, int blk_space, int nz_space, int blk_type)/******************************************************************************* Given a new element 'new_ele' (whose real row and column indices are given by 'row' and 'col') store it in the VBR matrix given by cnptr[], bindx[], bnptr[],indx[], and val[]. If the new element is in a block that already exists in the data structure, then we just add the new entry in 'val[]'. However, if the new element is in a block which does not already exist, we must create the new block and return a pointer to it (find_block_in_row(...)) before we can add the new entry to 'val[]'. Author: Ray S. Tuminaro, SNL, 1422 ======= Return code: void ============ Parameter list: =============== val, bindx, indx, bnptr: Sparse matrix arrays. See User's Guide. blk_row: Block indices of the block for which we are looking. row, col: Point row and column of new entry. new_ele: New value to be placed in matrix. maxcols: Total number of block columns in the local submatrix stored on this processor. blk_space: Length of storage allocated for bindx[] and indx[]. An error message will be printed if we try to write past these arrays. nz_space: Length of storage allocated for val[]. An error message will be printed if we try to write past this array. blk_type: blk_type > 0 ==> all the blocks are the same size so we can use a shortcut in computing the block column index. blk_type = 0 ==> short cut not used.*******************************************************************************/{ /* local variables */ int blk_col, no_elements, k, start_location, little_col, little_row, offset; /*---------------------- execution begins -----------------------------*/ /* find block column containing 'col' */ blk_col = AZ_find_block_col(cnptr, col, maxcols, blk_type); /* compute number of elements in block containing new point */ no_elements = (cnptr[blk_col + 1] - cnptr[blk_col]) * (cnptr[blk_row + 1] - cnptr[blk_row]); /* * Search the block row looking for 'blk_col'. If it does not exist, create it * (and initialize it to all zeros). Return a ptr (actually an index into * indx[]) to the block corresponding to (blk_row,blk_col) */ k = AZ_find_block_in_row(bindx, bnptr, blk_row, blk_col, indx, no_elements, val, blk_space, nz_space); /* compute the location of the new element in val[] */ start_location = indx[k]; little_col = col - cnptr[blk_col]; little_row = row - cnptr[blk_row]; offset = little_col * (cnptr[blk_row + 1] - cnptr[blk_row]) + little_row; val[start_location + offset] = new_ele;} /* add_new_ele *//******************************************************************************//******************************************************************************//******************************************************************************/void AZ_check_msr(int bindx[], int N_update, int N_external, int option, int proc_config[])/******************************************************************************* Check the msr matrix: 1) check that the number of nonzero offdiagonals in each row is non-negative and is not too large. 2) check that the column numbers are nonnegative and not too large. Author: Ray S. Tuminaro, SNL, 1422 ======= Return code: void ============ Parameter list: =============== bindx: MSR array (see User's Guide). N_update: Number of elements updated on this processor. N_external: Number of external elements on this processor. option: AZ_LOCAL ==> the matrix uses local indices. Thus, the number of nonzeros in a row and the largest column index should not exceed the total number of elements on this processor. AZ_GLOBAL==> the matrix uses global indices. Thus, the number of nonzeros in a row and the largest column index should not exceed the total number of elements in the simulation.*******************************************************************************/{ /* local variables */ int i, largest, num, total_ele = 0; char *yo = "AZ_check_msr: "; /**************************** execution begins ******************************/ AZ__MPI_comm_space_ok(); /* compute the total number of elements in this simulation. */ if (option == AZ_GLOBAL) total_ele = AZ_gsum_int(N_update, proc_config); /* * First check that the number of offdiagonal nonzeros is positive also * compute the largest number of nonzeros in a row. */ largest = -1; for (i = 0; i < N_update; i++) { num = bindx[i + 1] - bindx[i]; if (num > largest) largest = num; if (num < 0) { (void) fprintf(stderr, "%sERROR on proc %d: Number of ", yo, proc_config[AZ_node]); (void) fprintf(stderr, "nonzeros offdiagonals in row %d = (%d - %d) = %d\n", i, bindx[i + 1], bindx[i], bindx[i + 1] - bindx[i]); (void) fprintf(stderr, "is negative inside MSR check?\n"); } } if (option == AZ_LOCAL) { if (largest > N_update + N_external) { (void) fprintf(stderr, "%sERROR on proc %d: Number of ", yo, proc_config[AZ_node]); (void) fprintf(stderr, "offdiagonals in row %d exceeds the", largest); (void) fprintf(stderr, " number of elements on the processor %d\n", N_update + N_external); } } else { if (largest > total_ele) { (void) fprintf(stderr, "%sERROR on proc %d: Number of ", yo, proc_config[AZ_node]); (void) fprintf(stderr, "offdiagonals in row %d exceeds the", largest); (void) fprintf(stderr, " total number of elements in simulation %d\n", total_ele); } } largest = AZ_gmax_int(largest, proc_config); if (proc_config[AZ_node] == 0) { (void) fprintf(stdout, "The max number of nonzeros in a row = %d\n", largest); } /* compute the largest column index */ largest = -1; for (i = bindx[0]; i < bindx[N_update]; i++) { if (bindx[i] < 0) { (void) fprintf(stderr, "%sWARNING on proc %d: Negative column (%d)= %d\n", yo, proc_config[AZ_node], i, bindx[i]); } if (bindx[i] > largest) largest = bindx[i]; } if (option == AZ_LOCAL) { if (largest > N_update + N_external) { (void) fprintf(stderr, "%sWARNING on proc %d: Column ", yo, proc_config[AZ_node]); (void) fprintf(stderr, "referenced (%d) that does not exist\n", largest); (void) fprintf(stderr, " # of elements update on proc = %d\n", N_update); (void) fprintf(stderr, " # of external elements = %d\n", N_external); } } else { /* find largest possible index */ if (largest > total_ele) { (void) fprintf(stderr, "%sWARNING on proc %d: Column ", yo, proc_config[AZ_node]); (void) fprintf(stderr, "referenced (%d) that is larger than ", largest); (void) fprintf(stderr, "the total number of elements in simulation %d.\n", total_ele); } }} /* AZ_check_msr *//******************************************************************************//******************************************************************************//******************************************************************************/void AZ_check_vbr(int N_update, int N_external, int option, int bindx[], int bnptr[], int cnptr[], int rnptr[], int proc_config[])/******************************************************************************* Check the vbr matrix: 1) check that the largest column block size (cnptr) is not too large and not <= 0. 2) check that rnptr[i] = cnptr[i] for i < N_update. 3) check that the number of nonzero blocks (bnptr) is not too large and not <= 0 4) check that the block column indices (bindx) are not too large and not <= 0. Author: Ray S. Tuminaro, SNL, 1422 ======= Return code: void ============ Parameter list: =============== N_update: Number of elements updated on this processor. N_external: Number of external elements on this processor. option: AZ_LOCAL ==> the matrix uses local indices. Thus, the number of nonzeros in a row and the largest column index should not exceed the total number of elements on this processor. AZ_GLOBAL==> the matrix uses global indices. Thus, the number of nonzeros in a row and the largest column index should not exceed the total number of elements in the simulation. rnptr, bindx, indx, bnptr, cnptr: Sparse matrix arrays. See User's Guide. On input, the matrix corresponds to the initial ordering (e.g. row i corresponds to global row update[i]). On output, the matrix rows and columns are renumbered to correspond to the ordering given by 'update_index' and 'extern_index'. (e.g. global row update[i] now appears as row update_index[i] in the matrix). proc_config: proc_config[AZ_node] is node number. proc_config[AZ_N_procs] is the number of processors.*******************************************************************************/{ /* local variables */ int i; int largest, num; int total_ele = 0; int proc; char *yo = "AZ_check_vbr: "; /**************************** execution begins ******************************/ AZ__MPI_comm_space_ok(); proc = proc_config[AZ_node]; /* compute the total number of blocks in this simulation. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -