az_tutorial.c

来自「并行解法器,功能强大」· C语言 代码 · 共 164 行

C
164
字号
/*==================================================================== * ------------------------ * | CVS File Information | * ------------------------ * * $RCSfile: az_tutorial.c,v $ * * $Author: tuminaro $ * * $Date: 2000/06/02 16:48:32 $ * * $Revision: 1.8 $ * * $Name:  $ *====================================================================*/#ifndef lintstatic char rcsid[] = "$Id: az_tutorial.c,v 1.8 2000/06/02 16:48:32 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.                                                                 * ******************************************************************************/#include <stdio.h>#include <stdlib.h>#include "az_aztec.h"#define perror(str) { fprintf(stderr,"%s\n",str);   exit(-1); }int n =6;            /* POISSON EQUATION IS SOLVED ON an n x n GRID. This    */                     /* corresponds to an x-vector of length n-squared and   */                      /* thus the matrix A is of size n-squared by n-squared. */#define MAX_NZ_ROW 5 /*  Max number of nonzero elements in any matrix row    */extern void create_matrix_row(int row,int i,double val[],int bindx[]);int main(int argc, char *argv[])/* Set up a Poisson test problem and solve it with AZTEC.                 */{  double *b,*x;                    /* rhs and approximate solution          */  int    i, nrow;  /* See Aztec User's Guide for the variables that follow:         */  int    proc_config[AZ_PROC_SIZE];/* Processor information.                */  int    options[AZ_OPTIONS_SIZE]; /* Array used to select solver options.  */  double params[AZ_PARAMS_SIZE];   /* User selected solver paramters.       */  int    *data_org;                /* Array to specify data layout          */  double status[AZ_STATUS_SIZE];   /* Information returned from AZ_solve(). */  int    *update,                  /* vector elements updated on this node. */         *external;                /* vector elements needed by this node.  */  int    *update_index;            /* ordering of update[] and external[]   */  int    *extern_index;            /* locally on this processor.            */  int    *bindx;                   /* Sparse matrix to be solved is stored  */  double *val;                     /* in these MSR arrays.                  */  int    N_update;                 /* # of unknowns updated on this node    */  /* get number of processors and the name of this processor */#ifdef AZ_MPI  MPI_Init(&argc,&argv);  AZ_set_proc_config(proc_config, MPI_COMM_WORLD);#else  AZ_set_proc_config(proc_config, AZ_NOT_MPI);#endif  /* Define partitioning:  matrix rows (ascending order) owned by this node */  nrow = n*n;  AZ_read_update(&N_update, &update, proc_config, nrow, 1, AZ_linear);  /*   * Create the matrix: each processor creates only rows appearing in update[]   * (using global col. numbers).   */  bindx = (int    *) malloc((N_update*MAX_NZ_ROW+1)*sizeof(int));  val   = (double *) malloc((N_update*MAX_NZ_ROW+1)*sizeof(double));  if (val == NULL) perror("Error: Not enough space to create matrix");  bindx[0] = N_update+1;  for (i = 0; i < N_update; i++) {    create_matrix_row(update[i], i, val, bindx);  }  /* convert matrix to a local distributed matrix */  AZ_transform(proc_config, &external, bindx, val, update, &update_index,               &extern_index, &data_org, N_update, NULL, NULL, NULL, NULL,               AZ_MSR_MATRIX);  /* initialize AZTEC options */  AZ_defaults(options, params);  /* Set rhs (delta function at lower left corner) and initialize guess */  b = (double *) malloc(N_update*sizeof(double));  x = (double *) malloc((N_update + data_org[AZ_N_external])*sizeof(double));          /* NOTE: SOLUTION VECTOR MUST CONTAIN SPACE FOR EXTERNAL ELEMENTS */  if ((x == NULL) && (i != 0)) perror("Not enough space in rhs");  for (i = 0; i < N_update; i++) {    x[update_index[i]] = 0.0;    b[update_index[i]] = 0.0;    if (update[i] == 0) b[update_index[i]] = 1.0;  }  /* solve the system of equations using b  as the right hand side */  AZ_solve(x, b, options, params, NULL, bindx, NULL, NULL, NULL, val, data_org,           status, proc_config);  /* Free allocated memory */   free((void *) update);   free((void *) update_index);  free((void *) external); free((void *) extern_index);  free((void *) x);    free((void *) b);       free((void *) bindx);      free((void *) val);  free((void *) data_org); #ifdef AZ_MPI  MPI_Finalize();#endif  return(1);} /* main *//***************************************************************************//***************************************************************************//***************************************************************************/void create_matrix_row(int row, int location, double val[], int bindx[])/* Add one row to an MSR matrix corresponding to a discrete approximation to the * 2D Poisson operator on an n x n square. * * Parameters: *    row          == global row number of the new row to be added. *    location     == local row where 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. */{  int k;  /* check neighbors in each direction and add nonzero if neighbor exits */  k = bindx[location];  bindx[k]  = row + 1; if ((row  )%n != n-1) val[k++] = -1.;  bindx[k]  = row - 1; if ((row  )%n !=   0) val[k++] = -1.;  bindx[k]  = row + n; if ((row/n)%n != n-1) val[k++] = -1.;  bindx[k]  = row - n; if ((row/n)%n !=   0) val[k++] = -1.;  bindx[location+1] = k;  val[location]     = 4.; /* matrix diagonal */}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?