az_examples.c
来自「并行解法器,功能强大」· C语言 代码 · 共 1,282 行 · 第 1/3 页
C
1,282 行
/*==================================================================== * ------------------------ * | CVS File Information | * ------------------------ * * $RCSfile: az_examples.c,v $ * * $Author: tuminaro $ * * $Date: 1998/12/21 19:17:26 $ * * $Revision: 1.10 $ * * $Name: $ *====================================================================*/#ifndef lintstatic char rcsid[] = "$Id: az_examples.c,v 1.10 1998/12/21 19:17:26 tuminaro Exp $";#endif/******************************************************************************* * Copyright 1995, Sandia Corporation. The United States Government retains a * * nonexclusive license in this software as prescribed in AL 88-1 and AL 91-7. * * Export of this program may require a license from the United States * * Government. * ******************************************************************************//****************************************************************************** * * These routines correspond to the matrix setup phase for a number of sample * PDE problems using AZTEC. All of the examples are discretizations of * the Poisson equation (2D structured using 5pt operator, 2D structured using * 9pt operator, 2D unstructured using finite elements, 3D structured using * 7pt operator). All the examples are for MSR matrices excluding one VBR * example. The examples are discussed in further detail in the paper: * * Tuminaro, R.S., Shadid, J.N., and Hutchinson, H.A., Parallel Sparse * Matrix Vector Multiply Software for Matrix with Data Locality", * Sandia Technical Report, 1995. * *****************************************************************************/extern int N_grid_pts, num_PDE_eqns;#include <stdio.h>#include <stdlib.h>#include <math.h>#include "az_aztec.h"/* external function declarations */extern void create_msr_matrix(int update[], double **val, int **bindx, int N_update);extern void add_row_3D(int row, int i, double val[], int bindx[], int *n);extern void add_row_5pt(int row, int location, double val[], int bindx[], int *n);extern void add_row_9pt(int row, int location, int *next_nonzero, double val[], int bindx[], int *n);extern void create_vbr_matrix(int update_blks[], double **val, int **indx, int num_update_blks, int **rnptr, int **bnptr, int **bindx);extern void check_memory_space(int bnptr_next, int total_blks, int indx_next, int total_nz);extern void add_vbr_row(int row, int location, double val[], int indx[], int rnptr[], int bnptr[], int bindx[]);extern int get_block_size(int );extern void new_block(int *next , int row_blk_size, int col_blk_size, int blk_col, double number, int bindx[], int indx[], double val[]);extern void read_triangles(int proc, int N_update);extern void init_msr(double **val, int **bindx, int N_update);extern void compress_matrix(double val[], int bindx[], int N_update);extern void add_to_element(int row, int column, double element, double val[], int bindx[], int diag);extern void setup_Ke(double Ke[][3], double x1, double , double , double y2, double x3, double y3);extern void read_coordinates(double **x, double **y, int update_indx[],int,int);extern void add_to_element(int row, int column, double element, double val[], int bindx[], int diag);extern void create_fe_matrix(int update[], int proc, int **bindx, double **val, int N_update);extern void fill_fe_matrix(double val[], int bindx[], int update[], int update_indx[], int external[], int extern_indx[], int data_org[], int proc_config[]);extern void add_row_matrix_free(int row, int location, int *next_nonzero, double val[], int bindx[]);extern void matrix_vector_mult(int N_update, int update[], int update_indx[], int N_external, int external[], int extern_indx[], double x[], double y[], int data_org[],int proc_config[]);/***************************************************************************** * * * MSR * * * *****************************************************************************/void create_msr_matrix(int update[], double **val, int **bindx, int N_update){ int i,total_nz, n = -1; int avg_nonzeros_per_row = 9; total_nz = N_update*avg_nonzeros_per_row + 1; *bindx = (int *) AZ_allocate(total_nz*sizeof(int)); *val = (double *) AZ_allocate(total_nz*sizeof(double)); if ((*val == NULL) && (total_nz != 0) ) { (void) fprintf(stderr, "Error: Not enough space to create matrix\n"); (void) fprintf(stderr, " Try reducing the variable 'avg_nonzeros_per_row'\n"); exit(1); } for (i = 0 ; i < total_nz ; i++ ) (*bindx)[i] = 0; (*bindx)[0] = N_update+1; for (i = 0; i < N_update; i++) { add_row_3D(update[i], i, *val, *bindx,&n); if ( (*bindx)[i+1] > total_nz) { (void) fprintf(stderr, "Error:total_nz not large enough to accomodate"); (void) fprintf(stderr, " nonzeros\n Try increasing the variable"); (void) fprintf(stderr, " 'avg_nonzeros_per_row'\n Finished \n"); (void) fprintf(stderr, "first %d rows out of %d\n", i, N_update); exit(1); } }} /* create_msr_matrix *//******************************************************************************//******************************************************************************//******************************************************************************/void add_row_5pt(int row, int location, double val[], int bindx[], int *n)/* * Add one row to an MSR matrix corresponding to a 5pt discrete approximation * to the 2D Poisson operator on an n x n square. * * Author: Ray Tuminaro, Div 1422 * Date: 3/15/95 * * Parameters: * row == the global row number of the new row to be added. * location == the local row number where the diagonal of the new row * will be stored. * val,bindx == (see user's guide). On output, val[] and bindx[] * are appended such that the new row has been added. */{/* static int n = -1;*/ int m; int k; int NP; /* determine grid dimensions */ m = *n; if (m == -1) { m = N_grid_pts; m = (int ) sqrt( ((double) m)+0.01); if ( m*m != N_grid_pts) { (void) fprintf(stderr, "Error: the total number of points (%d) needs\n", N_grid_pts); (void) fprintf(stderr, " to equal k^2 where k is an integer\n"); exit(1); } if (m == 1) { /* special case */ val[0] = 1.0; bindx[1] = bindx[0]; return; } } *n = m; k = bindx[location]; NP = num_PDE_eqns; /* * Check neighboring points in each direction and add nonzero entry if * neighbor exists. */ bindx[k] = row + NP; if ((row/NP)%m != m-1) val[k++] = -1.00; bindx[k] = row - NP; if ((row/NP)%m != 0) val[k++] = -1.00; bindx[k] = row + m*NP; if ((row/(NP*m))%m != m-1) val[k++] = -1.00; bindx[k] = row - m*NP; if ((row/(NP*m))%m != 0) val[k++] = -1.00; bindx[location+1] = k; val[location] = 4.0;} /* add_row_5pt *//*************************************************************** * * * Other examples * * * **************************************************************//******************************************************************************//******************************************************************************//******************************************************************************/void add_row_3D(int row, int location, double val[], int bindx[], int *n)/* * Add one row to an MSR matrix corresponding to a 7pt discrete approximation * to the 3D Poisson operator on an n x n x n square. * * Author: Ray Tuminaro, Div 1422 * Date: 3/15/95 * * Parameters: * row == the global row number of the new row to be added. * location == the local row number where the diagonal of the new row * will be stored. * val,bindx == (see Aztec User's guide). On output, val[] and bindx[] * are appended such that the new row has been added. */{ int m; int k, NP; /* determine grid dimensions */ m = *n; if (m == -1) { m = N_grid_pts; m = (int ) pow( ((double) m )+0.01, 0.33334); if (m == 1) { /* special case */ val[0] = 1.0; bindx[1] = bindx[0]; return; } if (m*m*m != N_grid_pts) { (void) fprintf(stderr, "Error: the total number of points (%d) needs\n", N_grid_pts); (void) fprintf(stderr, " to equal k^3 where k is an integer\n"); exit(1); } } *n = m; k = bindx[location]; NP = num_PDE_eqns; /* * Check neighboring points in each direction and add nonzero entry if * neighbor exists. */ bindx[k] = row + NP; if ((row/NP)%m != m-1) val[k++] = -1.0; bindx[k] = row - NP; if ((row/NP)%m != 0 ) val[k++] = -1.0; bindx[k] = row + m*NP; if ((row/(NP*m))%m != m-1) val[k++] = -1.0; bindx[k] = row - m*NP; if ((row/(NP*m))%m != 0 ) val[k++] = -1.0; bindx[k] = row + m*m*NP; if (bindx[k] < m*m*m*NP) val[k++] = -1.0; bindx[k] = row - m*m*NP; if (bindx[k] >= 0) val[k++] = -1.0; bindx[location+1] = k; val[location] = 6.0;} /* add_row_3D *//******************************************************************************//******************************************************************************//******************************************************************************/void add_row_9pt(int row, int location, int *next_nonzero, double val[], int bindx[], int *n)/* * Add one row to an MSR matrix corresponding to a 9pt discrete approximation * to the 2D Poisson operator on an n x n square. * * Author: Ray Tuminaro, Div 1422 * Date: 3/15/95 * * Parameters: * row == the global row number of the new row to be added. * location == the local row number where the diagonal of the new row * will be stored. * next_nonzero == points to the next free storage location in val[] and * bindx[]. * On input, next_nonzero points to location where off * diagonals in new row will be stored. * On output, next_nonzero points to the next free location * (i.e. after the new row that was added). * val,bindx == (see file 'parameters'). On output, val[] and bindx[] * are appended such that the new row has been added. */{ int i, j, point, old_ptr, stride, m; m = *n; if (m == -1) { m = N_grid_pts; m = (int ) sqrt(((double) m ) + 0.01); if (m <= 1) { (void) fprintf(stderr, "grid size too small\n"); exit(1); } if (m*m != N_grid_pts) { (void) fprintf(stderr, "Error: the total number of points (%d) needs\n", N_grid_pts); (void) fprintf(stderr, " to equal k^2 where k is an integer\n"); exit(1); } } *n = m; /* figure out where we are in the global grid */ point = row/num_PDE_eqns; i = point%m; j = (point-i)/m; old_ptr = *next_nonzero; val[location] = 0.0; for (stride = 1; stride <= m; stride = stride*m) { /* * If we are on the bottom boundary, create entries for 2nd order * discretization. Otherwise create high order discretization. */ if ((i != 0) && (i != m-1)) { if (i != 1) { val[*next_nonzero] = 1.0/12.0; bindx[*next_nonzero] = row - stride*2*num_PDE_eqns; *next_nonzero = *next_nonzero + 1; } val[*next_nonzero] = -16.0/12.0; bindx[*next_nonzero] = row - stride*num_PDE_eqns; *next_nonzero = *next_nonzero + 1; if (i != m-2) { val[*next_nonzero] = 1.0/12.0; bindx[*next_nonzero] = row + stride*2*num_PDE_eqns; *next_nonzero = *next_nonzero + 1; } val[*next_nonzero] = -16.0/12.0; bindx[*next_nonzero] = row + stride*num_PDE_eqns; *next_nonzero = *next_nonzero + 1; } else if (i != m-1) { val[*next_nonzero] = -1.0; bindx[*next_nonzero] = row + stride*num_PDE_eqns; *next_nonzero = *next_nonzero + 1; } else if (i != 0) { val[*next_nonzero] = -1.0; bindx[*next_nonzero] = row - stride*num_PDE_eqns; *next_nonzero = *next_nonzero + 1; } if ((i != 0) && (i != m-1)) val[location] += 30.0/12.0; else val[location] += 2.0; i = j; } bindx[location+1] = bindx[location] + (*next_nonzero - old_ptr);} /* add_row_9pt *//***************************************************************************** * * * VBR * * * *****************************************************************************//******************************************************************************//******************************************************************************//******************************************************************************/void create_vbr_matrix(int update_blks[], double **val, int **indx, int num_update_blks, int **rnptr, int **bnptr, int **bindx)/* * Create a matrix in VBR format (containing 'num_update_blks' block rows). * * Author: Ray Tuminaro, Div 1422 * Date: 3/1/95 * * Parameter list: * * update_blks == list of blocks updated by this processor * val == On output, contains matrix nonzeros * indx == On output, contains points to blocks of nonzeros * in val[]. IN particular, the pointers to the nonzero * blocks in block row i are * indx[bnptr[i], ... , bnptr[i+1]-1 ] * num_update_blks == Number of blocks updated by this processor. * rnptr == On output, rnptr[0] = 0 and rnptr[i+1]-rnptr[i] gives * the row dimension of global block row 'update_blks[i]'. * bnptr == On output, bnptr[i] points to * 1) the list of nonzero blocks in bindx[] of the * global row 'update_blks[i]'. * 2) the list of pointers to nonzero matrix values * in indx[] of the global row 'update_blks[i]'. * bindx == On output, bindx[bnptr[i], ..., bnptr[i+1]-1] lists * the global block column indices of the nonzero * blocks in global row 'update_blks[i]'. */{ int avg_blks_per_row = 7;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?