1*82b1193eSBarry Smith /*$Id: aij.c,v 1.351 2000/05/13 14:19:29 bsmith Exp bsmith $*/ 2*82b1193eSBarry Smith /* 3*82b1193eSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4*82b1193eSBarry Smith matrix storage format. 5*82b1193eSBarry Smith */ 6*82b1193eSBarry Smith 7*82b1193eSBarry Smith #include "petscsys.h" 8*82b1193eSBarry Smith #include "src/mat/impls/aij/seq/aij.h" 9*82b1193eSBarry Smith #include "src/vec/vecimpl.h" 10*82b1193eSBarry Smith #include "src/inline/spops.h" 11*82b1193eSBarry Smith #include "src/inline/dot.h" 12*82b1193eSBarry Smith #include "petscbt.h" 13*82b1193eSBarry Smith 14*82b1193eSBarry Smith 15*82b1193eSBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 16*82b1193eSBarry Smith 17*82b1193eSBarry Smith #undef __FUNC__ 18*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetRowIJ_SeqAIJ"></a>*/"MatGetRowIJ_SeqAIJ" 19*82b1193eSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja,PetscTruth *done) 20*82b1193eSBarry Smith { 21*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22*82b1193eSBarry Smith int ierr,i,ishift; 23*82b1193eSBarry Smith 24*82b1193eSBarry Smith PetscFunctionBegin; 25*82b1193eSBarry Smith *m = A->m; 26*82b1193eSBarry Smith if (!ia) PetscFunctionReturn(0); 27*82b1193eSBarry Smith ishift = a->indexshift; 28*82b1193eSBarry Smith if (symmetric) { 29*82b1193eSBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 30*82b1193eSBarry Smith } else if (oshift == 0 && ishift == -1) { 31*82b1193eSBarry Smith int nz = a->i[a->m]; 32*82b1193eSBarry Smith /* malloc space and subtract 1 from i and j indices */ 33*82b1193eSBarry Smith *ia = (int*)PetscMalloc((a->m+1)*sizeof(int));CHKPTRQ(*ia); 34*82b1193eSBarry Smith *ja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(*ja); 35*82b1193eSBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] - 1; 36*82b1193eSBarry Smith for (i=0; i<a->m+1; i++) (*ia)[i] = a->i[i] - 1; 37*82b1193eSBarry Smith } else if (oshift == 1 && ishift == 0) { 38*82b1193eSBarry Smith int nz = a->i[a->m] + 1; 39*82b1193eSBarry Smith /* malloc space and add 1 to i and j indices */ 40*82b1193eSBarry Smith *ia = (int*)PetscMalloc((a->m+1)*sizeof(int));CHKPTRQ(*ia); 41*82b1193eSBarry Smith *ja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(*ja); 42*82b1193eSBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 43*82b1193eSBarry Smith for (i=0; i<a->m+1; i++) (*ia)[i] = a->i[i] + 1; 44*82b1193eSBarry Smith } else { 45*82b1193eSBarry Smith *ia = a->i; *ja = a->j; 46*82b1193eSBarry Smith } 47*82b1193eSBarry Smith PetscFunctionReturn(0); 48*82b1193eSBarry Smith } 49*82b1193eSBarry Smith 50*82b1193eSBarry Smith #undef __FUNC__ 51*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRestoreRowIJ_SeqAIJ"></a>*/"MatRestoreRowIJ_SeqAIJ" 52*82b1193eSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 53*82b1193eSBarry Smith { 54*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 55*82b1193eSBarry Smith int ishift = a->indexshift,ierr; 56*82b1193eSBarry Smith 57*82b1193eSBarry Smith PetscFunctionBegin; 58*82b1193eSBarry Smith if (!ia) PetscFunctionReturn(0); 59*82b1193eSBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 60*82b1193eSBarry Smith ierr = PetscFree(*ia);CHKERRQ(ierr); 61*82b1193eSBarry Smith ierr = PetscFree(*ja);CHKERRQ(ierr); 62*82b1193eSBarry Smith } 63*82b1193eSBarry Smith PetscFunctionReturn(0); 64*82b1193eSBarry Smith } 65*82b1193eSBarry Smith 66*82b1193eSBarry Smith #undef __FUNC__ 67*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetColumnIJ_SeqAIJ"></a>*/"MatGetColumnIJ_SeqAIJ" 68*82b1193eSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja,PetscTruth *done) 69*82b1193eSBarry Smith { 70*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 71*82b1193eSBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 72*82b1193eSBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 73*82b1193eSBarry Smith 74*82b1193eSBarry Smith PetscFunctionBegin; 75*82b1193eSBarry Smith *nn = A->n; 76*82b1193eSBarry Smith if (!ia) PetscFunctionReturn(0); 77*82b1193eSBarry Smith if (symmetric) { 78*82b1193eSBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 79*82b1193eSBarry Smith } else { 80*82b1193eSBarry Smith collengths = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(collengths); 81*82b1193eSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 82*82b1193eSBarry Smith cia = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(cia); 83*82b1193eSBarry Smith cja = (int*)PetscMalloc((nz+1)*sizeof(int));CHKPTRQ(cja); 84*82b1193eSBarry Smith jj = a->j; 85*82b1193eSBarry Smith for (i=0; i<nz; i++) { 86*82b1193eSBarry Smith collengths[jj[i] + ishift]++; 87*82b1193eSBarry Smith } 88*82b1193eSBarry Smith cia[0] = oshift; 89*82b1193eSBarry Smith for (i=0; i<n; i++) { 90*82b1193eSBarry Smith cia[i+1] = cia[i] + collengths[i]; 91*82b1193eSBarry Smith } 92*82b1193eSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 93*82b1193eSBarry Smith jj = a->j; 94*82b1193eSBarry Smith for (row=0; row<m; row++) { 95*82b1193eSBarry Smith mr = a->i[row+1] - a->i[row]; 96*82b1193eSBarry Smith for (i=0; i<mr; i++) { 97*82b1193eSBarry Smith col = *jj++ + ishift; 98*82b1193eSBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 99*82b1193eSBarry Smith } 100*82b1193eSBarry Smith } 101*82b1193eSBarry Smith ierr = PetscFree(collengths);CHKERRQ(ierr); 102*82b1193eSBarry Smith *ia = cia; *ja = cja; 103*82b1193eSBarry Smith } 104*82b1193eSBarry Smith PetscFunctionReturn(0); 105*82b1193eSBarry Smith } 106*82b1193eSBarry Smith 107*82b1193eSBarry Smith #undef __FUNC__ 108*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRestoreColumnIJ_SeqAIJ"></a>*/"MatRestoreColumnIJ_SeqAIJ" 109*82b1193eSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja,PetscTruth *done) 110*82b1193eSBarry Smith { 111*82b1193eSBarry Smith int ierr; 112*82b1193eSBarry Smith 113*82b1193eSBarry Smith PetscFunctionBegin; 114*82b1193eSBarry Smith if (!ia) PetscFunctionReturn(0); 115*82b1193eSBarry Smith 116*82b1193eSBarry Smith ierr = PetscFree(*ia);CHKERRQ(ierr); 117*82b1193eSBarry Smith ierr = PetscFree(*ja);CHKERRQ(ierr); 118*82b1193eSBarry Smith 119*82b1193eSBarry Smith PetscFunctionReturn(0); 120*82b1193eSBarry Smith } 121*82b1193eSBarry Smith 122*82b1193eSBarry Smith #define CHUNKSIZE 15 123*82b1193eSBarry Smith 124*82b1193eSBarry Smith #undef __FUNC__ 125*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSetValues_SeqAIJ"></a>*/"MatSetValues_SeqAIJ" 126*82b1193eSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 127*82b1193eSBarry Smith { 128*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 129*82b1193eSBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 130*82b1193eSBarry Smith int *imax = a->imax,*ai = a->i,*ailen = a->ilen,roworiented = a->roworiented; 131*82b1193eSBarry Smith int *aj = a->j,nonew = a->nonew,shift = a->indexshift,ierr; 132*82b1193eSBarry Smith Scalar *ap,value,*aa = a->a; 133*82b1193eSBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 134*82b1193eSBarry Smith 135*82b1193eSBarry Smith PetscFunctionBegin; 136*82b1193eSBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 137*82b1193eSBarry Smith row = im[k]; 138*82b1193eSBarry Smith if (row < 0) continue; 139*82b1193eSBarry Smith #if defined(PETSC_USE_BOPT_g) 140*82b1193eSBarry Smith if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m); 141*82b1193eSBarry Smith #endif 142*82b1193eSBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 143*82b1193eSBarry Smith rmax = imax[row]; nrow = ailen[row]; 144*82b1193eSBarry Smith low = 0; 145*82b1193eSBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 146*82b1193eSBarry Smith if (in[l] < 0) continue; 147*82b1193eSBarry Smith #if defined(PETSC_USE_BOPT_g) 148*82b1193eSBarry Smith if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n); 149*82b1193eSBarry Smith #endif 150*82b1193eSBarry Smith col = in[l] - shift; 151*82b1193eSBarry Smith if (roworiented) { 152*82b1193eSBarry Smith value = v[l + k*n]; 153*82b1193eSBarry Smith } else { 154*82b1193eSBarry Smith value = v[k + l*m]; 155*82b1193eSBarry Smith } 156*82b1193eSBarry Smith if (value == 0.0 && ignorezeroentries) continue; 157*82b1193eSBarry Smith 158*82b1193eSBarry Smith if (!sorted) low = 0; high = nrow; 159*82b1193eSBarry Smith while (high-low > 5) { 160*82b1193eSBarry Smith t = (low+high)/2; 161*82b1193eSBarry Smith if (rp[t] > col) high = t; 162*82b1193eSBarry Smith else low = t; 163*82b1193eSBarry Smith } 164*82b1193eSBarry Smith for (i=low; i<high; i++) { 165*82b1193eSBarry Smith if (rp[i] > col) break; 166*82b1193eSBarry Smith if (rp[i] == col) { 167*82b1193eSBarry Smith if (is == ADD_VALUES) ap[i] += value; 168*82b1193eSBarry Smith else ap[i] = value; 169*82b1193eSBarry Smith goto noinsert; 170*82b1193eSBarry Smith } 171*82b1193eSBarry Smith } 172*82b1193eSBarry Smith if (nonew == 1) goto noinsert; 173*82b1193eSBarry Smith else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero at (%d,%d) in the matrix",row,col); 174*82b1193eSBarry Smith if (nrow >= rmax) { 175*82b1193eSBarry Smith /* there is no extra room in row, therefore enlarge */ 176*82b1193eSBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 177*82b1193eSBarry Smith Scalar *new_a; 178*82b1193eSBarry Smith 179*82b1193eSBarry Smith if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col); 180*82b1193eSBarry Smith 181*82b1193eSBarry Smith /* malloc new storage space */ 182*82b1193eSBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 183*82b1193eSBarry Smith new_a = (Scalar*)PetscMalloc(len);CHKPTRQ(new_a); 184*82b1193eSBarry Smith new_j = (int*)(new_a + new_nz); 185*82b1193eSBarry Smith new_i = new_j + new_nz; 186*82b1193eSBarry Smith 187*82b1193eSBarry Smith /* copy over old data into new slots */ 188*82b1193eSBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 189*82b1193eSBarry Smith for (ii=row+1; ii<a->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 190*82b1193eSBarry Smith ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr); 191*82b1193eSBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 192*82b1193eSBarry Smith ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr); 193*82b1193eSBarry Smith ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr); 194*82b1193eSBarry Smith ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr); 195*82b1193eSBarry Smith /* free up old matrix storage */ 196*82b1193eSBarry Smith ierr = PetscFree(a->a);CHKERRQ(ierr); 197*82b1193eSBarry Smith if (!a->singlemalloc) { 198*82b1193eSBarry Smith ierr = PetscFree(a->i);CHKERRQ(ierr); 199*82b1193eSBarry Smith ierr = PetscFree(a->j);CHKERRQ(ierr); 200*82b1193eSBarry Smith } 201*82b1193eSBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 202*82b1193eSBarry Smith a->singlemalloc = PETSC_TRUE; 203*82b1193eSBarry Smith 204*82b1193eSBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 205*82b1193eSBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 206*82b1193eSBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 207*82b1193eSBarry Smith a->maxnz += CHUNKSIZE; 208*82b1193eSBarry Smith a->reallocs++; 209*82b1193eSBarry Smith } 210*82b1193eSBarry Smith N = nrow++ - 1; a->nz++; 211*82b1193eSBarry Smith /* shift up all the later entries in this row */ 212*82b1193eSBarry Smith for (ii=N; ii>=i; ii--) { 213*82b1193eSBarry Smith rp[ii+1] = rp[ii]; 214*82b1193eSBarry Smith ap[ii+1] = ap[ii]; 215*82b1193eSBarry Smith } 216*82b1193eSBarry Smith rp[i] = col; 217*82b1193eSBarry Smith ap[i] = value; 218*82b1193eSBarry Smith noinsert:; 219*82b1193eSBarry Smith low = i + 1; 220*82b1193eSBarry Smith } 221*82b1193eSBarry Smith ailen[row] = nrow; 222*82b1193eSBarry Smith } 223*82b1193eSBarry Smith PetscFunctionReturn(0); 224*82b1193eSBarry Smith } 225*82b1193eSBarry Smith 226*82b1193eSBarry Smith #undef __FUNC__ 227*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetValues_SeqAIJ"></a>*/"MatGetValues_SeqAIJ" 228*82b1193eSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 229*82b1193eSBarry Smith { 230*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 231*82b1193eSBarry Smith int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 232*82b1193eSBarry Smith int *ai = a->i,*ailen = a->ilen,shift = a->indexshift; 233*82b1193eSBarry Smith Scalar *ap,*aa = a->a,zero = 0.0; 234*82b1193eSBarry Smith 235*82b1193eSBarry Smith PetscFunctionBegin; 236*82b1193eSBarry Smith for (k=0; k<m; k++) { /* loop over rows */ 237*82b1193eSBarry Smith row = im[k]; 238*82b1193eSBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row: %d",row); 239*82b1193eSBarry Smith if (row >= a->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: %d",row); 240*82b1193eSBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 241*82b1193eSBarry Smith nrow = ailen[row]; 242*82b1193eSBarry Smith for (l=0; l<n; l++) { /* loop over columns */ 243*82b1193eSBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column: %d",in[l]); 244*82b1193eSBarry Smith if (in[l] >= a->n) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: %d",in[l]); 245*82b1193eSBarry Smith col = in[l] - shift; 246*82b1193eSBarry Smith high = nrow; low = 0; /* assume unsorted */ 247*82b1193eSBarry Smith while (high-low > 5) { 248*82b1193eSBarry Smith t = (low+high)/2; 249*82b1193eSBarry Smith if (rp[t] > col) high = t; 250*82b1193eSBarry Smith else low = t; 251*82b1193eSBarry Smith } 252*82b1193eSBarry Smith for (i=low; i<high; i++) { 253*82b1193eSBarry Smith if (rp[i] > col) break; 254*82b1193eSBarry Smith if (rp[i] == col) { 255*82b1193eSBarry Smith *v++ = ap[i]; 256*82b1193eSBarry Smith goto finished; 257*82b1193eSBarry Smith } 258*82b1193eSBarry Smith } 259*82b1193eSBarry Smith *v++ = zero; 260*82b1193eSBarry Smith finished:; 261*82b1193eSBarry Smith } 262*82b1193eSBarry Smith } 263*82b1193eSBarry Smith PetscFunctionReturn(0); 264*82b1193eSBarry Smith } 265*82b1193eSBarry Smith 266*82b1193eSBarry Smith 267*82b1193eSBarry Smith #undef __FUNC__ 268*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Binary"></a>*/"MatView_SeqAIJ_Binary" 269*82b1193eSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 270*82b1193eSBarry Smith { 271*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 272*82b1193eSBarry Smith int i,fd,*col_lens,ierr; 273*82b1193eSBarry Smith 274*82b1193eSBarry Smith PetscFunctionBegin; 275*82b1193eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 276*82b1193eSBarry Smith col_lens = (int*)PetscMalloc((4+a->m)*sizeof(int));CHKPTRQ(col_lens); 277*82b1193eSBarry Smith col_lens[0] = MAT_COOKIE; 278*82b1193eSBarry Smith col_lens[1] = a->m; 279*82b1193eSBarry Smith col_lens[2] = a->n; 280*82b1193eSBarry Smith col_lens[3] = a->nz; 281*82b1193eSBarry Smith 282*82b1193eSBarry Smith /* store lengths of each row and write (including header) to file */ 283*82b1193eSBarry Smith for (i=0; i<a->m; i++) { 284*82b1193eSBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 285*82b1193eSBarry Smith } 286*82b1193eSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr); 287*82b1193eSBarry Smith ierr = PetscFree(col_lens);CHKERRQ(ierr); 288*82b1193eSBarry Smith 289*82b1193eSBarry Smith /* store column indices (zero start index) */ 290*82b1193eSBarry Smith if (a->indexshift) { 291*82b1193eSBarry Smith for (i=0; i<a->nz; i++) a->j[i]--; 292*82b1193eSBarry Smith } 293*82b1193eSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 294*82b1193eSBarry Smith if (a->indexshift) { 295*82b1193eSBarry Smith for (i=0; i<a->nz; i++) a->j[i]++; 296*82b1193eSBarry Smith } 297*82b1193eSBarry Smith 298*82b1193eSBarry Smith /* store nonzero values */ 299*82b1193eSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 300*82b1193eSBarry Smith PetscFunctionReturn(0); 301*82b1193eSBarry Smith } 302*82b1193eSBarry Smith 303*82b1193eSBarry Smith #undef __FUNC__ 304*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_ASCII"></a>*/"MatView_SeqAIJ_ASCII" 305*82b1193eSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 306*82b1193eSBarry Smith { 307*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 308*82b1193eSBarry Smith int ierr,i,j,m = a->m,shift = a->indexshift,format; 309*82b1193eSBarry Smith char *outputname; 310*82b1193eSBarry Smith 311*82b1193eSBarry Smith PetscFunctionBegin; 312*82b1193eSBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 313*82b1193eSBarry Smith ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 314*82b1193eSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) { 315*82b1193eSBarry Smith if (a->inode.size) { 316*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 317*82b1193eSBarry Smith } else { 318*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 319*82b1193eSBarry Smith } 320*82b1193eSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 321*82b1193eSBarry Smith int nofinalvalue = 0; 322*82b1193eSBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) { 323*82b1193eSBarry Smith nofinalvalue = 1; 324*82b1193eSBarry Smith } 325*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 326*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr); 327*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 328*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 329*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 330*82b1193eSBarry Smith 331*82b1193eSBarry Smith for (i=0; i<m; i++) { 332*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 333*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 334*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 335*82b1193eSBarry Smith #else 336*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 337*82b1193eSBarry Smith #endif 338*82b1193eSBarry Smith } 339*82b1193eSBarry Smith } 340*82b1193eSBarry Smith if (nofinalvalue) { 341*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n",m,a->n,0.0);CHKERRQ(ierr); 342*82b1193eSBarry Smith } 343*82b1193eSBarry Smith if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);} 344*82b1193eSBarry Smith else {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);} 345*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 346*82b1193eSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 347*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 348*82b1193eSBarry Smith for (i=0; i<m; i++) { 349*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 350*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 351*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 352*82b1193eSBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 353*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 354*82b1193eSBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 355*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 356*82b1193eSBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 357*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 358*82b1193eSBarry Smith } 359*82b1193eSBarry Smith #else 360*82b1193eSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 361*82b1193eSBarry Smith #endif 362*82b1193eSBarry Smith } 363*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 364*82b1193eSBarry Smith } 365*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 366*82b1193eSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) { 367*82b1193eSBarry Smith int nzd=0,fshift=1,*sptr; 368*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 369*82b1193eSBarry Smith sptr = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(sptr); 370*82b1193eSBarry Smith for (i=0; i<m; i++) { 371*82b1193eSBarry Smith sptr[i] = nzd+1; 372*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 373*82b1193eSBarry Smith if (a->j[j] >= i) { 374*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 375*82b1193eSBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 376*82b1193eSBarry Smith #else 377*82b1193eSBarry Smith if (a->a[j] != 0.0) nzd++; 378*82b1193eSBarry Smith #endif 379*82b1193eSBarry Smith } 380*82b1193eSBarry Smith } 381*82b1193eSBarry Smith } 382*82b1193eSBarry Smith sptr[m] = nzd+1; 383*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 384*82b1193eSBarry Smith for (i=0; i<m+1; i+=6) { 385*82b1193eSBarry Smith if (i+4<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);} 386*82b1193eSBarry Smith else if (i+3<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);} 387*82b1193eSBarry Smith else if (i+2<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);} 388*82b1193eSBarry Smith else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 389*82b1193eSBarry Smith else if (i<m) {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 390*82b1193eSBarry Smith else {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 391*82b1193eSBarry Smith } 392*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 393*82b1193eSBarry Smith ierr = PetscFree(sptr);CHKERRQ(ierr); 394*82b1193eSBarry Smith for (i=0; i<m; i++) { 395*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 396*82b1193eSBarry Smith if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 397*82b1193eSBarry Smith } 398*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 399*82b1193eSBarry Smith } 400*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 401*82b1193eSBarry Smith for (i=0; i<m; i++) { 402*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 403*82b1193eSBarry Smith if (a->j[j] >= i) { 404*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 405*82b1193eSBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 406*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 407*82b1193eSBarry Smith } 408*82b1193eSBarry Smith #else 409*82b1193eSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 410*82b1193eSBarry Smith #endif 411*82b1193eSBarry Smith } 412*82b1193eSBarry Smith } 413*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 414*82b1193eSBarry Smith } 415*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 416*82b1193eSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_DENSE) { 417*82b1193eSBarry Smith int cnt = 0,jcnt; 418*82b1193eSBarry Smith Scalar value; 419*82b1193eSBarry Smith 420*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 421*82b1193eSBarry Smith for (i=0; i<m; i++) { 422*82b1193eSBarry Smith jcnt = 0; 423*82b1193eSBarry Smith for (j=0; j<a->n; j++) { 424*82b1193eSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 425*82b1193eSBarry Smith value = a->a[cnt++]; 426*82b1193eSBarry Smith jcnt++; 427*82b1193eSBarry Smith } else { 428*82b1193eSBarry Smith value = 0.0; 429*82b1193eSBarry Smith } 430*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 431*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 432*82b1193eSBarry Smith #else 433*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 434*82b1193eSBarry Smith #endif 435*82b1193eSBarry Smith } 436*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 437*82b1193eSBarry Smith } 438*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 439*82b1193eSBarry Smith } else { 440*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 441*82b1193eSBarry Smith for (i=0; i<m; i++) { 442*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 443*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 444*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 445*82b1193eSBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 446*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 447*82b1193eSBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 448*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 449*82b1193eSBarry Smith } else { 450*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 451*82b1193eSBarry Smith } 452*82b1193eSBarry Smith #else 453*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 454*82b1193eSBarry Smith #endif 455*82b1193eSBarry Smith } 456*82b1193eSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 457*82b1193eSBarry Smith } 458*82b1193eSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 459*82b1193eSBarry Smith } 460*82b1193eSBarry Smith ierr = ViewerFlush(viewer);CHKERRQ(ierr); 461*82b1193eSBarry Smith PetscFunctionReturn(0); 462*82b1193eSBarry Smith } 463*82b1193eSBarry Smith 464*82b1193eSBarry Smith #undef __FUNC__ 465*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Draw_Zoom"></a>*/"MatView_SeqAIJ_Draw_Zoom" 466*82b1193eSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa) 467*82b1193eSBarry Smith { 468*82b1193eSBarry Smith Mat A = (Mat) Aa; 469*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 470*82b1193eSBarry Smith int ierr,i,j,m = a->m,shift = a->indexshift,color; 471*82b1193eSBarry Smith int format; 472*82b1193eSBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 473*82b1193eSBarry Smith Viewer viewer; 474*82b1193eSBarry Smith 475*82b1193eSBarry Smith PetscFunctionBegin; 476*82b1193eSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 477*82b1193eSBarry Smith ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 478*82b1193eSBarry Smith 479*82b1193eSBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 480*82b1193eSBarry Smith /* loop over matrix elements drawing boxes */ 481*82b1193eSBarry Smith 482*82b1193eSBarry Smith if (format != VIEWER_FORMAT_DRAW_CONTOUR) { 483*82b1193eSBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 484*82b1193eSBarry Smith color = DRAW_BLUE; 485*82b1193eSBarry Smith for (i=0; i<m; i++) { 486*82b1193eSBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 487*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 488*82b1193eSBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 489*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 490*82b1193eSBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 491*82b1193eSBarry Smith #else 492*82b1193eSBarry Smith if (a->a[j] >= 0.) continue; 493*82b1193eSBarry Smith #endif 494*82b1193eSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 495*82b1193eSBarry Smith } 496*82b1193eSBarry Smith } 497*82b1193eSBarry Smith color = DRAW_CYAN; 498*82b1193eSBarry Smith for (i=0; i<m; i++) { 499*82b1193eSBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 500*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 501*82b1193eSBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 502*82b1193eSBarry Smith if (a->a[j] != 0.) continue; 503*82b1193eSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 504*82b1193eSBarry Smith } 505*82b1193eSBarry Smith } 506*82b1193eSBarry Smith color = DRAW_RED; 507*82b1193eSBarry Smith for (i=0; i<m; i++) { 508*82b1193eSBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 509*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 510*82b1193eSBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 511*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 512*82b1193eSBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 513*82b1193eSBarry Smith #else 514*82b1193eSBarry Smith if (a->a[j] <= 0.) continue; 515*82b1193eSBarry Smith #endif 516*82b1193eSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 517*82b1193eSBarry Smith } 518*82b1193eSBarry Smith } 519*82b1193eSBarry Smith } else { 520*82b1193eSBarry Smith /* use contour shading to indicate magnitude of values */ 521*82b1193eSBarry Smith /* first determine max of all nonzero values */ 522*82b1193eSBarry Smith int nz = a->nz,count; 523*82b1193eSBarry Smith Draw popup; 524*82b1193eSBarry Smith PetscReal scale; 525*82b1193eSBarry Smith 526*82b1193eSBarry Smith for (i=0; i<nz; i++) { 527*82b1193eSBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 528*82b1193eSBarry Smith } 529*82b1193eSBarry Smith scale = (245.0 - DRAW_BASIC_COLORS)/maxv; 530*82b1193eSBarry Smith ierr = DrawGetPopup(draw,&popup);CHKERRQ(ierr); 531*82b1193eSBarry Smith if (popup) {ierr = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 532*82b1193eSBarry Smith count = 0; 533*82b1193eSBarry Smith for (i=0; i<m; i++) { 534*82b1193eSBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 535*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 536*82b1193eSBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 537*82b1193eSBarry Smith color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 538*82b1193eSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 539*82b1193eSBarry Smith count++; 540*82b1193eSBarry Smith } 541*82b1193eSBarry Smith } 542*82b1193eSBarry Smith } 543*82b1193eSBarry Smith PetscFunctionReturn(0); 544*82b1193eSBarry Smith } 545*82b1193eSBarry Smith 546*82b1193eSBarry Smith #undef __FUNC__ 547*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ_Draw"></a>*/"MatView_SeqAIJ_Draw" 548*82b1193eSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 549*82b1193eSBarry Smith { 550*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 551*82b1193eSBarry Smith int ierr; 552*82b1193eSBarry Smith Draw draw; 553*82b1193eSBarry Smith PetscReal xr,yr,xl,yl,h,w; 554*82b1193eSBarry Smith PetscTruth isnull; 555*82b1193eSBarry Smith 556*82b1193eSBarry Smith PetscFunctionBegin; 557*82b1193eSBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 558*82b1193eSBarry Smith ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); 559*82b1193eSBarry Smith if (isnull) PetscFunctionReturn(0); 560*82b1193eSBarry Smith 561*82b1193eSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 562*82b1193eSBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 563*82b1193eSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 564*82b1193eSBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 565*82b1193eSBarry Smith ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 566*82b1193eSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 567*82b1193eSBarry Smith PetscFunctionReturn(0); 568*82b1193eSBarry Smith } 569*82b1193eSBarry Smith 570*82b1193eSBarry Smith #undef __FUNC__ 571*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatView_SeqAIJ"></a>*/"MatView_SeqAIJ" 572*82b1193eSBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer) 573*82b1193eSBarry Smith { 574*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 575*82b1193eSBarry Smith int ierr; 576*82b1193eSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 577*82b1193eSBarry Smith 578*82b1193eSBarry Smith PetscFunctionBegin; 579*82b1193eSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr); 580*82b1193eSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 581*82b1193eSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr); 582*82b1193eSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr); 583*82b1193eSBarry Smith if (issocket) { 584*82b1193eSBarry Smith if (a->indexshift) { 585*82b1193eSBarry Smith SETERRQ(1,1,"Can only socket send sparse matrix with 0 based indexing"); 586*82b1193eSBarry Smith } 587*82b1193eSBarry Smith ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 588*82b1193eSBarry Smith } else if (isascii) { 589*82b1193eSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 590*82b1193eSBarry Smith } else if (isbinary) { 591*82b1193eSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 592*82b1193eSBarry Smith } else if (isdraw) { 593*82b1193eSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 594*82b1193eSBarry Smith } else { 595*82b1193eSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 596*82b1193eSBarry Smith } 597*82b1193eSBarry Smith PetscFunctionReturn(0); 598*82b1193eSBarry Smith } 599*82b1193eSBarry Smith 600*82b1193eSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat); 601*82b1193eSBarry Smith #undef __FUNC__ 602*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatAssemblyEnd_SeqAIJ"></a>*/"MatAssemblyEnd_SeqAIJ" 603*82b1193eSBarry Smith int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 604*82b1193eSBarry Smith { 605*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 606*82b1193eSBarry Smith int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr; 607*82b1193eSBarry Smith int m = a->m,*ip,N,*ailen = a->ilen,shift = a->indexshift,rmax = 0; 608*82b1193eSBarry Smith Scalar *aa = a->a,*ap; 609*82b1193eSBarry Smith 610*82b1193eSBarry Smith PetscFunctionBegin; 611*82b1193eSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 612*82b1193eSBarry Smith 613*82b1193eSBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 614*82b1193eSBarry Smith for (i=1; i<m; i++) { 615*82b1193eSBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 616*82b1193eSBarry Smith fshift += imax[i-1] - ailen[i-1]; 617*82b1193eSBarry Smith rmax = PetscMax(rmax,ailen[i]); 618*82b1193eSBarry Smith if (fshift) { 619*82b1193eSBarry Smith ip = aj + ai[i] + shift; 620*82b1193eSBarry Smith ap = aa + ai[i] + shift; 621*82b1193eSBarry Smith N = ailen[i]; 622*82b1193eSBarry Smith for (j=0; j<N; j++) { 623*82b1193eSBarry Smith ip[j-fshift] = ip[j]; 624*82b1193eSBarry Smith ap[j-fshift] = ap[j]; 625*82b1193eSBarry Smith } 626*82b1193eSBarry Smith } 627*82b1193eSBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 628*82b1193eSBarry Smith } 629*82b1193eSBarry Smith if (m) { 630*82b1193eSBarry Smith fshift += imax[m-1] - ailen[m-1]; 631*82b1193eSBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 632*82b1193eSBarry Smith } 633*82b1193eSBarry Smith /* reset ilen and imax for each row */ 634*82b1193eSBarry Smith for (i=0; i<m; i++) { 635*82b1193eSBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 636*82b1193eSBarry Smith } 637*82b1193eSBarry Smith a->nz = ai[m] + shift; 638*82b1193eSBarry Smith 639*82b1193eSBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 640*82b1193eSBarry Smith if (fshift && a->diag) { 641*82b1193eSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 642*82b1193eSBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 643*82b1193eSBarry Smith a->diag = 0; 644*82b1193eSBarry Smith } 645*82b1193eSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,a->n,fshift,a->nz); 646*82b1193eSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 647*82b1193eSBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 648*82b1193eSBarry Smith a->reallocs = 0; 649*82b1193eSBarry Smith A->info.nz_unneeded = (double)fshift; 650*82b1193eSBarry Smith a->rmax = rmax; 651*82b1193eSBarry Smith 652*82b1193eSBarry Smith /* check out for identical nodes. If found, use inode functions */ 653*82b1193eSBarry Smith ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr); 654*82b1193eSBarry Smith PetscFunctionReturn(0); 655*82b1193eSBarry Smith } 656*82b1193eSBarry Smith 657*82b1193eSBarry Smith #undef __FUNC__ 658*82b1193eSBarry Smith #define __FUNC__ /*<a name="atZeroEntries_SeqAIJ"></a>*/"MatZeroEntries_SeqAIJ" 659*82b1193eSBarry Smith int MatZeroEntries_SeqAIJ(Mat A) 660*82b1193eSBarry Smith { 661*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 662*82b1193eSBarry Smith int ierr; 663*82b1193eSBarry Smith 664*82b1193eSBarry Smith PetscFunctionBegin; 665*82b1193eSBarry Smith ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 666*82b1193eSBarry Smith PetscFunctionReturn(0); 667*82b1193eSBarry Smith } 668*82b1193eSBarry Smith 669*82b1193eSBarry Smith #undef __FUNC__ 670*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatDestroy_SeqAIJ"></a>*/"MatDestroy_SeqAIJ" 671*82b1193eSBarry Smith int MatDestroy_SeqAIJ(Mat A) 672*82b1193eSBarry Smith { 673*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 674*82b1193eSBarry Smith int ierr; 675*82b1193eSBarry Smith 676*82b1193eSBarry Smith PetscFunctionBegin; 677*82b1193eSBarry Smith 678*82b1193eSBarry Smith if (A->mapping) { 679*82b1193eSBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr); 680*82b1193eSBarry Smith } 681*82b1193eSBarry Smith if (A->bmapping) { 682*82b1193eSBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr); 683*82b1193eSBarry Smith } 684*82b1193eSBarry Smith if (A->rmap) { 685*82b1193eSBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 686*82b1193eSBarry Smith } 687*82b1193eSBarry Smith if (A->cmap) { 688*82b1193eSBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 689*82b1193eSBarry Smith } 690*82b1193eSBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 691*82b1193eSBarry Smith #if defined(PETSC_USE_LOG) 692*82b1193eSBarry Smith PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 693*82b1193eSBarry Smith #endif 694*82b1193eSBarry Smith if (a->freedata) { 695*82b1193eSBarry Smith ierr = PetscFree(a->a);CHKERRQ(ierr); 696*82b1193eSBarry Smith if (!a->singlemalloc) { 697*82b1193eSBarry Smith ierr = PetscFree(a->i);CHKERRQ(ierr); 698*82b1193eSBarry Smith ierr = PetscFree(a->j);CHKERRQ(ierr); 699*82b1193eSBarry Smith } 700*82b1193eSBarry Smith } 701*82b1193eSBarry Smith if (a->row) { 702*82b1193eSBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 703*82b1193eSBarry Smith } 704*82b1193eSBarry Smith if (a->col) { 705*82b1193eSBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 706*82b1193eSBarry Smith } 707*82b1193eSBarry Smith if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 708*82b1193eSBarry Smith if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 709*82b1193eSBarry Smith if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 710*82b1193eSBarry Smith if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 711*82b1193eSBarry Smith if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 712*82b1193eSBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 713*82b1193eSBarry Smith if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 714*82b1193eSBarry Smith ierr = PetscFree(a);CHKERRQ(ierr); 715*82b1193eSBarry Smith 716*82b1193eSBarry Smith PLogObjectDestroy(A); 717*82b1193eSBarry Smith PetscHeaderDestroy(A); 718*82b1193eSBarry Smith PetscFunctionReturn(0); 719*82b1193eSBarry Smith } 720*82b1193eSBarry Smith 721*82b1193eSBarry Smith #undef __FUNC__ 722*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCompress_SeqAIJ"></a>*/"MatCompress_SeqAIJ" 723*82b1193eSBarry Smith int MatCompress_SeqAIJ(Mat A) 724*82b1193eSBarry Smith { 725*82b1193eSBarry Smith PetscFunctionBegin; 726*82b1193eSBarry Smith PetscFunctionReturn(0); 727*82b1193eSBarry Smith } 728*82b1193eSBarry Smith 729*82b1193eSBarry Smith #undef __FUNC__ 730*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSetOption_SeqAIJ"></a>*/"MatSetOption_SeqAIJ" 731*82b1193eSBarry Smith int MatSetOption_SeqAIJ(Mat A,MatOption op) 732*82b1193eSBarry Smith { 733*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 734*82b1193eSBarry Smith 735*82b1193eSBarry Smith PetscFunctionBegin; 736*82b1193eSBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = PETSC_TRUE; 737*82b1193eSBarry Smith else if (op == MAT_KEEP_ZEROED_ROWS) a->keepzeroedrows = PETSC_TRUE; 738*82b1193eSBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = PETSC_FALSE; 739*82b1193eSBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = PETSC_TRUE; 740*82b1193eSBarry Smith else if (op == MAT_COLUMNS_UNSORTED) a->sorted = PETSC_FALSE; 741*82b1193eSBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 742*82b1193eSBarry Smith else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 743*82b1193eSBarry Smith else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 744*82b1193eSBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 745*82b1193eSBarry Smith else if (op == MAT_IGNORE_ZERO_ENTRIES) a->ignorezeroentries = PETSC_TRUE; 746*82b1193eSBarry Smith else if (op == MAT_USE_INODES) a->inode.use = PETSC_TRUE; 747*82b1193eSBarry Smith else if (op == MAT_DO_NOT_USE_INODES) a->inode.use = PETSC_FALSE; 748*82b1193eSBarry Smith else if (op == MAT_ROWS_SORTED || 749*82b1193eSBarry Smith op == MAT_ROWS_UNSORTED || 750*82b1193eSBarry Smith op == MAT_SYMMETRIC || 751*82b1193eSBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 752*82b1193eSBarry Smith op == MAT_YES_NEW_DIAGONALS || 753*82b1193eSBarry Smith op == MAT_IGNORE_OFF_PROC_ENTRIES|| 754*82b1193eSBarry Smith op == MAT_USE_HASH_TABLE) 755*82b1193eSBarry Smith PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 756*82b1193eSBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) { 757*82b1193eSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 758*82b1193eSBarry Smith } else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 759*82b1193eSBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 760*82b1193eSBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 761*82b1193eSBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 762*82b1193eSBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 763*82b1193eSBarry Smith else SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 764*82b1193eSBarry Smith PetscFunctionReturn(0); 765*82b1193eSBarry Smith } 766*82b1193eSBarry Smith 767*82b1193eSBarry Smith #undef __FUNC__ 768*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetDiagonal_SeqAIJ"></a>*/"MatGetDiagonal_SeqAIJ" 769*82b1193eSBarry Smith int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 770*82b1193eSBarry Smith { 771*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 772*82b1193eSBarry Smith int i,j,n,shift = a->indexshift,ierr; 773*82b1193eSBarry Smith Scalar *x,zero = 0.0; 774*82b1193eSBarry Smith 775*82b1193eSBarry Smith PetscFunctionBegin; 776*82b1193eSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 777*82b1193eSBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 778*82b1193eSBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 779*82b1193eSBarry Smith if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector"); 780*82b1193eSBarry Smith for (i=0; i<a->m; i++) { 781*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 782*82b1193eSBarry Smith if (a->j[j]+shift == i) { 783*82b1193eSBarry Smith x[i] = a->a[j]; 784*82b1193eSBarry Smith break; 785*82b1193eSBarry Smith } 786*82b1193eSBarry Smith } 787*82b1193eSBarry Smith } 788*82b1193eSBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 789*82b1193eSBarry Smith PetscFunctionReturn(0); 790*82b1193eSBarry Smith } 791*82b1193eSBarry Smith 792*82b1193eSBarry Smith #undef __FUNC__ 793*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMultTranspose_SeqAIJ"></a>*/"MatMultTranspose_SeqAIJ" 794*82b1193eSBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 795*82b1193eSBarry Smith { 796*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 797*82b1193eSBarry Smith Scalar *x,*y,*v,alpha,zero = 0.0; 798*82b1193eSBarry Smith int ierr,m = a->m,n,i,*idx,shift = a->indexshift; 799*82b1193eSBarry Smith 800*82b1193eSBarry Smith PetscFunctionBegin; 801*82b1193eSBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 802*82b1193eSBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 803*82b1193eSBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 804*82b1193eSBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 805*82b1193eSBarry Smith for (i=0; i<m; i++) { 806*82b1193eSBarry Smith idx = a->j + a->i[i] + shift; 807*82b1193eSBarry Smith v = a->a + a->i[i] + shift; 808*82b1193eSBarry Smith n = a->i[i+1] - a->i[i]; 809*82b1193eSBarry Smith alpha = x[i]; 810*82b1193eSBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 811*82b1193eSBarry Smith } 812*82b1193eSBarry Smith PLogFlops(2*a->nz - a->n); 813*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 814*82b1193eSBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 815*82b1193eSBarry Smith PetscFunctionReturn(0); 816*82b1193eSBarry Smith } 817*82b1193eSBarry Smith 818*82b1193eSBarry Smith #undef __FUNC__ 819*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMultTransposeAdd_SeqAIJ"></a>*/"MatMultTransposeAdd_SeqAIJ" 820*82b1193eSBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 821*82b1193eSBarry Smith { 822*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 823*82b1193eSBarry Smith Scalar *x,*y,*v,alpha; 824*82b1193eSBarry Smith int ierr,m = a->m,n,i,*idx,shift = a->indexshift; 825*82b1193eSBarry Smith 826*82b1193eSBarry Smith PetscFunctionBegin; 827*82b1193eSBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 828*82b1193eSBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 829*82b1193eSBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 830*82b1193eSBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 831*82b1193eSBarry Smith for (i=0; i<m; i++) { 832*82b1193eSBarry Smith idx = a->j + a->i[i] + shift; 833*82b1193eSBarry Smith v = a->a + a->i[i] + shift; 834*82b1193eSBarry Smith n = a->i[i+1] - a->i[i]; 835*82b1193eSBarry Smith alpha = x[i]; 836*82b1193eSBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 837*82b1193eSBarry Smith } 838*82b1193eSBarry Smith PLogFlops(2*a->nz); 839*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 840*82b1193eSBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 841*82b1193eSBarry Smith PetscFunctionReturn(0); 842*82b1193eSBarry Smith } 843*82b1193eSBarry Smith 844*82b1193eSBarry Smith #undef __FUNC__ 845*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMult_SeqAIJ"></a>*/"MatMult_SeqAIJ" 846*82b1193eSBarry Smith int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 847*82b1193eSBarry Smith { 848*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 849*82b1193eSBarry Smith Scalar *x,*y,*v,sum; 850*82b1193eSBarry Smith int ierr,m = a->m,*idx,shift = a->indexshift,*ii; 851*82b1193eSBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 852*82b1193eSBarry Smith int n,i,jrow,j; 853*82b1193eSBarry Smith #endif 854*82b1193eSBarry Smith 855*82b1193eSBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 856*82b1193eSBarry Smith #pragma disjoint(*x,*y,*v) 857*82b1193eSBarry Smith #endif 858*82b1193eSBarry Smith 859*82b1193eSBarry Smith PetscFunctionBegin; 860*82b1193eSBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 861*82b1193eSBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 862*82b1193eSBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 863*82b1193eSBarry Smith idx = a->j; 864*82b1193eSBarry Smith v = a->a; 865*82b1193eSBarry Smith ii = a->i; 866*82b1193eSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 867*82b1193eSBarry Smith fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 868*82b1193eSBarry Smith #else 869*82b1193eSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 870*82b1193eSBarry Smith idx += shift; 871*82b1193eSBarry Smith for (i=0; i<m; i++) { 872*82b1193eSBarry Smith jrow = ii[i]; 873*82b1193eSBarry Smith n = ii[i+1] - jrow; 874*82b1193eSBarry Smith sum = 0.0; 875*82b1193eSBarry Smith for (j=0; j<n; j++) { 876*82b1193eSBarry Smith sum += v[jrow]*x[idx[jrow]]; jrow++; 877*82b1193eSBarry Smith } 878*82b1193eSBarry Smith y[i] = sum; 879*82b1193eSBarry Smith } 880*82b1193eSBarry Smith #endif 881*82b1193eSBarry Smith PLogFlops(2*a->nz - m); 882*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 883*82b1193eSBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 884*82b1193eSBarry Smith PetscFunctionReturn(0); 885*82b1193eSBarry Smith } 886*82b1193eSBarry Smith 887*82b1193eSBarry Smith #undef __FUNC__ 888*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMultAdd_SeqAIJ"></a>*/"MatMultAdd_SeqAIJ" 889*82b1193eSBarry Smith int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 890*82b1193eSBarry Smith { 891*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 892*82b1193eSBarry Smith Scalar *x,*y,*z,*v,sum; 893*82b1193eSBarry Smith int ierr,m = a->m,*idx,shift = a->indexshift,*ii; 894*82b1193eSBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 895*82b1193eSBarry Smith int n,i,jrow,j; 896*82b1193eSBarry Smith #endif 897*82b1193eSBarry Smith 898*82b1193eSBarry Smith PetscFunctionBegin; 899*82b1193eSBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 900*82b1193eSBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 901*82b1193eSBarry Smith if (zz != yy) { 902*82b1193eSBarry Smith ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 903*82b1193eSBarry Smith } else { 904*82b1193eSBarry Smith z = y; 905*82b1193eSBarry Smith } 906*82b1193eSBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 907*82b1193eSBarry Smith idx = a->j; 908*82b1193eSBarry Smith v = a->a; 909*82b1193eSBarry Smith ii = a->i; 910*82b1193eSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 911*82b1193eSBarry Smith fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 912*82b1193eSBarry Smith #else 913*82b1193eSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 914*82b1193eSBarry Smith idx += shift; 915*82b1193eSBarry Smith for (i=0; i<m; i++) { 916*82b1193eSBarry Smith jrow = ii[i]; 917*82b1193eSBarry Smith n = ii[i+1] - jrow; 918*82b1193eSBarry Smith sum = y[i]; 919*82b1193eSBarry Smith for (j=0; j<n; j++) { 920*82b1193eSBarry Smith sum += v[jrow]*x[idx[jrow]]; jrow++; 921*82b1193eSBarry Smith } 922*82b1193eSBarry Smith z[i] = sum; 923*82b1193eSBarry Smith } 924*82b1193eSBarry Smith #endif 925*82b1193eSBarry Smith PLogFlops(2*a->nz); 926*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 927*82b1193eSBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 928*82b1193eSBarry Smith if (zz != yy) { 929*82b1193eSBarry Smith ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 930*82b1193eSBarry Smith } 931*82b1193eSBarry Smith PetscFunctionReturn(0); 932*82b1193eSBarry Smith } 933*82b1193eSBarry Smith 934*82b1193eSBarry Smith /* 935*82b1193eSBarry Smith Adds diagonal pointers to sparse matrix structure. 936*82b1193eSBarry Smith */ 937*82b1193eSBarry Smith #undef __FUNC__ 938*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMarkDiagonal_SeqAIJ"></a>*/"MatMarkDiagonal_SeqAIJ" 939*82b1193eSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A) 940*82b1193eSBarry Smith { 941*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 942*82b1193eSBarry Smith int i,j,*diag,m = a->m,shift = a->indexshift; 943*82b1193eSBarry Smith 944*82b1193eSBarry Smith PetscFunctionBegin; 945*82b1193eSBarry Smith if (a->diag) PetscFunctionReturn(0); 946*82b1193eSBarry Smith 947*82b1193eSBarry Smith diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(diag); 948*82b1193eSBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 949*82b1193eSBarry Smith for (i=0; i<a->m; i++) { 950*82b1193eSBarry Smith diag[i] = a->i[i+1]; 951*82b1193eSBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 952*82b1193eSBarry Smith if (a->j[j]+shift == i) { 953*82b1193eSBarry Smith diag[i] = j - shift; 954*82b1193eSBarry Smith break; 955*82b1193eSBarry Smith } 956*82b1193eSBarry Smith } 957*82b1193eSBarry Smith } 958*82b1193eSBarry Smith a->diag = diag; 959*82b1193eSBarry Smith PetscFunctionReturn(0); 960*82b1193eSBarry Smith } 961*82b1193eSBarry Smith 962*82b1193eSBarry Smith /* 963*82b1193eSBarry Smith Checks for missing diagonals 964*82b1193eSBarry Smith */ 965*82b1193eSBarry Smith #undef __FUNC__ 966*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMissingDiagonal_SeqAIJ"></a>*/"MatMissingDiagonal_SeqAIJ" 967*82b1193eSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A) 968*82b1193eSBarry Smith { 969*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 970*82b1193eSBarry Smith int *diag,*jj = a->j,i,shift = a->indexshift,ierr; 971*82b1193eSBarry Smith 972*82b1193eSBarry Smith PetscFunctionBegin; 973*82b1193eSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 974*82b1193eSBarry Smith diag = a->diag; 975*82b1193eSBarry Smith for (i=0; i<a->m; i++) { 976*82b1193eSBarry Smith if (jj[diag[i]+shift] != i-shift) { 977*82b1193eSBarry Smith SETERRQ1(1,1,"Matrix is missing diagonal number %d",i); 978*82b1193eSBarry Smith } 979*82b1193eSBarry Smith } 980*82b1193eSBarry Smith PetscFunctionReturn(0); 981*82b1193eSBarry Smith } 982*82b1193eSBarry Smith 983*82b1193eSBarry Smith #undef __FUNC__ 984*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRelax_SeqAIJ"></a>*/"MatRelax_SeqAIJ" 985*82b1193eSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,Vec xx) 986*82b1193eSBarry Smith { 987*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 988*82b1193eSBarry Smith Scalar *x,*b,*bs, d,*xs,sum,*v = a->a,*t=0,scale,*ts,*xb,*idiag=0; 989*82b1193eSBarry Smith int ierr,*idx,*diag,n = a->n,m = a->m,i,shift = a->indexshift; 990*82b1193eSBarry Smith 991*82b1193eSBarry Smith PetscFunctionBegin; 992*82b1193eSBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 993*82b1193eSBarry Smith if (xx != bb) { 994*82b1193eSBarry Smith ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 995*82b1193eSBarry Smith } else { 996*82b1193eSBarry Smith b = x; 997*82b1193eSBarry Smith } 998*82b1193eSBarry Smith 999*82b1193eSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1000*82b1193eSBarry Smith diag = a->diag; 1001*82b1193eSBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 1002*82b1193eSBarry Smith if (flag == SOR_APPLY_UPPER) { 1003*82b1193eSBarry Smith /* apply (U + D/omega) to the vector */ 1004*82b1193eSBarry Smith bs = b + shift; 1005*82b1193eSBarry Smith for (i=0; i<m; i++) { 1006*82b1193eSBarry Smith d = fshift + a->a[diag[i] + shift]; 1007*82b1193eSBarry Smith n = a->i[i+1] - diag[i] - 1; 1008*82b1193eSBarry Smith PLogFlops(2*n-1); 1009*82b1193eSBarry Smith idx = a->j + diag[i] + (!shift); 1010*82b1193eSBarry Smith v = a->a + diag[i] + (!shift); 1011*82b1193eSBarry Smith sum = b[i]*d/omega; 1012*82b1193eSBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 1013*82b1193eSBarry Smith x[i] = sum; 1014*82b1193eSBarry Smith } 1015*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1016*82b1193eSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1017*82b1193eSBarry Smith PetscFunctionReturn(0); 1018*82b1193eSBarry Smith } 1019*82b1193eSBarry Smith 1020*82b1193eSBarry Smith /* setup workspace for Eisenstat */ 1021*82b1193eSBarry Smith if (flag & SOR_EISENSTAT) { 1022*82b1193eSBarry Smith if (!a->idiag) { 1023*82b1193eSBarry Smith a->idiag = (Scalar*)PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag); 1024*82b1193eSBarry Smith a->ssor = a->idiag + m; 1025*82b1193eSBarry Smith v = a->a; 1026*82b1193eSBarry Smith for (i=0; i<m; i++) { a->idiag[i] = 1.0/v[diag[i]];} 1027*82b1193eSBarry Smith } 1028*82b1193eSBarry Smith t = a->ssor; 1029*82b1193eSBarry Smith idiag = a->idiag; 1030*82b1193eSBarry Smith } 1031*82b1193eSBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1032*82b1193eSBarry Smith U is upper triangular, E is diagonal; This routine applies 1033*82b1193eSBarry Smith 1034*82b1193eSBarry Smith (L + E)^{-1} A (U + E)^{-1} 1035*82b1193eSBarry Smith 1036*82b1193eSBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1037*82b1193eSBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 1038*82b1193eSBarry Smith is the relaxation factor. 1039*82b1193eSBarry Smith */ 1040*82b1193eSBarry Smith 1041*82b1193eSBarry Smith if (flag == SOR_APPLY_LOWER) { 1042*82b1193eSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not implemented"); 1043*82b1193eSBarry Smith } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) { 1044*82b1193eSBarry Smith /* special case for omega = 1.0 saves flops and some integer ops */ 1045*82b1193eSBarry Smith Scalar *v2; 1046*82b1193eSBarry Smith 1047*82b1193eSBarry Smith v2 = a->a; 1048*82b1193eSBarry Smith /* x = (E + U)^{-1} b */ 1049*82b1193eSBarry Smith for (i=m-1; i>=0; i--) { 1050*82b1193eSBarry Smith n = a->i[i+1] - diag[i] - 1; 1051*82b1193eSBarry Smith idx = a->j + diag[i] + 1; 1052*82b1193eSBarry Smith v = a->a + diag[i] + 1; 1053*82b1193eSBarry Smith sum = b[i]; 1054*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1055*82b1193eSBarry Smith x[i] = sum*idiag[i]; 1056*82b1193eSBarry Smith 1057*82b1193eSBarry Smith /* t = b - (2*E - D)x */ 1058*82b1193eSBarry Smith t[i] = b[i] - (v2[diag[i]])*x[i]; 1059*82b1193eSBarry Smith } 1060*82b1193eSBarry Smith 1061*82b1193eSBarry Smith /* t = (E + L)^{-1}t */ 1062*82b1193eSBarry Smith diag = a->diag; 1063*82b1193eSBarry Smith for (i=0; i<m; i++) { 1064*82b1193eSBarry Smith n = diag[i] - a->i[i]; 1065*82b1193eSBarry Smith idx = a->j + a->i[i]; 1066*82b1193eSBarry Smith v = a->a + a->i[i]; 1067*82b1193eSBarry Smith sum = t[i]; 1068*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,t,v,idx,n); 1069*82b1193eSBarry Smith t[i] = sum*idiag[i]; 1070*82b1193eSBarry Smith 1071*82b1193eSBarry Smith /* x = x + t */ 1072*82b1193eSBarry Smith x[i] += t[i]; 1073*82b1193eSBarry Smith } 1074*82b1193eSBarry Smith 1075*82b1193eSBarry Smith PLogFlops(3*m-1 + 2*a->nz); 1076*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1077*82b1193eSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1078*82b1193eSBarry Smith PetscFunctionReturn(0); 1079*82b1193eSBarry Smith } else if (flag & SOR_EISENSTAT) { 1080*82b1193eSBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1081*82b1193eSBarry Smith U is upper triangular, E is diagonal; This routine applies 1082*82b1193eSBarry Smith 1083*82b1193eSBarry Smith (L + E)^{-1} A (U + E)^{-1} 1084*82b1193eSBarry Smith 1085*82b1193eSBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1086*82b1193eSBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 1087*82b1193eSBarry Smith is the relaxation factor. 1088*82b1193eSBarry Smith */ 1089*82b1193eSBarry Smith scale = (2.0/omega) - 1.0; 1090*82b1193eSBarry Smith 1091*82b1193eSBarry Smith /* x = (E + U)^{-1} b */ 1092*82b1193eSBarry Smith for (i=m-1; i>=0; i--) { 1093*82b1193eSBarry Smith d = fshift + a->a[diag[i] + shift]; 1094*82b1193eSBarry Smith n = a->i[i+1] - diag[i] - 1; 1095*82b1193eSBarry Smith idx = a->j + diag[i] + (!shift); 1096*82b1193eSBarry Smith v = a->a + diag[i] + (!shift); 1097*82b1193eSBarry Smith sum = b[i]; 1098*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1099*82b1193eSBarry Smith x[i] = omega*(sum/d); 1100*82b1193eSBarry Smith } 1101*82b1193eSBarry Smith 1102*82b1193eSBarry Smith /* t = b - (2*E - D)x */ 1103*82b1193eSBarry Smith v = a->a; 1104*82b1193eSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 1105*82b1193eSBarry Smith 1106*82b1193eSBarry Smith /* t = (E + L)^{-1}t */ 1107*82b1193eSBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 1108*82b1193eSBarry Smith diag = a->diag; 1109*82b1193eSBarry Smith for (i=0; i<m; i++) { 1110*82b1193eSBarry Smith d = fshift + a->a[diag[i]+shift]; 1111*82b1193eSBarry Smith n = diag[i] - a->i[i]; 1112*82b1193eSBarry Smith idx = a->j + a->i[i] + shift; 1113*82b1193eSBarry Smith v = a->a + a->i[i] + shift; 1114*82b1193eSBarry Smith sum = t[i]; 1115*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1116*82b1193eSBarry Smith t[i] = omega*(sum/d); 1117*82b1193eSBarry Smith /* x = x + t */ 1118*82b1193eSBarry Smith x[i] += t[i]; 1119*82b1193eSBarry Smith } 1120*82b1193eSBarry Smith 1121*82b1193eSBarry Smith PLogFlops(6*m-1 + 2*a->nz); 1122*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1123*82b1193eSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1124*82b1193eSBarry Smith PetscFunctionReturn(0); 1125*82b1193eSBarry Smith } 1126*82b1193eSBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 1127*82b1193eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 1128*82b1193eSBarry Smith for (i=0; i<m; i++) { 1129*82b1193eSBarry Smith d = fshift + a->a[diag[i]+shift]; 1130*82b1193eSBarry Smith n = diag[i] - a->i[i]; 1131*82b1193eSBarry Smith PLogFlops(2*n-1); 1132*82b1193eSBarry Smith idx = a->j + a->i[i] + shift; 1133*82b1193eSBarry Smith v = a->a + a->i[i] + shift; 1134*82b1193eSBarry Smith sum = b[i]; 1135*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1136*82b1193eSBarry Smith x[i] = omega*(sum/d); 1137*82b1193eSBarry Smith } 1138*82b1193eSBarry Smith xb = x; 1139*82b1193eSBarry Smith } else xb = b; 1140*82b1193eSBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 1141*82b1193eSBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 1142*82b1193eSBarry Smith for (i=0; i<m; i++) { 1143*82b1193eSBarry Smith x[i] *= a->a[diag[i]+shift]; 1144*82b1193eSBarry Smith } 1145*82b1193eSBarry Smith PLogFlops(m); 1146*82b1193eSBarry Smith } 1147*82b1193eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 1148*82b1193eSBarry Smith for (i=m-1; i>=0; i--) { 1149*82b1193eSBarry Smith d = fshift + a->a[diag[i] + shift]; 1150*82b1193eSBarry Smith n = a->i[i+1] - diag[i] - 1; 1151*82b1193eSBarry Smith PLogFlops(2*n-1); 1152*82b1193eSBarry Smith idx = a->j + diag[i] + (!shift); 1153*82b1193eSBarry Smith v = a->a + diag[i] + (!shift); 1154*82b1193eSBarry Smith sum = xb[i]; 1155*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1156*82b1193eSBarry Smith x[i] = omega*(sum/d); 1157*82b1193eSBarry Smith } 1158*82b1193eSBarry Smith } 1159*82b1193eSBarry Smith its--; 1160*82b1193eSBarry Smith } 1161*82b1193eSBarry Smith while (its--) { 1162*82b1193eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 1163*82b1193eSBarry Smith for (i=0; i<m; i++) { 1164*82b1193eSBarry Smith d = fshift + a->a[diag[i]+shift]; 1165*82b1193eSBarry Smith n = a->i[i+1] - a->i[i]; 1166*82b1193eSBarry Smith PLogFlops(2*n-1); 1167*82b1193eSBarry Smith idx = a->j + a->i[i] + shift; 1168*82b1193eSBarry Smith v = a->a + a->i[i] + shift; 1169*82b1193eSBarry Smith sum = b[i]; 1170*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1171*82b1193eSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 1172*82b1193eSBarry Smith } 1173*82b1193eSBarry Smith } 1174*82b1193eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 1175*82b1193eSBarry Smith for (i=m-1; i>=0; i--) { 1176*82b1193eSBarry Smith d = fshift + a->a[diag[i] + shift]; 1177*82b1193eSBarry Smith n = a->i[i+1] - a->i[i]; 1178*82b1193eSBarry Smith PLogFlops(2*n-1); 1179*82b1193eSBarry Smith idx = a->j + a->i[i] + shift; 1180*82b1193eSBarry Smith v = a->a + a->i[i] + shift; 1181*82b1193eSBarry Smith sum = b[i]; 1182*82b1193eSBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1183*82b1193eSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 1184*82b1193eSBarry Smith } 1185*82b1193eSBarry Smith } 1186*82b1193eSBarry Smith } 1187*82b1193eSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1188*82b1193eSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1189*82b1193eSBarry Smith PetscFunctionReturn(0); 1190*82b1193eSBarry Smith } 1191*82b1193eSBarry Smith 1192*82b1193eSBarry Smith #undef __FUNC__ 1193*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetInfo_SeqAIJ"></a>*/"MatGetInfo_SeqAIJ" 1194*82b1193eSBarry Smith int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 1195*82b1193eSBarry Smith { 1196*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1197*82b1193eSBarry Smith 1198*82b1193eSBarry Smith PetscFunctionBegin; 1199*82b1193eSBarry Smith info->rows_global = (double)a->m; 1200*82b1193eSBarry Smith info->columns_global = (double)a->n; 1201*82b1193eSBarry Smith info->rows_local = (double)a->m; 1202*82b1193eSBarry Smith info->columns_local = (double)a->n; 1203*82b1193eSBarry Smith info->block_size = 1.0; 1204*82b1193eSBarry Smith info->nz_allocated = (double)a->maxnz; 1205*82b1193eSBarry Smith info->nz_used = (double)a->nz; 1206*82b1193eSBarry Smith info->nz_unneeded = (double)(a->maxnz - a->nz); 1207*82b1193eSBarry Smith info->assemblies = (double)A->num_ass; 1208*82b1193eSBarry Smith info->mallocs = (double)a->reallocs; 1209*82b1193eSBarry Smith info->memory = A->mem; 1210*82b1193eSBarry Smith if (A->factor) { 1211*82b1193eSBarry Smith info->fill_ratio_given = A->info.fill_ratio_given; 1212*82b1193eSBarry Smith info->fill_ratio_needed = A->info.fill_ratio_needed; 1213*82b1193eSBarry Smith info->factor_mallocs = A->info.factor_mallocs; 1214*82b1193eSBarry Smith } else { 1215*82b1193eSBarry Smith info->fill_ratio_given = 0; 1216*82b1193eSBarry Smith info->fill_ratio_needed = 0; 1217*82b1193eSBarry Smith info->factor_mallocs = 0; 1218*82b1193eSBarry Smith } 1219*82b1193eSBarry Smith PetscFunctionReturn(0); 1220*82b1193eSBarry Smith } 1221*82b1193eSBarry Smith 1222*82b1193eSBarry Smith EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatLUInfo*,Mat*); 1223*82b1193eSBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 1224*82b1193eSBarry Smith EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatLUInfo*); 1225*82b1193eSBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec); 1226*82b1193eSBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 1227*82b1193eSBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec); 1228*82b1193eSBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec); 1229*82b1193eSBarry Smith 1230*82b1193eSBarry Smith #undef __FUNC__ 1231*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatZeroRows_SeqAIJ"></a>*/"MatZeroRows_SeqAIJ" 1232*82b1193eSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 1233*82b1193eSBarry Smith { 1234*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1235*82b1193eSBarry Smith int i,ierr,N,*rows,m = a->m - 1,shift = a->indexshift; 1236*82b1193eSBarry Smith 1237*82b1193eSBarry Smith PetscFunctionBegin; 1238*82b1193eSBarry Smith ierr = ISGetSize(is,&N);CHKERRQ(ierr); 1239*82b1193eSBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1240*82b1193eSBarry Smith if (a->keepzeroedrows) { 1241*82b1193eSBarry Smith for (i=0; i<N; i++) { 1242*82b1193eSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1243*82b1193eSBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]+shift],a->ilen[rows[i]]*sizeof(Scalar));CHKERRQ(ierr); 1244*82b1193eSBarry Smith } 1245*82b1193eSBarry Smith if (diag) { 1246*82b1193eSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1247*82b1193eSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1248*82b1193eSBarry Smith for (i=0; i<N; i++) { 1249*82b1193eSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1250*82b1193eSBarry Smith } 1251*82b1193eSBarry Smith } 1252*82b1193eSBarry Smith } else { 1253*82b1193eSBarry Smith if (diag) { 1254*82b1193eSBarry Smith for (i=0; i<N; i++) { 1255*82b1193eSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1256*82b1193eSBarry Smith if (a->ilen[rows[i]] > 0) { 1257*82b1193eSBarry Smith a->ilen[rows[i]] = 1; 1258*82b1193eSBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1259*82b1193eSBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 1260*82b1193eSBarry Smith } else { /* in case row was completely empty */ 1261*82b1193eSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 1262*82b1193eSBarry Smith } 1263*82b1193eSBarry Smith } 1264*82b1193eSBarry Smith } else { 1265*82b1193eSBarry Smith for (i=0; i<N; i++) { 1266*82b1193eSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1267*82b1193eSBarry Smith a->ilen[rows[i]] = 0; 1268*82b1193eSBarry Smith } 1269*82b1193eSBarry Smith } 1270*82b1193eSBarry Smith } 1271*82b1193eSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 1272*82b1193eSBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1273*82b1193eSBarry Smith PetscFunctionReturn(0); 1274*82b1193eSBarry Smith } 1275*82b1193eSBarry Smith 1276*82b1193eSBarry Smith #undef __FUNC__ 1277*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetSize_SeqAIJ"></a>*/"MatGetSize_SeqAIJ" 1278*82b1193eSBarry Smith int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 1279*82b1193eSBarry Smith { 1280*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1281*82b1193eSBarry Smith 1282*82b1193eSBarry Smith PetscFunctionBegin; 1283*82b1193eSBarry Smith if (m) *m = a->m; 1284*82b1193eSBarry Smith if (n) *n = a->n; 1285*82b1193eSBarry Smith PetscFunctionReturn(0); 1286*82b1193eSBarry Smith } 1287*82b1193eSBarry Smith 1288*82b1193eSBarry Smith #undef __FUNC__ 1289*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetOwnershipRange_SeqAIJ"></a>*/"MatGetOwnershipRange_SeqAIJ" 1290*82b1193eSBarry Smith int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 1291*82b1193eSBarry Smith { 1292*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1293*82b1193eSBarry Smith 1294*82b1193eSBarry Smith PetscFunctionBegin; 1295*82b1193eSBarry Smith if (m) *m = 0; 1296*82b1193eSBarry Smith if (n) *n = a->m; 1297*82b1193eSBarry Smith PetscFunctionReturn(0); 1298*82b1193eSBarry Smith } 1299*82b1193eSBarry Smith 1300*82b1193eSBarry Smith #undef __FUNC__ 1301*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetRow_SeqAIJ"></a>*/"MatGetRow_SeqAIJ" 1302*82b1193eSBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 1303*82b1193eSBarry Smith { 1304*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1305*82b1193eSBarry Smith int *itmp,i,shift = a->indexshift; 1306*82b1193eSBarry Smith 1307*82b1193eSBarry Smith PetscFunctionBegin; 1308*82b1193eSBarry Smith if (row < 0 || row >= a->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"Row %d out of range",row); 1309*82b1193eSBarry Smith 1310*82b1193eSBarry Smith *nz = a->i[row+1] - a->i[row]; 1311*82b1193eSBarry Smith if (v) *v = a->a + a->i[row] + shift; 1312*82b1193eSBarry Smith if (idx) { 1313*82b1193eSBarry Smith itmp = a->j + a->i[row] + shift; 1314*82b1193eSBarry Smith if (*nz && shift) { 1315*82b1193eSBarry Smith *idx = (int*)PetscMalloc((*nz)*sizeof(int));CHKPTRQ(*idx); 1316*82b1193eSBarry Smith for (i=0; i<(*nz); i++) {(*idx)[i] = itmp[i] + shift;} 1317*82b1193eSBarry Smith } else if (*nz) { 1318*82b1193eSBarry Smith *idx = itmp; 1319*82b1193eSBarry Smith } 1320*82b1193eSBarry Smith else *idx = 0; 1321*82b1193eSBarry Smith } 1322*82b1193eSBarry Smith PetscFunctionReturn(0); 1323*82b1193eSBarry Smith } 1324*82b1193eSBarry Smith 1325*82b1193eSBarry Smith #undef __FUNC__ 1326*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRestoreRow_SeqAIJ"></a>*/"MatRestoreRow_SeqAIJ" 1327*82b1193eSBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 1328*82b1193eSBarry Smith { 1329*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1330*82b1193eSBarry Smith int ierr; 1331*82b1193eSBarry Smith 1332*82b1193eSBarry Smith PetscFunctionBegin; 1333*82b1193eSBarry Smith if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 1334*82b1193eSBarry Smith PetscFunctionReturn(0); 1335*82b1193eSBarry Smith } 1336*82b1193eSBarry Smith 1337*82b1193eSBarry Smith #undef __FUNC__ 1338*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatNorm_SeqAIJ"></a>*/"MatNorm_SeqAIJ" 1339*82b1193eSBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *norm) 1340*82b1193eSBarry Smith { 1341*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1342*82b1193eSBarry Smith Scalar *v = a->a; 1343*82b1193eSBarry Smith PetscReal sum = 0.0; 1344*82b1193eSBarry Smith int i,j,shift = a->indexshift,ierr; 1345*82b1193eSBarry Smith 1346*82b1193eSBarry Smith PetscFunctionBegin; 1347*82b1193eSBarry Smith if (type == NORM_FROBENIUS) { 1348*82b1193eSBarry Smith for (i=0; i<a->nz; i++) { 1349*82b1193eSBarry Smith #if defined(PETSC_USE_COMPLEX) 1350*82b1193eSBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1351*82b1193eSBarry Smith #else 1352*82b1193eSBarry Smith sum += (*v)*(*v); v++; 1353*82b1193eSBarry Smith #endif 1354*82b1193eSBarry Smith } 1355*82b1193eSBarry Smith *norm = sqrt(sum); 1356*82b1193eSBarry Smith } else if (type == NORM_1) { 1357*82b1193eSBarry Smith PetscReal *tmp; 1358*82b1193eSBarry Smith int *jj = a->j; 1359*82b1193eSBarry Smith tmp = (PetscReal*)PetscMalloc((a->n+1)*sizeof(PetscReal));CHKPTRQ(tmp); 1360*82b1193eSBarry Smith ierr = PetscMemzero(tmp,a->n*sizeof(PetscReal));CHKERRQ(ierr); 1361*82b1193eSBarry Smith *norm = 0.0; 1362*82b1193eSBarry Smith for (j=0; j<a->nz; j++) { 1363*82b1193eSBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 1364*82b1193eSBarry Smith } 1365*82b1193eSBarry Smith for (j=0; j<a->n; j++) { 1366*82b1193eSBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 1367*82b1193eSBarry Smith } 1368*82b1193eSBarry Smith ierr = PetscFree(tmp);CHKERRQ(ierr); 1369*82b1193eSBarry Smith } else if (type == NORM_INFINITY) { 1370*82b1193eSBarry Smith *norm = 0.0; 1371*82b1193eSBarry Smith for (j=0; j<a->m; j++) { 1372*82b1193eSBarry Smith v = a->a + a->i[j] + shift; 1373*82b1193eSBarry Smith sum = 0.0; 1374*82b1193eSBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1375*82b1193eSBarry Smith sum += PetscAbsScalar(*v); v++; 1376*82b1193eSBarry Smith } 1377*82b1193eSBarry Smith if (sum > *norm) *norm = sum; 1378*82b1193eSBarry Smith } 1379*82b1193eSBarry Smith } else { 1380*82b1193eSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"No support for two norm"); 1381*82b1193eSBarry Smith } 1382*82b1193eSBarry Smith PetscFunctionReturn(0); 1383*82b1193eSBarry Smith } 1384*82b1193eSBarry Smith 1385*82b1193eSBarry Smith #undef __FUNC__ 1386*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatTranspose_SeqAIJ"></a>*/"MatTranspose_SeqAIJ" 1387*82b1193eSBarry Smith int MatTranspose_SeqAIJ(Mat A,Mat *B) 1388*82b1193eSBarry Smith { 1389*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1390*82b1193eSBarry Smith Mat C; 1391*82b1193eSBarry Smith int i,ierr,*aj = a->j,*ai = a->i,m = a->m,len,*col; 1392*82b1193eSBarry Smith int shift = a->indexshift,refct; 1393*82b1193eSBarry Smith Scalar *array = a->a; 1394*82b1193eSBarry Smith 1395*82b1193eSBarry Smith PetscFunctionBegin; 1396*82b1193eSBarry Smith if (!B && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place"); 1397*82b1193eSBarry Smith col = (int*)PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col); 1398*82b1193eSBarry Smith ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr); 1399*82b1193eSBarry Smith if (shift) { 1400*82b1193eSBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] -= 1; 1401*82b1193eSBarry Smith } 1402*82b1193eSBarry Smith for (i=0; i<ai[m]+shift; i++) col[aj[i]] += 1; 1403*82b1193eSBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr); 1404*82b1193eSBarry Smith ierr = PetscFree(col);CHKERRQ(ierr); 1405*82b1193eSBarry Smith for (i=0; i<m; i++) { 1406*82b1193eSBarry Smith len = ai[i+1]-ai[i]; 1407*82b1193eSBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1408*82b1193eSBarry Smith array += len; aj += len; 1409*82b1193eSBarry Smith } 1410*82b1193eSBarry Smith if (shift) { 1411*82b1193eSBarry Smith for (i=0; i<ai[m]-1; i++) aj[i] += 1; 1412*82b1193eSBarry Smith } 1413*82b1193eSBarry Smith 1414*82b1193eSBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1415*82b1193eSBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1416*82b1193eSBarry Smith 1417*82b1193eSBarry Smith if (B) { 1418*82b1193eSBarry Smith *B = C; 1419*82b1193eSBarry Smith } else { 1420*82b1193eSBarry Smith PetscOps *Abops; 1421*82b1193eSBarry Smith MatOps Aops; 1422*82b1193eSBarry Smith 1423*82b1193eSBarry Smith /* This isn't really an in-place transpose */ 1424*82b1193eSBarry Smith ierr = PetscFree(a->a);CHKERRQ(ierr); 1425*82b1193eSBarry Smith if (!a->singlemalloc) { 1426*82b1193eSBarry Smith ierr = PetscFree(a->i);CHKERRQ(ierr); 1427*82b1193eSBarry Smith ierr = PetscFree(a->j); 1428*82b1193eSBarry Smith } 1429*82b1193eSBarry Smith if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 1430*82b1193eSBarry Smith if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 1431*82b1193eSBarry Smith if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 1432*82b1193eSBarry Smith if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 1433*82b1193eSBarry Smith if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 1434*82b1193eSBarry Smith ierr = PetscFree(a);CHKERRQ(ierr); 1435*82b1193eSBarry Smith 1436*82b1193eSBarry Smith 1437*82b1193eSBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 1438*82b1193eSBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 1439*82b1193eSBarry Smith 1440*82b1193eSBarry Smith /* 1441*82b1193eSBarry Smith This is horrible, horrible code. We need to keep the 1442*82b1193eSBarry Smith the bops and ops Structures, copy everything from C 1443*82b1193eSBarry Smith including the function pointers.. 1444*82b1193eSBarry Smith */ 1445*82b1193eSBarry Smith ierr = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1446*82b1193eSBarry Smith ierr = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr); 1447*82b1193eSBarry Smith Abops = A->bops; 1448*82b1193eSBarry Smith Aops = A->ops; 1449*82b1193eSBarry Smith refct = A->refct; 1450*82b1193eSBarry Smith ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 1451*82b1193eSBarry Smith A->bops = Abops; 1452*82b1193eSBarry Smith A->ops = Aops; 1453*82b1193eSBarry Smith A->qlist = 0; 1454*82b1193eSBarry Smith A->refct = refct; 1455*82b1193eSBarry Smith /* copy over the type_name and name */ 1456*82b1193eSBarry Smith ierr = PetscStrallocpy(C->type_name,&A->type_name);CHKERRQ(ierr); 1457*82b1193eSBarry Smith ierr = PetscStrallocpy(C->name,&A->name);CHKERRQ(ierr); 1458*82b1193eSBarry Smith 1459*82b1193eSBarry Smith PetscHeaderDestroy(C); 1460*82b1193eSBarry Smith } 1461*82b1193eSBarry Smith PetscFunctionReturn(0); 1462*82b1193eSBarry Smith } 1463*82b1193eSBarry Smith 1464*82b1193eSBarry Smith #undef __FUNC__ 1465*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatDiagonalScale_SeqAIJ"></a>*/"MatDiagonalScale_SeqAIJ" 1466*82b1193eSBarry Smith int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 1467*82b1193eSBarry Smith { 1468*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1469*82b1193eSBarry Smith Scalar *l,*r,x,*v; 1470*82b1193eSBarry Smith int ierr,i,j,m = a->m,n = a->n,M,nz = a->nz,*jj,shift = a->indexshift; 1471*82b1193eSBarry Smith 1472*82b1193eSBarry Smith PetscFunctionBegin; 1473*82b1193eSBarry Smith if (ll) { 1474*82b1193eSBarry Smith /* The local size is used so that VecMPI can be passed to this routine 1475*82b1193eSBarry Smith by MatDiagonalScale_MPIAIJ */ 1476*82b1193eSBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1477*82b1193eSBarry Smith if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length"); 1478*82b1193eSBarry Smith ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1479*82b1193eSBarry Smith v = a->a; 1480*82b1193eSBarry Smith for (i=0; i<m; i++) { 1481*82b1193eSBarry Smith x = l[i]; 1482*82b1193eSBarry Smith M = a->i[i+1] - a->i[i]; 1483*82b1193eSBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 1484*82b1193eSBarry Smith } 1485*82b1193eSBarry Smith ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1486*82b1193eSBarry Smith PLogFlops(nz); 1487*82b1193eSBarry Smith } 1488*82b1193eSBarry Smith if (rr) { 1489*82b1193eSBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1490*82b1193eSBarry Smith if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length"); 1491*82b1193eSBarry Smith ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1492*82b1193eSBarry Smith v = a->a; jj = a->j; 1493*82b1193eSBarry Smith for (i=0; i<nz; i++) { 1494*82b1193eSBarry Smith (*v++) *= r[*jj++ + shift]; 1495*82b1193eSBarry Smith } 1496*82b1193eSBarry Smith ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1497*82b1193eSBarry Smith PLogFlops(nz); 1498*82b1193eSBarry Smith } 1499*82b1193eSBarry Smith PetscFunctionReturn(0); 1500*82b1193eSBarry Smith } 1501*82b1193eSBarry Smith 1502*82b1193eSBarry Smith #undef __FUNC__ 1503*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetSubMatrix_SeqAIJ"></a>*/"MatGetSubMatrix_SeqAIJ" 1504*82b1193eSBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 1505*82b1193eSBarry Smith { 1506*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 1507*82b1193eSBarry Smith int *smap,i,k,kstart,kend,ierr,oldcols = a->n,*lens; 1508*82b1193eSBarry Smith int row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 1509*82b1193eSBarry Smith int *irow,*icol,nrows,ncols,shift = a->indexshift,*ssmap; 1510*82b1193eSBarry Smith int *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 1511*82b1193eSBarry Smith Scalar *a_new,*mat_a; 1512*82b1193eSBarry Smith Mat C; 1513*82b1193eSBarry Smith PetscTruth stride; 1514*82b1193eSBarry Smith 1515*82b1193eSBarry Smith PetscFunctionBegin; 1516*82b1193eSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 1517*82b1193eSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted"); 1518*82b1193eSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 1519*82b1193eSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted"); 1520*82b1193eSBarry Smith 1521*82b1193eSBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1522*82b1193eSBarry Smith ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr); 1523*82b1193eSBarry Smith ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr); 1524*82b1193eSBarry Smith 1525*82b1193eSBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1526*82b1193eSBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1527*82b1193eSBarry Smith if (stride && step == 1) { 1528*82b1193eSBarry Smith /* special case of contiguous rows */ 1529*82b1193eSBarry Smith lens = (int*)PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens); 1530*82b1193eSBarry Smith starts = lens + ncols; 1531*82b1193eSBarry Smith /* loop over new rows determining lens and starting points */ 1532*82b1193eSBarry Smith for (i=0; i<nrows; i++) { 1533*82b1193eSBarry Smith kstart = ai[irow[i]]+shift; 1534*82b1193eSBarry Smith kend = kstart + ailen[irow[i]]; 1535*82b1193eSBarry Smith for (k=kstart; k<kend; k++) { 1536*82b1193eSBarry Smith if (aj[k]+shift >= first) { 1537*82b1193eSBarry Smith starts[i] = k; 1538*82b1193eSBarry Smith break; 1539*82b1193eSBarry Smith } 1540*82b1193eSBarry Smith } 1541*82b1193eSBarry Smith sum = 0; 1542*82b1193eSBarry Smith while (k < kend) { 1543*82b1193eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1544*82b1193eSBarry Smith sum++; 1545*82b1193eSBarry Smith } 1546*82b1193eSBarry Smith lens[i] = sum; 1547*82b1193eSBarry Smith } 1548*82b1193eSBarry Smith /* create submatrix */ 1549*82b1193eSBarry Smith if (scall == MAT_REUSE_MATRIX) { 1550*82b1193eSBarry Smith int n_cols,n_rows; 1551*82b1193eSBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1552*82b1193eSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1553*82b1193eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 1554*82b1193eSBarry Smith C = *B; 1555*82b1193eSBarry Smith } else { 1556*82b1193eSBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 1557*82b1193eSBarry Smith } 1558*82b1193eSBarry Smith c = (Mat_SeqAIJ*)C->data; 1559*82b1193eSBarry Smith 1560*82b1193eSBarry Smith /* loop over rows inserting into submatrix */ 1561*82b1193eSBarry Smith a_new = c->a; 1562*82b1193eSBarry Smith j_new = c->j; 1563*82b1193eSBarry Smith i_new = c->i; 1564*82b1193eSBarry Smith i_new[0] = -shift; 1565*82b1193eSBarry Smith for (i=0; i<nrows; i++) { 1566*82b1193eSBarry Smith ii = starts[i]; 1567*82b1193eSBarry Smith lensi = lens[i]; 1568*82b1193eSBarry Smith for (k=0; k<lensi; k++) { 1569*82b1193eSBarry Smith *j_new++ = aj[ii+k] - first; 1570*82b1193eSBarry Smith } 1571*82b1193eSBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr); 1572*82b1193eSBarry Smith a_new += lensi; 1573*82b1193eSBarry Smith i_new[i+1] = i_new[i] + lensi; 1574*82b1193eSBarry Smith c->ilen[i] = lensi; 1575*82b1193eSBarry Smith } 1576*82b1193eSBarry Smith ierr = PetscFree(lens);CHKERRQ(ierr); 1577*82b1193eSBarry Smith } else { 1578*82b1193eSBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1579*82b1193eSBarry Smith smap = (int*)PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap); 1580*82b1193eSBarry Smith ssmap = smap + shift; 1581*82b1193eSBarry Smith lens = (int*)PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens); 1582*82b1193eSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 1583*82b1193eSBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 1584*82b1193eSBarry Smith /* determine lens of each row */ 1585*82b1193eSBarry Smith for (i=0; i<nrows; i++) { 1586*82b1193eSBarry Smith kstart = ai[irow[i]]+shift; 1587*82b1193eSBarry Smith kend = kstart + a->ilen[irow[i]]; 1588*82b1193eSBarry Smith lens[i] = 0; 1589*82b1193eSBarry Smith for (k=kstart; k<kend; k++) { 1590*82b1193eSBarry Smith if (ssmap[aj[k]]) { 1591*82b1193eSBarry Smith lens[i]++; 1592*82b1193eSBarry Smith } 1593*82b1193eSBarry Smith } 1594*82b1193eSBarry Smith } 1595*82b1193eSBarry Smith /* Create and fill new matrix */ 1596*82b1193eSBarry Smith if (scall == MAT_REUSE_MATRIX) { 1597*82b1193eSBarry Smith PetscTruth equal; 1598*82b1193eSBarry Smith 1599*82b1193eSBarry Smith c = (Mat_SeqAIJ *)((*B)->data); 1600*82b1193eSBarry Smith if (c->m != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size"); 1601*82b1193eSBarry Smith ierr = PetscMemcmp(c->ilen,lens,c->m*sizeof(int),&equal);CHKERRQ(ierr); 1602*82b1193eSBarry Smith if (!equal) { 1603*82b1193eSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros"); 1604*82b1193eSBarry Smith } 1605*82b1193eSBarry Smith ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr); 1606*82b1193eSBarry Smith C = *B; 1607*82b1193eSBarry Smith } else { 1608*82b1193eSBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 1609*82b1193eSBarry Smith } 1610*82b1193eSBarry Smith c = (Mat_SeqAIJ *)(C->data); 1611*82b1193eSBarry Smith for (i=0; i<nrows; i++) { 1612*82b1193eSBarry Smith row = irow[i]; 1613*82b1193eSBarry Smith kstart = ai[row]+shift; 1614*82b1193eSBarry Smith kend = kstart + a->ilen[row]; 1615*82b1193eSBarry Smith mat_i = c->i[i]+shift; 1616*82b1193eSBarry Smith mat_j = c->j + mat_i; 1617*82b1193eSBarry Smith mat_a = c->a + mat_i; 1618*82b1193eSBarry Smith mat_ilen = c->ilen + i; 1619*82b1193eSBarry Smith for (k=kstart; k<kend; k++) { 1620*82b1193eSBarry Smith if ((tcol=ssmap[a->j[k]])) { 1621*82b1193eSBarry Smith *mat_j++ = tcol - (!shift); 1622*82b1193eSBarry Smith *mat_a++ = a->a[k]; 1623*82b1193eSBarry Smith (*mat_ilen)++; 1624*82b1193eSBarry Smith 1625*82b1193eSBarry Smith } 1626*82b1193eSBarry Smith } 1627*82b1193eSBarry Smith } 1628*82b1193eSBarry Smith /* Free work space */ 1629*82b1193eSBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1630*82b1193eSBarry Smith ierr = PetscFree(smap);CHKERRQ(ierr); 1631*82b1193eSBarry Smith ierr = PetscFree(lens);CHKERRQ(ierr); 1632*82b1193eSBarry Smith } 1633*82b1193eSBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1634*82b1193eSBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1635*82b1193eSBarry Smith 1636*82b1193eSBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1637*82b1193eSBarry Smith *B = C; 1638*82b1193eSBarry Smith PetscFunctionReturn(0); 1639*82b1193eSBarry Smith } 1640*82b1193eSBarry Smith 1641*82b1193eSBarry Smith /* 1642*82b1193eSBarry Smith */ 1643*82b1193eSBarry Smith #undef __FUNC__ 1644*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatILUFactor_SeqAIJ"></a>*/"MatILUFactor_SeqAIJ" 1645*82b1193eSBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 1646*82b1193eSBarry Smith { 1647*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1648*82b1193eSBarry Smith int ierr; 1649*82b1193eSBarry Smith Mat outA; 1650*82b1193eSBarry Smith PetscTruth row_identity,col_identity; 1651*82b1193eSBarry Smith 1652*82b1193eSBarry Smith PetscFunctionBegin; 1653*82b1193eSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu"); 1654*82b1193eSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1655*82b1193eSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1656*82b1193eSBarry Smith if (!row_identity || !col_identity) { 1657*82b1193eSBarry Smith SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU"); 1658*82b1193eSBarry Smith } 1659*82b1193eSBarry Smith 1660*82b1193eSBarry Smith outA = inA; 1661*82b1193eSBarry Smith inA->factor = FACTOR_LU; 1662*82b1193eSBarry Smith a->row = row; 1663*82b1193eSBarry Smith a->col = col; 1664*82b1193eSBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1665*82b1193eSBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 1666*82b1193eSBarry Smith 1667*82b1193eSBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1668*82b1193eSBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 1669*82b1193eSBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1670*82b1193eSBarry Smith PLogObjectParent(inA,a->icol); 1671*82b1193eSBarry Smith 1672*82b1193eSBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 1673*82b1193eSBarry Smith a->solve_work = (Scalar*)PetscMalloc((a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work); 1674*82b1193eSBarry Smith } 1675*82b1193eSBarry Smith 1676*82b1193eSBarry Smith if (!a->diag) { 1677*82b1193eSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 1678*82b1193eSBarry Smith } 1679*82b1193eSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 1680*82b1193eSBarry Smith PetscFunctionReturn(0); 1681*82b1193eSBarry Smith } 1682*82b1193eSBarry Smith 1683*82b1193eSBarry Smith #include "pinclude/blaslapack.h" 1684*82b1193eSBarry Smith #undef __FUNC__ 1685*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatScale_SeqAIJ"></a>*/"MatScale_SeqAIJ" 1686*82b1193eSBarry Smith int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1687*82b1193eSBarry Smith { 1688*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1689*82b1193eSBarry Smith int one = 1; 1690*82b1193eSBarry Smith 1691*82b1193eSBarry Smith PetscFunctionBegin; 1692*82b1193eSBarry Smith BLscal_(&a->nz,alpha,a->a,&one); 1693*82b1193eSBarry Smith PLogFlops(a->nz); 1694*82b1193eSBarry Smith PetscFunctionReturn(0); 1695*82b1193eSBarry Smith } 1696*82b1193eSBarry Smith 1697*82b1193eSBarry Smith #undef __FUNC__ 1698*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetSubMatrices_SeqAIJ"></a>*/"MatGetSubMatrices_SeqAIJ" 1699*82b1193eSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,IS *irow,IS *icol,MatReuse scall,Mat **B) 1700*82b1193eSBarry Smith { 1701*82b1193eSBarry Smith int ierr,i; 1702*82b1193eSBarry Smith 1703*82b1193eSBarry Smith PetscFunctionBegin; 1704*82b1193eSBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1705*82b1193eSBarry Smith *B = (Mat*)PetscMalloc((n+1)*sizeof(Mat));CHKPTRQ(*B); 1706*82b1193eSBarry Smith } 1707*82b1193eSBarry Smith 1708*82b1193eSBarry Smith for (i=0; i<n; i++) { 1709*82b1193eSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1710*82b1193eSBarry Smith } 1711*82b1193eSBarry Smith PetscFunctionReturn(0); 1712*82b1193eSBarry Smith } 1713*82b1193eSBarry Smith 1714*82b1193eSBarry Smith #undef __FUNC__ 1715*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatGetBlockSize_SeqAIJ"></a>*/"MatGetBlockSize_SeqAIJ" 1716*82b1193eSBarry Smith int MatGetBlockSize_SeqAIJ(Mat A,int *bs) 1717*82b1193eSBarry Smith { 1718*82b1193eSBarry Smith PetscFunctionBegin; 1719*82b1193eSBarry Smith *bs = 1; 1720*82b1193eSBarry Smith PetscFunctionReturn(0); 1721*82b1193eSBarry Smith } 1722*82b1193eSBarry Smith 1723*82b1193eSBarry Smith #undef __FUNC__ 1724*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatIncreaseOverlap_SeqAIJ"></a>*/"MatIncreaseOverlap_SeqAIJ" 1725*82b1193eSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS *is,int ov) 1726*82b1193eSBarry Smith { 1727*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1728*82b1193eSBarry Smith int shift,row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val; 1729*82b1193eSBarry Smith int start,end,*ai,*aj; 1730*82b1193eSBarry Smith PetscBT table; 1731*82b1193eSBarry Smith 1732*82b1193eSBarry Smith PetscFunctionBegin; 1733*82b1193eSBarry Smith shift = a->indexshift; 1734*82b1193eSBarry Smith m = a->m; 1735*82b1193eSBarry Smith ai = a->i; 1736*82b1193eSBarry Smith aj = a->j+shift; 1737*82b1193eSBarry Smith 1738*82b1193eSBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used"); 1739*82b1193eSBarry Smith 1740*82b1193eSBarry Smith nidx = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx); 1741*82b1193eSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 1742*82b1193eSBarry Smith 1743*82b1193eSBarry Smith for (i=0; i<is_max; i++) { 1744*82b1193eSBarry Smith /* Initialize the two local arrays */ 1745*82b1193eSBarry Smith isz = 0; 1746*82b1193eSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1747*82b1193eSBarry Smith 1748*82b1193eSBarry Smith /* Extract the indices, assume there can be duplicate entries */ 1749*82b1193eSBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1750*82b1193eSBarry Smith ierr = ISGetSize(is[i],&n);CHKERRQ(ierr); 1751*82b1193eSBarry Smith 1752*82b1193eSBarry Smith /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1753*82b1193eSBarry Smith for (j=0; j<n ; ++j){ 1754*82b1193eSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 1755*82b1193eSBarry Smith } 1756*82b1193eSBarry Smith ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 1757*82b1193eSBarry Smith ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1758*82b1193eSBarry Smith 1759*82b1193eSBarry Smith k = 0; 1760*82b1193eSBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 1761*82b1193eSBarry Smith n = isz; 1762*82b1193eSBarry Smith for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1763*82b1193eSBarry Smith row = nidx[k]; 1764*82b1193eSBarry Smith start = ai[row]; 1765*82b1193eSBarry Smith end = ai[row+1]; 1766*82b1193eSBarry Smith for (l = start; l<end ; l++){ 1767*82b1193eSBarry Smith val = aj[l] + shift; 1768*82b1193eSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1769*82b1193eSBarry Smith } 1770*82b1193eSBarry Smith } 1771*82b1193eSBarry Smith } 1772*82b1193eSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1773*82b1193eSBarry Smith } 1774*82b1193eSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1775*82b1193eSBarry Smith ierr = PetscFree(nidx);CHKERRQ(ierr); 1776*82b1193eSBarry Smith PetscFunctionReturn(0); 1777*82b1193eSBarry Smith } 1778*82b1193eSBarry Smith 1779*82b1193eSBarry Smith /* -------------------------------------------------------------- */ 1780*82b1193eSBarry Smith #undef __FUNC__ 1781*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatPermute_SeqAIJ"></a>*/"MatPermute_SeqAIJ" 1782*82b1193eSBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 1783*82b1193eSBarry Smith { 1784*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1785*82b1193eSBarry Smith Scalar *vwork; 1786*82b1193eSBarry Smith int i,ierr,nz,m = a->m,n = a->n,*cwork; 1787*82b1193eSBarry Smith int *row,*col,*cnew,j,*lens; 1788*82b1193eSBarry Smith IS icolp,irowp; 1789*82b1193eSBarry Smith 1790*82b1193eSBarry Smith PetscFunctionBegin; 1791*82b1193eSBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 1792*82b1193eSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 1793*82b1193eSBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 1794*82b1193eSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 1795*82b1193eSBarry Smith 1796*82b1193eSBarry Smith /* determine lengths of permuted rows */ 1797*82b1193eSBarry Smith lens = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(lens); 1798*82b1193eSBarry Smith for (i=0; i<m; i++) { 1799*82b1193eSBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 1800*82b1193eSBarry Smith } 1801*82b1193eSBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1802*82b1193eSBarry Smith ierr = PetscFree(lens);CHKERRQ(ierr); 1803*82b1193eSBarry Smith 1804*82b1193eSBarry Smith cnew = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(cnew); 1805*82b1193eSBarry Smith for (i=0; i<m; i++) { 1806*82b1193eSBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 1807*82b1193eSBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 1808*82b1193eSBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 1809*82b1193eSBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 1810*82b1193eSBarry Smith } 1811*82b1193eSBarry Smith ierr = PetscFree(cnew);CHKERRQ(ierr); 1812*82b1193eSBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1813*82b1193eSBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1814*82b1193eSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 1815*82b1193eSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 1816*82b1193eSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 1817*82b1193eSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 1818*82b1193eSBarry Smith PetscFunctionReturn(0); 1819*82b1193eSBarry Smith } 1820*82b1193eSBarry Smith 1821*82b1193eSBarry Smith #undef __FUNC__ 1822*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatPrintHelp_SeqAIJ"></a>*/"MatPrintHelp_SeqAIJ" 1823*82b1193eSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1824*82b1193eSBarry Smith { 1825*82b1193eSBarry Smith static PetscTruth called = PETSC_FALSE; 1826*82b1193eSBarry Smith MPI_Comm comm = A->comm; 1827*82b1193eSBarry Smith int ierr; 1828*82b1193eSBarry Smith 1829*82b1193eSBarry Smith PetscFunctionBegin; 1830*82b1193eSBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1831*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1832*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1833*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1834*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1835*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 1836*82b1193eSBarry Smith #if defined(PETSC_HAVE_ESSL) 1837*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1838*82b1193eSBarry Smith #endif 1839*82b1193eSBarry Smith #if defined(PETSC_HAVE_MATLAB) 1840*82b1193eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr); 1841*82b1193eSBarry Smith #endif 1842*82b1193eSBarry Smith PetscFunctionReturn(0); 1843*82b1193eSBarry Smith } 1844*82b1193eSBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg); 1845*82b1193eSBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1846*82b1193eSBarry Smith EXTERN int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 1847*82b1193eSBarry Smith EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatILUInfo*,IS,IS,Mat*); 1848*82b1193eSBarry Smith #undef __FUNC__ 1849*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCopy_SeqAIJ"></a>*/"MatCopy_SeqAIJ" 1850*82b1193eSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1851*82b1193eSBarry Smith { 1852*82b1193eSBarry Smith int ierr; 1853*82b1193eSBarry Smith 1854*82b1193eSBarry Smith PetscFunctionBegin; 1855*82b1193eSBarry Smith if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) { 1856*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1857*82b1193eSBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1858*82b1193eSBarry Smith 1859*82b1193eSBarry Smith if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) { 1860*82b1193eSBarry Smith SETERRQ(1,1,"Number of nonzeros in two matrices are different"); 1861*82b1193eSBarry Smith } 1862*82b1193eSBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 1863*82b1193eSBarry Smith } else { 1864*82b1193eSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1865*82b1193eSBarry Smith } 1866*82b1193eSBarry Smith PetscFunctionReturn(0); 1867*82b1193eSBarry Smith } 1868*82b1193eSBarry Smith 1869*82b1193eSBarry Smith /* -------------------------------------------------------------------*/ 1870*82b1193eSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 1871*82b1193eSBarry Smith MatGetRow_SeqAIJ, 1872*82b1193eSBarry Smith MatRestoreRow_SeqAIJ, 1873*82b1193eSBarry Smith MatMult_SeqAIJ, 1874*82b1193eSBarry Smith MatMultAdd_SeqAIJ, 1875*82b1193eSBarry Smith MatMultTranspose_SeqAIJ, 1876*82b1193eSBarry Smith MatMultTransposeAdd_SeqAIJ, 1877*82b1193eSBarry Smith MatSolve_SeqAIJ, 1878*82b1193eSBarry Smith MatSolveAdd_SeqAIJ, 1879*82b1193eSBarry Smith MatSolveTranspose_SeqAIJ, 1880*82b1193eSBarry Smith MatSolveTransposeAdd_SeqAIJ, 1881*82b1193eSBarry Smith MatLUFactor_SeqAIJ, 1882*82b1193eSBarry Smith 0, 1883*82b1193eSBarry Smith MatRelax_SeqAIJ, 1884*82b1193eSBarry Smith MatTranspose_SeqAIJ, 1885*82b1193eSBarry Smith MatGetInfo_SeqAIJ, 1886*82b1193eSBarry Smith MatEqual_SeqAIJ, 1887*82b1193eSBarry Smith MatGetDiagonal_SeqAIJ, 1888*82b1193eSBarry Smith MatDiagonalScale_SeqAIJ, 1889*82b1193eSBarry Smith MatNorm_SeqAIJ, 1890*82b1193eSBarry Smith 0, 1891*82b1193eSBarry Smith MatAssemblyEnd_SeqAIJ, 1892*82b1193eSBarry Smith MatCompress_SeqAIJ, 1893*82b1193eSBarry Smith MatSetOption_SeqAIJ, 1894*82b1193eSBarry Smith MatZeroEntries_SeqAIJ, 1895*82b1193eSBarry Smith MatZeroRows_SeqAIJ, 1896*82b1193eSBarry Smith MatLUFactorSymbolic_SeqAIJ, 1897*82b1193eSBarry Smith MatLUFactorNumeric_SeqAIJ, 1898*82b1193eSBarry Smith 0, 1899*82b1193eSBarry Smith 0, 1900*82b1193eSBarry Smith MatGetSize_SeqAIJ, 1901*82b1193eSBarry Smith MatGetSize_SeqAIJ, 1902*82b1193eSBarry Smith MatGetOwnershipRange_SeqAIJ, 1903*82b1193eSBarry Smith MatILUFactorSymbolic_SeqAIJ, 1904*82b1193eSBarry Smith 0, 1905*82b1193eSBarry Smith 0, 1906*82b1193eSBarry Smith 0, 1907*82b1193eSBarry Smith MatDuplicate_SeqAIJ, 1908*82b1193eSBarry Smith 0, 1909*82b1193eSBarry Smith 0, 1910*82b1193eSBarry Smith MatILUFactor_SeqAIJ, 1911*82b1193eSBarry Smith 0, 1912*82b1193eSBarry Smith 0, 1913*82b1193eSBarry Smith MatGetSubMatrices_SeqAIJ, 1914*82b1193eSBarry Smith MatIncreaseOverlap_SeqAIJ, 1915*82b1193eSBarry Smith MatGetValues_SeqAIJ, 1916*82b1193eSBarry Smith MatCopy_SeqAIJ, 1917*82b1193eSBarry Smith MatPrintHelp_SeqAIJ, 1918*82b1193eSBarry Smith MatScale_SeqAIJ, 1919*82b1193eSBarry Smith 0, 1920*82b1193eSBarry Smith 0, 1921*82b1193eSBarry Smith MatILUDTFactor_SeqAIJ, 1922*82b1193eSBarry Smith MatGetBlockSize_SeqAIJ, 1923*82b1193eSBarry Smith MatGetRowIJ_SeqAIJ, 1924*82b1193eSBarry Smith MatRestoreRowIJ_SeqAIJ, 1925*82b1193eSBarry Smith MatGetColumnIJ_SeqAIJ, 1926*82b1193eSBarry Smith MatRestoreColumnIJ_SeqAIJ, 1927*82b1193eSBarry Smith MatFDColoringCreate_SeqAIJ, 1928*82b1193eSBarry Smith MatColoringPatch_SeqAIJ, 1929*82b1193eSBarry Smith 0, 1930*82b1193eSBarry Smith MatPermute_SeqAIJ, 1931*82b1193eSBarry Smith 0, 1932*82b1193eSBarry Smith 0, 1933*82b1193eSBarry Smith 0, 1934*82b1193eSBarry Smith 0, 1935*82b1193eSBarry Smith MatGetMaps_Petsc}; 1936*82b1193eSBarry Smith 1937*82b1193eSBarry Smith EXTERN int MatUseSuperLU_SeqAIJ(Mat); 1938*82b1193eSBarry Smith EXTERN int MatUseEssl_SeqAIJ(Mat); 1939*82b1193eSBarry Smith EXTERN int MatUseMatlab_SeqAIJ(Mat); 1940*82b1193eSBarry Smith EXTERN int MatUseDXML_SeqAIJ(Mat); 1941*82b1193eSBarry Smith 1942*82b1193eSBarry Smith EXTERN_C_BEGIN 1943*82b1193eSBarry Smith #undef __FUNC__ 1944*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSeqAIJSetColumnIndices_SeqAIJ"></a>*/"MatSeqAIJSetColumnIndices_SeqAIJ" 1945*82b1193eSBarry Smith 1946*82b1193eSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 1947*82b1193eSBarry Smith { 1948*82b1193eSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1949*82b1193eSBarry Smith int i,nz,n; 1950*82b1193eSBarry Smith 1951*82b1193eSBarry Smith PetscFunctionBegin; 1952*82b1193eSBarry Smith if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing"); 1953*82b1193eSBarry Smith 1954*82b1193eSBarry Smith nz = aij->maxnz; 1955*82b1193eSBarry Smith n = aij->n; 1956*82b1193eSBarry Smith for (i=0; i<nz; i++) { 1957*82b1193eSBarry Smith aij->j[i] = indices[i]; 1958*82b1193eSBarry Smith } 1959*82b1193eSBarry Smith aij->nz = nz; 1960*82b1193eSBarry Smith for (i=0; i<n; i++) { 1961*82b1193eSBarry Smith aij->ilen[i] = aij->imax[i]; 1962*82b1193eSBarry Smith } 1963*82b1193eSBarry Smith 1964*82b1193eSBarry Smith PetscFunctionReturn(0); 1965*82b1193eSBarry Smith } 1966*82b1193eSBarry Smith EXTERN_C_END 1967*82b1193eSBarry Smith 1968*82b1193eSBarry Smith #undef __FUNC__ 1969*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatSeqAIJSetColumnIndices"></a>*/"MatSeqAIJSetColumnIndices" 1970*82b1193eSBarry Smith /*@ 1971*82b1193eSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 1972*82b1193eSBarry Smith in the matrix. 1973*82b1193eSBarry Smith 1974*82b1193eSBarry Smith Input Parameters: 1975*82b1193eSBarry Smith + mat - the SeqAIJ matrix 1976*82b1193eSBarry Smith - indices - the column indices 1977*82b1193eSBarry Smith 1978*82b1193eSBarry Smith Level: advanced 1979*82b1193eSBarry Smith 1980*82b1193eSBarry Smith Notes: 1981*82b1193eSBarry Smith This can be called if you have precomputed the nonzero structure of the 1982*82b1193eSBarry Smith matrix and want to provide it to the matrix object to improve the performance 1983*82b1193eSBarry Smith of the MatSetValues() operation. 1984*82b1193eSBarry Smith 1985*82b1193eSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 1986*82b1193eSBarry Smith MatCreateSeqAIJ(). 1987*82b1193eSBarry Smith 1988*82b1193eSBarry Smith MUST be called before any calls to MatSetValues(); 1989*82b1193eSBarry Smith 1990*82b1193eSBarry Smith @*/ 1991*82b1193eSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 1992*82b1193eSBarry Smith { 1993*82b1193eSBarry Smith int ierr,(*f)(Mat,int *); 1994*82b1193eSBarry Smith 1995*82b1193eSBarry Smith PetscFunctionBegin; 1996*82b1193eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1997*82b1193eSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr); 1998*82b1193eSBarry Smith if (f) { 1999*82b1193eSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2000*82b1193eSBarry Smith } else { 2001*82b1193eSBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 2002*82b1193eSBarry Smith } 2003*82b1193eSBarry Smith PetscFunctionReturn(0); 2004*82b1193eSBarry Smith } 2005*82b1193eSBarry Smith 2006*82b1193eSBarry Smith /* ----------------------------------------------------------------------------------------*/ 2007*82b1193eSBarry Smith 2008*82b1193eSBarry Smith EXTERN_C_BEGIN 2009*82b1193eSBarry Smith #undef __FUNC__ 2010*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatStoreValues_SeqAIJ"></a>*/"MatStoreValues_SeqAIJ" 2011*82b1193eSBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2012*82b1193eSBarry Smith { 2013*82b1193eSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2014*82b1193eSBarry Smith int nz = aij->i[aij->m]+aij->indexshift,ierr; 2015*82b1193eSBarry Smith 2016*82b1193eSBarry Smith PetscFunctionBegin; 2017*82b1193eSBarry Smith if (aij->nonew != 1) { 2018*82b1193eSBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2019*82b1193eSBarry Smith } 2020*82b1193eSBarry Smith 2021*82b1193eSBarry Smith /* allocate space for values if not already there */ 2022*82b1193eSBarry Smith if (!aij->saved_values) { 2023*82b1193eSBarry Smith aij->saved_values = (Scalar*)PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values); 2024*82b1193eSBarry Smith } 2025*82b1193eSBarry Smith 2026*82b1193eSBarry Smith /* copy values over */ 2027*82b1193eSBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 2028*82b1193eSBarry Smith PetscFunctionReturn(0); 2029*82b1193eSBarry Smith } 2030*82b1193eSBarry Smith EXTERN_C_END 2031*82b1193eSBarry Smith 2032*82b1193eSBarry Smith #undef __FUNC__ 2033*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatStoreValues""></a>*/"MatStoreValues" 2034*82b1193eSBarry Smith /*@ 2035*82b1193eSBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2036*82b1193eSBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2037*82b1193eSBarry Smith nonlinear portion. 2038*82b1193eSBarry Smith 2039*82b1193eSBarry Smith Collect on Mat 2040*82b1193eSBarry Smith 2041*82b1193eSBarry Smith Input Parameters: 2042*82b1193eSBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2043*82b1193eSBarry Smith 2044*82b1193eSBarry Smith Level: advanced 2045*82b1193eSBarry Smith 2046*82b1193eSBarry Smith Common Usage, with SNESSolve(): 2047*82b1193eSBarry Smith $ Create Jacobian matrix 2048*82b1193eSBarry Smith $ Set linear terms into matrix 2049*82b1193eSBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2050*82b1193eSBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2051*82b1193eSBarry Smith $ boundary conditions again will not change the nonzero structure 2052*82b1193eSBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2053*82b1193eSBarry Smith $ ierr = MatStoreValues(mat); 2054*82b1193eSBarry Smith $ Call SNESSetJacobian() with matrix 2055*82b1193eSBarry Smith $ In your Jacobian routine 2056*82b1193eSBarry Smith $ ierr = MatRetrieveValues(mat); 2057*82b1193eSBarry Smith $ Set nonlinear terms in matrix 2058*82b1193eSBarry Smith 2059*82b1193eSBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2060*82b1193eSBarry Smith $ // build linear portion of Jacobian 2061*82b1193eSBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2062*82b1193eSBarry Smith $ ierr = MatStoreValues(mat); 2063*82b1193eSBarry Smith $ loop over nonlinear iterations 2064*82b1193eSBarry Smith $ ierr = MatRetrieveValues(mat); 2065*82b1193eSBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2066*82b1193eSBarry Smith $ // call MatAssemblyBegin/End() on matrix 2067*82b1193eSBarry Smith $ Solve linear system with Jacobian 2068*82b1193eSBarry Smith $ endloop 2069*82b1193eSBarry Smith 2070*82b1193eSBarry Smith Notes: 2071*82b1193eSBarry Smith Matrix must already be assemblied before calling this routine 2072*82b1193eSBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2073*82b1193eSBarry Smith calling this routine. 2074*82b1193eSBarry Smith 2075*82b1193eSBarry Smith .seealso: MatRetrieveValues() 2076*82b1193eSBarry Smith 2077*82b1193eSBarry Smith @*/ 2078*82b1193eSBarry Smith int MatStoreValues(Mat mat) 2079*82b1193eSBarry Smith { 2080*82b1193eSBarry Smith int ierr,(*f)(Mat); 2081*82b1193eSBarry Smith 2082*82b1193eSBarry Smith PetscFunctionBegin; 2083*82b1193eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2084*82b1193eSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2085*82b1193eSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2086*82b1193eSBarry Smith 2087*82b1193eSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr); 2088*82b1193eSBarry Smith if (f) { 2089*82b1193eSBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2090*82b1193eSBarry Smith } else { 2091*82b1193eSBarry Smith SETERRQ(1,1,"Wrong type of matrix to store values"); 2092*82b1193eSBarry Smith } 2093*82b1193eSBarry Smith PetscFunctionReturn(0); 2094*82b1193eSBarry Smith } 2095*82b1193eSBarry Smith 2096*82b1193eSBarry Smith EXTERN_C_BEGIN 2097*82b1193eSBarry Smith #undef __FUNC__ 2098*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRetrieveValues_SeqAIJ"></a>*/"MatRetrieveValues_SeqAIJ" 2099*82b1193eSBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2100*82b1193eSBarry Smith { 2101*82b1193eSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2102*82b1193eSBarry Smith int nz = aij->i[aij->m]+aij->indexshift,ierr; 2103*82b1193eSBarry Smith 2104*82b1193eSBarry Smith PetscFunctionBegin; 2105*82b1193eSBarry Smith if (aij->nonew != 1) { 2106*82b1193eSBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2107*82b1193eSBarry Smith } 2108*82b1193eSBarry Smith if (!aij->saved_values) { 2109*82b1193eSBarry Smith SETERRQ(1,1,"Must call MatStoreValues(A);first"); 2110*82b1193eSBarry Smith } 2111*82b1193eSBarry Smith 2112*82b1193eSBarry Smith /* copy values over */ 2113*82b1193eSBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 2114*82b1193eSBarry Smith PetscFunctionReturn(0); 2115*82b1193eSBarry Smith } 2116*82b1193eSBarry Smith EXTERN_C_END 2117*82b1193eSBarry Smith 2118*82b1193eSBarry Smith #undef __FUNC__ 2119*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatRetrieveValues"></a>*/"MatRetrieveValues" 2120*82b1193eSBarry Smith /*@ 2121*82b1193eSBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2122*82b1193eSBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2123*82b1193eSBarry Smith nonlinear portion. 2124*82b1193eSBarry Smith 2125*82b1193eSBarry Smith Collect on Mat 2126*82b1193eSBarry Smith 2127*82b1193eSBarry Smith Input Parameters: 2128*82b1193eSBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2129*82b1193eSBarry Smith 2130*82b1193eSBarry Smith Level: advanced 2131*82b1193eSBarry Smith 2132*82b1193eSBarry Smith .seealso: MatStoreValues() 2133*82b1193eSBarry Smith 2134*82b1193eSBarry Smith @*/ 2135*82b1193eSBarry Smith int MatRetrieveValues(Mat mat) 2136*82b1193eSBarry Smith { 2137*82b1193eSBarry Smith int ierr,(*f)(Mat); 2138*82b1193eSBarry Smith 2139*82b1193eSBarry Smith PetscFunctionBegin; 2140*82b1193eSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2141*82b1193eSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2142*82b1193eSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2143*82b1193eSBarry Smith 2144*82b1193eSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr); 2145*82b1193eSBarry Smith if (f) { 2146*82b1193eSBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2147*82b1193eSBarry Smith } else { 2148*82b1193eSBarry Smith SETERRQ(1,1,"Wrong type of matrix to retrieve values"); 2149*82b1193eSBarry Smith } 2150*82b1193eSBarry Smith PetscFunctionReturn(0); 2151*82b1193eSBarry Smith } 2152*82b1193eSBarry Smith 2153*82b1193eSBarry Smith /* 2154*82b1193eSBarry Smith This allows SeqAIJ matrices to be passed to the matlab engine 2155*82b1193eSBarry Smith */ 2156*82b1193eSBarry Smith #if defined(PETSC_HAVE_MATLAB) 2157*82b1193eSBarry Smith #include "engine.h" /* Matlab include file */ 2158*82b1193eSBarry Smith #include "mex.h" /* Matlab include file */ 2159*82b1193eSBarry Smith EXTERN_C_BEGIN 2160*82b1193eSBarry Smith #undef __FUNC__ 2161*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatMatlabEnginePut_SeqAIJ"></a>*/"MatMatlabEnginePut_SeqAIJ" 2162*82b1193eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *engine) 2163*82b1193eSBarry Smith { 2164*82b1193eSBarry Smith int ierr,i,*aj,*ai; 2165*82b1193eSBarry Smith Mat B = (Mat)obj; 2166*82b1193eSBarry Smith Scalar *array; 2167*82b1193eSBarry Smith mxArray *mat; 2168*82b1193eSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 2169*82b1193eSBarry Smith 2170*82b1193eSBarry Smith 2171*82b1193eSBarry Smith PetscFunctionBegin; 2172*82b1193eSBarry Smith mat = mxCreateSparse(B->n,B->m,aij->nz,mxREAL); 2173*82b1193eSBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(Scalar));CHKERRQ(ierr); 2174*82b1193eSBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 2175*82b1193eSBarry Smith ai = mxGetJc(mat); 2176*82b1193eSBarry Smith aj = mxGetIr(mat); 2177*82b1193eSBarry Smith ierr = PetscMemcpy(aj,aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 2178*82b1193eSBarry Smith ierr = PetscMemcpy(ai,aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr); 2179*82b1193eSBarry Smith 2180*82b1193eSBarry Smith /* Matlab indices start at 0 for sparse (what a surprise) */ 2181*82b1193eSBarry Smith if (aij->indexshift) { 2182*82b1193eSBarry Smith for (i=0; i<B->m+1; i++) { 2183*82b1193eSBarry Smith ai[i]--; 2184*82b1193eSBarry Smith } 2185*82b1193eSBarry Smith for (i=0; i<aij->nz; i++) { 2186*82b1193eSBarry Smith aj[i]--; 2187*82b1193eSBarry Smith } 2188*82b1193eSBarry Smith } 2189*82b1193eSBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 2190*82b1193eSBarry Smith mxSetName(mat,obj->name); 2191*82b1193eSBarry Smith engPutArray((Engine *)engine,mat); 2192*82b1193eSBarry Smith PetscFunctionReturn(0); 2193*82b1193eSBarry Smith } 2194*82b1193eSBarry Smith EXTERN_C_END 2195*82b1193eSBarry Smith #endif 2196*82b1193eSBarry Smith 2197*82b1193eSBarry Smith /* --------------------------------------------------------------------------------*/ 2198*82b1193eSBarry Smith 2199*82b1193eSBarry Smith #undef __FUNC__ 2200*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCreateSeqAIJ"></a>*/"MatCreateSeqAIJ" 2201*82b1193eSBarry Smith /*@C 2202*82b1193eSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 2203*82b1193eSBarry Smith (the default parallel PETSc format). For good matrix assembly performance 2204*82b1193eSBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2205*82b1193eSBarry Smith (or the array nnz). By setting these parameters accurately, performance 2206*82b1193eSBarry Smith during matrix assembly can be increased by more than a factor of 50. 2207*82b1193eSBarry Smith 2208*82b1193eSBarry Smith Collective on MPI_Comm 2209*82b1193eSBarry Smith 2210*82b1193eSBarry Smith Input Parameters: 2211*82b1193eSBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2212*82b1193eSBarry Smith . m - number of rows 2213*82b1193eSBarry Smith . n - number of columns 2214*82b1193eSBarry Smith . nz - number of nonzeros per row (same for all rows) 2215*82b1193eSBarry Smith - nnz - array containing the number of nonzeros in the various rows 2216*82b1193eSBarry Smith (possibly different for each row) or PETSC_NULL 2217*82b1193eSBarry Smith 2218*82b1193eSBarry Smith Output Parameter: 2219*82b1193eSBarry Smith . A - the matrix 2220*82b1193eSBarry Smith 2221*82b1193eSBarry Smith Notes: 2222*82b1193eSBarry Smith The AIJ format (also called the Yale sparse matrix format or 2223*82b1193eSBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2224*82b1193eSBarry Smith storage. That is, the stored row and column indices can begin at 2225*82b1193eSBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2226*82b1193eSBarry Smith 2227*82b1193eSBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2228*82b1193eSBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2229*82b1193eSBarry Smith allocation. For large problems you MUST preallocate memory or you 2230*82b1193eSBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2231*82b1193eSBarry Smith 2232*82b1193eSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2233*82b1193eSBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2234*82b1193eSBarry Smith search for consecutive rows with the same nonzero structure, thereby 2235*82b1193eSBarry Smith reusing matrix information to achieve increased efficiency. 2236*82b1193eSBarry Smith 2237*82b1193eSBarry Smith Options Database Keys: 2238*82b1193eSBarry Smith + -mat_aij_no_inode - Do not use inodes 2239*82b1193eSBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2240*82b1193eSBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2241*82b1193eSBarry Smith rather than 0. Note that when calling MatSetValues(), 2242*82b1193eSBarry Smith the user still MUST index entries starting at 0! 2243*82b1193eSBarry Smith 2244*82b1193eSBarry Smith Level: intermediate 2245*82b1193eSBarry Smith 2246*82b1193eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2247*82b1193eSBarry Smith 2248*82b1193eSBarry Smith @*/ 2249*82b1193eSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz,Mat *A) 2250*82b1193eSBarry Smith { 2251*82b1193eSBarry Smith Mat B; 2252*82b1193eSBarry Smith Mat_SeqAIJ *b; 2253*82b1193eSBarry Smith int i,len,ierr,size; 2254*82b1193eSBarry Smith PetscTruth flg; 2255*82b1193eSBarry Smith 2256*82b1193eSBarry Smith PetscFunctionBegin; 2257*82b1193eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2258*82b1193eSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1"); 2259*82b1193eSBarry Smith 2260*82b1193eSBarry Smith if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz); 2261*82b1193eSBarry Smith if (nnz) { 2262*82b1193eSBarry Smith for (i=0; i<m; i++) { 2263*82b1193eSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 2264*82b1193eSBarry Smith } 2265*82b1193eSBarry Smith } 2266*82b1193eSBarry Smith 2267*82b1193eSBarry Smith *A = 0; 2268*82b1193eSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView); 2269*82b1193eSBarry Smith PLogObjectCreate(B); 2270*82b1193eSBarry Smith B->data = (void*)(b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b); 2271*82b1193eSBarry Smith ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2272*82b1193eSBarry Smith ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2273*82b1193eSBarry Smith B->ops->destroy = MatDestroy_SeqAIJ; 2274*82b1193eSBarry Smith B->ops->view = MatView_SeqAIJ; 2275*82b1193eSBarry Smith B->factor = 0; 2276*82b1193eSBarry Smith B->lupivotthreshold = 1.0; 2277*82b1193eSBarry Smith B->mapping = 0; 2278*82b1193eSBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2279*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2280*82b1193eSBarry Smith b->row = 0; 2281*82b1193eSBarry Smith b->col = 0; 2282*82b1193eSBarry Smith b->icol = 0; 2283*82b1193eSBarry Smith b->indexshift = 0; 2284*82b1193eSBarry Smith b->reallocs = 0; 2285*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex",&flg);CHKERRQ(ierr); 2286*82b1193eSBarry Smith if (flg) b->indexshift = -1; 2287*82b1193eSBarry Smith 2288*82b1193eSBarry Smith b->m = m; B->m = m; B->M = m; 2289*82b1193eSBarry Smith b->n = n; B->n = n; B->N = n; 2290*82b1193eSBarry Smith 2291*82b1193eSBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 2292*82b1193eSBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 2293*82b1193eSBarry Smith 2294*82b1193eSBarry Smith b->imax = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(b->imax); 2295*82b1193eSBarry Smith if (!nnz) { 2296*82b1193eSBarry Smith if (nz == PETSC_DEFAULT) nz = 10; 2297*82b1193eSBarry Smith else if (nz <= 0) nz = 1; 2298*82b1193eSBarry Smith for (i=0; i<m; i++) b->imax[i] = nz; 2299*82b1193eSBarry Smith nz = nz*m; 2300*82b1193eSBarry Smith } else { 2301*82b1193eSBarry Smith nz = 0; 2302*82b1193eSBarry Smith for (i=0; i<m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2303*82b1193eSBarry Smith } 2304*82b1193eSBarry Smith 2305*82b1193eSBarry Smith /* allocate the matrix space */ 2306*82b1193eSBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 2307*82b1193eSBarry Smith b->a = (Scalar*)PetscMalloc(len);CHKPTRQ(b->a); 2308*82b1193eSBarry Smith b->j = (int*)(b->a + nz); 2309*82b1193eSBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2310*82b1193eSBarry Smith b->i = b->j + nz; 2311*82b1193eSBarry Smith b->singlemalloc = PETSC_TRUE; 2312*82b1193eSBarry Smith b->freedata = PETSC_TRUE; 2313*82b1193eSBarry Smith 2314*82b1193eSBarry Smith b->i[0] = -b->indexshift; 2315*82b1193eSBarry Smith for (i=1; i<m+1; i++) { 2316*82b1193eSBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 2317*82b1193eSBarry Smith } 2318*82b1193eSBarry Smith 2319*82b1193eSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2320*82b1193eSBarry Smith b->ilen = (int*)PetscMalloc((m+1)*sizeof(int)); 2321*82b1193eSBarry Smith PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2322*82b1193eSBarry Smith for (i=0; i<b->m; i++) { b->ilen[i] = 0;} 2323*82b1193eSBarry Smith 2324*82b1193eSBarry Smith b->nz = 0; 2325*82b1193eSBarry Smith b->maxnz = nz; 2326*82b1193eSBarry Smith b->sorted = PETSC_FALSE; 2327*82b1193eSBarry Smith b->ignorezeroentries = PETSC_FALSE; 2328*82b1193eSBarry Smith b->roworiented = PETSC_TRUE; 2329*82b1193eSBarry Smith b->nonew = 0; 2330*82b1193eSBarry Smith b->diag = 0; 2331*82b1193eSBarry Smith b->solve_work = 0; 2332*82b1193eSBarry Smith b->spptr = 0; 2333*82b1193eSBarry Smith b->inode.use = PETSC_TRUE; 2334*82b1193eSBarry Smith b->inode.node_count = 0; 2335*82b1193eSBarry Smith b->inode.size = 0; 2336*82b1193eSBarry Smith b->inode.limit = 5; 2337*82b1193eSBarry Smith b->inode.max_limit = 5; 2338*82b1193eSBarry Smith b->saved_values = 0; 2339*82b1193eSBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2340*82b1193eSBarry Smith b->idiag = 0; 2341*82b1193eSBarry Smith b->ssor = 0; 2342*82b1193eSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2343*82b1193eSBarry Smith 2344*82b1193eSBarry Smith *A = B; 2345*82b1193eSBarry Smith 2346*82b1193eSBarry Smith /* SuperLU is not currently supported through PETSc */ 2347*82b1193eSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 2348*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu",&flg);CHKERRQ(ierr); 2349*82b1193eSBarry Smith if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 2350*82b1193eSBarry Smith #endif 2351*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl",&flg);CHKERRQ(ierr); 2352*82b1193eSBarry Smith if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 2353*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_matlab",&flg);CHKERRQ(ierr); 2354*82b1193eSBarry Smith if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);} 2355*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml",&flg);CHKERRQ(ierr); 2356*82b1193eSBarry Smith if (flg) { 2357*82b1193eSBarry Smith if (!b->indexshift) SETERRQ(PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml"); 2358*82b1193eSBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 2359*82b1193eSBarry Smith } 2360*82b1193eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-help",&flg);CHKERRQ(ierr); 2361*82b1193eSBarry Smith if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); } 2362*82b1193eSBarry Smith 2363*82b1193eSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2364*82b1193eSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2365*82b1193eSBarry Smith MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2366*82b1193eSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2367*82b1193eSBarry Smith "MatStoreValues_SeqAIJ", 2368*82b1193eSBarry Smith MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2369*82b1193eSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2370*82b1193eSBarry Smith "MatRetrieveValues_SeqAIJ", 2371*82b1193eSBarry Smith MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2372*82b1193eSBarry Smith #if defined(PETSC_HAVE_MATLAB) 2373*82b1193eSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 2374*82b1193eSBarry Smith #endif 2375*82b1193eSBarry Smith PetscFunctionReturn(0); 2376*82b1193eSBarry Smith } 2377*82b1193eSBarry Smith 2378*82b1193eSBarry Smith #undef __FUNC__ 2379*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatDuplicate_SeqAIJ"></a>*/"MatDuplicate_SeqAIJ" 2380*82b1193eSBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 2381*82b1193eSBarry Smith { 2382*82b1193eSBarry Smith Mat C; 2383*82b1193eSBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2384*82b1193eSBarry Smith int i,len,m = a->m,shift = a->indexshift,ierr; 2385*82b1193eSBarry Smith 2386*82b1193eSBarry Smith PetscFunctionBegin; 2387*82b1193eSBarry Smith *B = 0; 2388*82b1193eSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView); 2389*82b1193eSBarry Smith PLogObjectCreate(C); 2390*82b1193eSBarry Smith C->data = (void*)(c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c); 2391*82b1193eSBarry Smith ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2392*82b1193eSBarry Smith C->ops->destroy = MatDestroy_SeqAIJ; 2393*82b1193eSBarry Smith C->ops->view = MatView_SeqAIJ; 2394*82b1193eSBarry Smith C->factor = A->factor; 2395*82b1193eSBarry Smith c->row = 0; 2396*82b1193eSBarry Smith c->col = 0; 2397*82b1193eSBarry Smith c->icol = 0; 2398*82b1193eSBarry Smith c->indexshift = shift; 2399*82b1193eSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2400*82b1193eSBarry Smith C->assembled = PETSC_TRUE; 2401*82b1193eSBarry Smith 2402*82b1193eSBarry Smith c->m = C->m = a->m; 2403*82b1193eSBarry Smith c->n = C->n = a->n; 2404*82b1193eSBarry Smith C->M = a->m; 2405*82b1193eSBarry Smith C->N = a->n; 2406*82b1193eSBarry Smith 2407*82b1193eSBarry Smith c->imax = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax); 2408*82b1193eSBarry Smith c->ilen = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen); 2409*82b1193eSBarry Smith for (i=0; i<m; i++) { 2410*82b1193eSBarry Smith c->imax[i] = a->imax[i]; 2411*82b1193eSBarry Smith c->ilen[i] = a->ilen[i]; 2412*82b1193eSBarry Smith } 2413*82b1193eSBarry Smith 2414*82b1193eSBarry Smith /* allocate the matrix space */ 2415*82b1193eSBarry Smith c->singlemalloc = PETSC_TRUE; 2416*82b1193eSBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 2417*82b1193eSBarry Smith c->a = (Scalar*)PetscMalloc(len);CHKPTRQ(c->a); 2418*82b1193eSBarry Smith c->j = (int*)(c->a + a->i[m] + shift); 2419*82b1193eSBarry Smith c->i = c->j + a->i[m] + shift; 2420*82b1193eSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 2421*82b1193eSBarry Smith if (m > 0) { 2422*82b1193eSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr); 2423*82b1193eSBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2424*82b1193eSBarry Smith ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 2425*82b1193eSBarry Smith } else { 2426*82b1193eSBarry Smith ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 2427*82b1193eSBarry Smith } 2428*82b1193eSBarry Smith } 2429*82b1193eSBarry Smith 2430*82b1193eSBarry Smith PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2431*82b1193eSBarry Smith c->sorted = a->sorted; 2432*82b1193eSBarry Smith c->roworiented = a->roworiented; 2433*82b1193eSBarry Smith c->nonew = a->nonew; 2434*82b1193eSBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2435*82b1193eSBarry Smith c->saved_values = 0; 2436*82b1193eSBarry Smith c->idiag = 0; 2437*82b1193eSBarry Smith c->ssor = 0; 2438*82b1193eSBarry Smith c->ignorezeroentries = a->ignorezeroentries; 2439*82b1193eSBarry Smith c->freedata = PETSC_TRUE; 2440*82b1193eSBarry Smith 2441*82b1193eSBarry Smith if (a->diag) { 2442*82b1193eSBarry Smith c->diag = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->diag); 2443*82b1193eSBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 2444*82b1193eSBarry Smith for (i=0; i<m; i++) { 2445*82b1193eSBarry Smith c->diag[i] = a->diag[i]; 2446*82b1193eSBarry Smith } 2447*82b1193eSBarry Smith } else c->diag = 0; 2448*82b1193eSBarry Smith c->inode.use = a->inode.use; 2449*82b1193eSBarry Smith c->inode.limit = a->inode.limit; 2450*82b1193eSBarry Smith c->inode.max_limit = a->inode.max_limit; 2451*82b1193eSBarry Smith if (a->inode.size){ 2452*82b1193eSBarry Smith c->inode.size = (int*)PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->inode.size); 2453*82b1193eSBarry Smith c->inode.node_count = a->inode.node_count; 2454*82b1193eSBarry Smith ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2455*82b1193eSBarry Smith } else { 2456*82b1193eSBarry Smith c->inode.size = 0; 2457*82b1193eSBarry Smith c->inode.node_count = 0; 2458*82b1193eSBarry Smith } 2459*82b1193eSBarry Smith c->nz = a->nz; 2460*82b1193eSBarry Smith c->maxnz = a->maxnz; 2461*82b1193eSBarry Smith c->solve_work = 0; 2462*82b1193eSBarry Smith c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2463*82b1193eSBarry Smith 2464*82b1193eSBarry Smith *B = C; 2465*82b1193eSBarry Smith ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 2466*82b1193eSBarry Smith PetscFunctionReturn(0); 2467*82b1193eSBarry Smith } 2468*82b1193eSBarry Smith 2469*82b1193eSBarry Smith #undef __FUNC__ 2470*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatLoad_SeqAIJ"></a>*/"MatLoad_SeqAIJ" 2471*82b1193eSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 2472*82b1193eSBarry Smith { 2473*82b1193eSBarry Smith Mat_SeqAIJ *a; 2474*82b1193eSBarry Smith Mat B; 2475*82b1193eSBarry Smith int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N,shift; 2476*82b1193eSBarry Smith MPI_Comm comm; 2477*82b1193eSBarry Smith 2478*82b1193eSBarry Smith PetscFunctionBegin; 2479*82b1193eSBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2480*82b1193eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2481*82b1193eSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor"); 2482*82b1193eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 2483*82b1193eSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2484*82b1193eSBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file"); 2485*82b1193eSBarry Smith M = header[1]; N = header[2]; nz = header[3]; 2486*82b1193eSBarry Smith 2487*82b1193eSBarry Smith if (nz < 0) { 2488*82b1193eSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2489*82b1193eSBarry Smith } 2490*82b1193eSBarry Smith 2491*82b1193eSBarry Smith /* read in row lengths */ 2492*82b1193eSBarry Smith rowlengths = (int*)PetscMalloc(M*sizeof(int));CHKPTRQ(rowlengths); 2493*82b1193eSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 2494*82b1193eSBarry Smith 2495*82b1193eSBarry Smith /* create our matrix */ 2496*82b1193eSBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr); 2497*82b1193eSBarry Smith B = *A; 2498*82b1193eSBarry Smith a = (Mat_SeqAIJ*)B->data; 2499*82b1193eSBarry Smith shift = a->indexshift; 2500*82b1193eSBarry Smith 2501*82b1193eSBarry Smith /* read in column indices and adjust for Fortran indexing*/ 2502*82b1193eSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 2503*82b1193eSBarry Smith if (shift) { 2504*82b1193eSBarry Smith for (i=0; i<nz; i++) { 2505*82b1193eSBarry Smith a->j[i] += 1; 2506*82b1193eSBarry Smith } 2507*82b1193eSBarry Smith } 2508*82b1193eSBarry Smith 2509*82b1193eSBarry Smith /* read in nonzero values */ 2510*82b1193eSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 2511*82b1193eSBarry Smith 2512*82b1193eSBarry Smith /* set matrix "i" values */ 2513*82b1193eSBarry Smith a->i[0] = -shift; 2514*82b1193eSBarry Smith for (i=1; i<= M; i++) { 2515*82b1193eSBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2516*82b1193eSBarry Smith a->ilen[i-1] = rowlengths[i-1]; 2517*82b1193eSBarry Smith } 2518*82b1193eSBarry Smith ierr = PetscFree(rowlengths);CHKERRQ(ierr); 2519*82b1193eSBarry Smith 2520*82b1193eSBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2521*82b1193eSBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2522*82b1193eSBarry Smith PetscFunctionReturn(0); 2523*82b1193eSBarry Smith } 2524*82b1193eSBarry Smith 2525*82b1193eSBarry Smith #undef __FUNC__ 2526*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatEqual_SeqAIJ""></a>*/"MatEqual_SeqAIJ" 2527*82b1193eSBarry Smith int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 2528*82b1193eSBarry Smith { 2529*82b1193eSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 2530*82b1193eSBarry Smith int ierr; 2531*82b1193eSBarry Smith 2532*82b1193eSBarry Smith PetscFunctionBegin; 2533*82b1193eSBarry Smith if (B->type != MATSEQAIJ) SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 2534*82b1193eSBarry Smith 2535*82b1193eSBarry Smith /* If the matrix dimensions are not equal,or no of nonzeros or shift */ 2536*82b1193eSBarry Smith if ((a->m != b->m) || (a->n !=b->n) ||(a->nz != b->nz)|| (a->indexshift != b->indexshift)) { 2537*82b1193eSBarry Smith *flg = PETSC_FALSE; 2538*82b1193eSBarry Smith PetscFunctionReturn(0); 2539*82b1193eSBarry Smith } 2540*82b1193eSBarry Smith 2541*82b1193eSBarry Smith /* if the a->i are the same */ 2542*82b1193eSBarry Smith ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr); 2543*82b1193eSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2544*82b1193eSBarry Smith 2545*82b1193eSBarry Smith /* if a->j are the same */ 2546*82b1193eSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 2547*82b1193eSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2548*82b1193eSBarry Smith 2549*82b1193eSBarry Smith /* if a->a are the same */ 2550*82b1193eSBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr); 2551*82b1193eSBarry Smith 2552*82b1193eSBarry Smith PetscFunctionReturn(0); 2553*82b1193eSBarry Smith 2554*82b1193eSBarry Smith } 2555*82b1193eSBarry Smith 2556*82b1193eSBarry Smith #undef __FUNC__ 2557*82b1193eSBarry Smith #define __FUNC__ /*<a name="MatCreateSeqAIJWithArrays"></a>*/"MatCreateSeqAIJWithArrays" 2558*82b1193eSBarry Smith /*@C 2559*82b1193eSBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 2560*82b1193eSBarry Smith provided by the user. 2561*82b1193eSBarry Smith 2562*82b1193eSBarry Smith Coolective on MPI_Comm 2563*82b1193eSBarry Smith 2564*82b1193eSBarry Smith Input Parameters: 2565*82b1193eSBarry Smith + comm - must be an MPI communicator of size 1 2566*82b1193eSBarry Smith . m - number of rows 2567*82b1193eSBarry Smith . n - number of columns 2568*82b1193eSBarry Smith . i - row indices 2569*82b1193eSBarry Smith . j - column indices 2570*82b1193eSBarry Smith - a - matrix values 2571*82b1193eSBarry Smith 2572*82b1193eSBarry Smith Output Parameter: 2573*82b1193eSBarry Smith . mat - the matrix 2574*82b1193eSBarry Smith 2575*82b1193eSBarry Smith Level: intermediate 2576*82b1193eSBarry Smith 2577*82b1193eSBarry Smith Notes: 2578*82b1193eSBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 2579*82b1193eSBarry Smith once the matrix is destroyed 2580*82b1193eSBarry Smith 2581*82b1193eSBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 2582*82b1193eSBarry Smith 2583*82b1193eSBarry Smith The i and j indices can be either 0- or 1 based 2584*82b1193eSBarry Smith 2585*82b1193eSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 2586*82b1193eSBarry Smith 2587*82b1193eSBarry Smith @*/ 2588*82b1193eSBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,Scalar *a,Mat *mat) 2589*82b1193eSBarry Smith { 2590*82b1193eSBarry Smith int ierr,ii; 2591*82b1193eSBarry Smith Mat_SeqAIJ *aij; 2592*82b1193eSBarry Smith 2593*82b1193eSBarry Smith PetscFunctionBegin; 2594*82b1193eSBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,0,0,mat);CHKERRQ(ierr); 2595*82b1193eSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 2596*82b1193eSBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 2597*82b1193eSBarry Smith 2598*82b1193eSBarry Smith if (i[0] == 1) { 2599*82b1193eSBarry Smith aij->indexshift = -1; 2600*82b1193eSBarry Smith } else if (i[0]) { 2601*82b1193eSBarry Smith SETERRQ(1,1,"i (row indices) do not start with 0 or 1"); 2602*82b1193eSBarry Smith } 2603*82b1193eSBarry Smith aij->i = i; 2604*82b1193eSBarry Smith aij->j = j; 2605*82b1193eSBarry Smith aij->a = a; 2606*82b1193eSBarry Smith aij->singlemalloc = PETSC_FALSE; 2607*82b1193eSBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 2608*82b1193eSBarry Smith aij->freedata = PETSC_FALSE; 2609*82b1193eSBarry Smith 2610*82b1193eSBarry Smith for (ii=0; ii<m; ii++) { 2611*82b1193eSBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 2612*82b1193eSBarry Smith #if defined(PETSC_BOPT_g) 2613*82b1193eSBarry Smith if (i[ii+1] - i[i] < 0) SETERRQ2(1,1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 2614*82b1193eSBarry Smith #endif 2615*82b1193eSBarry Smith } 2616*82b1193eSBarry Smith #if defined(PETSC_BOPT_g) 2617*82b1193eSBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 2618*82b1193eSBarry Smith if (j[ii] < -aij->indexshift) SETERRQ2(1,1,"Negative column index at location = %d index = %d",ii,j[ii]); 2619*82b1193eSBarry Smith if (j[ii] > n - 1 -aij->indexshift) SETERRQ2(1,1,"Column index to large at location = %d index = %d",ii,j[ii]); 2620*82b1193eSBarry Smith } 2621*82b1193eSBarry Smith #endif 2622*82b1193eSBarry Smith 2623*82b1193eSBarry Smith /* changes indices to start at 0 */ 2624*82b1193eSBarry Smith if (i[0]) { 2625*82b1193eSBarry Smith aij->indexshift = 0; 2626*82b1193eSBarry Smith for (ii=0; ii<m; ii++) { 2627*82b1193eSBarry Smith i[ii]--; 2628*82b1193eSBarry Smith } 2629*82b1193eSBarry Smith for (ii=0; ii<i[m]; ii++) { 2630*82b1193eSBarry Smith j[ii]--; 2631*82b1193eSBarry Smith } 2632*82b1193eSBarry Smith } 2633*82b1193eSBarry Smith 2634*82b1193eSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2635*82b1193eSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2636*82b1193eSBarry Smith PetscFunctionReturn(0); 2637*82b1193eSBarry Smith } 2638*82b1193eSBarry Smith 2639*82b1193eSBarry Smith 2640*82b1193eSBarry Smith 2641