static char help[] = "Tests reusing MPI parallel matrices and MatGetValues().\n\ To test the parallel matrix assembly, this example intentionally lays out\n\ the matrix across processors differently from the way it is assembled.\n\ This example uses bilinear elements on the unit square. Input arguments are:\n\ -m : problem size\n\n"; #include "petscmat.h" #undef __FUNCT__ #define __FUNCT__ "FormElementStiffness" int FormElementStiffness(PetscReal H,PetscScalar *Ke) { PetscFunctionBegin; Ke[0] = H/6.0; Ke[1] = -.125*H; Ke[2] = H/12.0; Ke[3] = -.125*H; Ke[4] = -.125*H; Ke[5] = H/6.0; Ke[6] = -.125*H; Ke[7] = H/12.0; Ke[8] = H/12.0; Ke[9] = -.125*H; Ke[10] = H/6.0; Ke[11] = -.125*H; Ke[12] = -.125*H; Ke[13] = H/12.0; Ke[14] = -.125*H; Ke[15] = H/6.0; PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **args) { Mat C; Vec u,b; PetscErrorCode ierr; PetscMPIInt size,rank; PetscInt i,m = 5,N,start,end,M,idx[4]; PetscInt j,nrsub,ncsub,*rsub,*csub,mystart,myend; PetscTruth flg; PetscScalar one = 1.0,Ke[16],*vals; PetscReal h,norm; PetscInitialize(&argc,&args,(char *)0,help); ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL);CHKERRQ(ierr); N = (m+1)*(m+1); /* dimension of matrix */ M = m*m; /* number of elements */ h = 1.0/m; /* mesh width */ ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); /* Create stiffness matrix */ ierr = MatCreate(PETSC_COMM_WORLD,&C);CHKERRQ(ierr); ierr = MatSetSizes(C,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr); ierr = MatSetFromOptions(C);CHKERRQ(ierr); start = rank*(M/size) + ((M%size) < rank ? (M%size) : rank); end = start + M/size + ((M%size) > rank); /* Form the element stiffness for the Laplacian */ ierr = FormElementStiffness(h*h,Ke); for (i=start; i 1.e-10 || norm < -1.e-10) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Norm of error b %G should be near 0\n",norm);CHKERRQ(ierr); } /* Now test MatGetValues() */ ierr = PetscOptionsHasName(PETSC_NULL,"-get_values",&flg);CHKERRQ(ierr); if (flg) { ierr = MatGetOwnershipRange(C,&mystart,&myend);CHKERRQ(ierr); nrsub = myend - mystart; ncsub = 4; ierr = PetscMalloc(nrsub*ncsub*sizeof(PetscScalar),&vals);CHKERRQ(ierr); ierr = PetscMalloc(nrsub*sizeof(PetscInt),&rsub);CHKERRQ(ierr); ierr = PetscMalloc(ncsub*sizeof(PetscInt),&csub);CHKERRQ(ierr); for (i=myend-1; i>=mystart; i--) rsub[myend-i-1] = i; for (i=0; i