1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*77ed5343SBarry Smith static char vcid[] = "$Id: aij.c,v 1.288 1998/11/30 23:23:27 bsmith Exp bsmith $"; 317ab2063SBarry Smith #endif 417ab2063SBarry Smith 5d5d45c9bSBarry Smith /* 63369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 7d5d45c9bSBarry Smith matrix storage format. 8d5d45c9bSBarry Smith */ 93369ce9aSBarry Smith 103369ce9aSBarry Smith #include "sys.h" 1170f55243SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 12f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 13f5eb4b81SSatish Balay #include "src/inline/spops.h" 148d195f9aSBarry Smith #include "src/inline/dot.h" 15eeb667a2SSatish Balay #include "bitarray.h" 1617ab2063SBarry Smith 17a2ce50c7SBarry Smith /* 18a2ce50c7SBarry Smith Basic AIJ format ILU based on drop tolerance 19a2ce50c7SBarry Smith */ 205615d1e5SSatish Balay #undef __FUNC__ 215615d1e5SSatish Balay #define __FUNC__ "MatILUDTFactor_SeqAIJ" 22a2ce50c7SBarry Smith int MatILUDTFactor_SeqAIJ(Mat A,double dt,int maxnz,IS row,IS col,Mat *fact) 23a2ce50c7SBarry Smith { 24a2ce50c7SBarry Smith /* Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; */ 25a2ce50c7SBarry Smith int ierr = 1; 26a2ce50c7SBarry Smith 273a40ed3dSBarry Smith PetscFunctionBegin; 28e3372554SBarry Smith SETERRQ(ierr,0,"Not implemented"); 29d64ed03dSBarry Smith #if !defined(USE_PETSC_DEBUG) 30d64ed03dSBarry Smith PetscFunctionReturn(0); 31d64ed03dSBarry Smith #endif 32a2ce50c7SBarry Smith } 33a2ce50c7SBarry Smith 34bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 3517ab2063SBarry Smith 365615d1e5SSatish Balay #undef __FUNC__ 375615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqAIJ" 388f6be9afSLois Curfman McInnes int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja, 396945ee14SBarry Smith PetscTruth *done) 4017ab2063SBarry Smith { 41416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 426945ee14SBarry Smith int ierr,i,ishift; 4317ab2063SBarry Smith 443a40ed3dSBarry Smith PetscFunctionBegin; 4531625ec5SSatish Balay *m = A->m; 463a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 476945ee14SBarry Smith ishift = a->indexshift; 486945ee14SBarry Smith if (symmetric) { 4931625ec5SSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr); 506945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 5131625ec5SSatish Balay int nz = a->i[a->m]; 523b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 5331625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia); 543b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 553b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1; 5631625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1; 576945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 5831625ec5SSatish Balay int nz = a->i[a->m] + 1; 593b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 6031625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) ); CHKPTRQ(*ia); 613b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(*ja); 623b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1; 6331625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1; 646945ee14SBarry Smith } else { 656945ee14SBarry Smith *ia = a->i; *ja = a->j; 66a2ce50c7SBarry Smith } 67a2ce50c7SBarry Smith 683a40ed3dSBarry Smith PetscFunctionReturn(0); 69a2744918SBarry Smith } 70a2744918SBarry Smith 715615d1e5SSatish Balay #undef __FUNC__ 725615d1e5SSatish Balay #define __FUNC__ "MatRestoreRowIJ_SeqAIJ" 738f6be9afSLois Curfman McInnes int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 746945ee14SBarry Smith PetscTruth *done) 756945ee14SBarry Smith { 766945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 773b2fbd54SBarry Smith int ishift = a->indexshift; 786945ee14SBarry Smith 793a40ed3dSBarry Smith PetscFunctionBegin; 803a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 813b2fbd54SBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 826945ee14SBarry Smith PetscFree(*ia); 836945ee14SBarry Smith PetscFree(*ja); 84bcd2baecSBarry Smith } 853a40ed3dSBarry Smith PetscFunctionReturn(0); 8617ab2063SBarry Smith } 8717ab2063SBarry Smith 885615d1e5SSatish Balay #undef __FUNC__ 895615d1e5SSatish Balay #define __FUNC__ "MatGetColumnIJ_SeqAIJ" 9043a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 913b2fbd54SBarry Smith PetscTruth *done) 923b2fbd54SBarry Smith { 933b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 94a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 95a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 963b2fbd54SBarry Smith 973a40ed3dSBarry Smith PetscFunctionBegin; 983b2fbd54SBarry Smith *nn = A->n; 993a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1003b2fbd54SBarry Smith if (symmetric) { 101179192dfSSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja); CHKERRQ(ierr); 1023b2fbd54SBarry Smith } else { 10361d2ded1SBarry Smith collengths = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(collengths); 1043b2fbd54SBarry Smith PetscMemzero(collengths,n*sizeof(int)); 1053b2fbd54SBarry Smith cia = (int *) PetscMalloc( (n+1)*sizeof(int) ); CHKPTRQ(cia); 106a93ec695SBarry Smith cja = (int *) PetscMalloc( (nz+1)*sizeof(int) ); CHKPTRQ(cja); 1073b2fbd54SBarry Smith jj = a->j; 1083b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) { 1093b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 1103b2fbd54SBarry Smith } 1113b2fbd54SBarry Smith cia[0] = oshift; 1123b2fbd54SBarry Smith for ( i=0; i<n; i++) { 1133b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1143b2fbd54SBarry Smith } 1153b2fbd54SBarry Smith PetscMemzero(collengths,n*sizeof(int)); 1163b2fbd54SBarry Smith jj = a->j; 117a93ec695SBarry Smith for ( row=0; row<m; row++ ) { 118a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 119a93ec695SBarry Smith for ( i=0; i<mr; i++ ) { 1203b2fbd54SBarry Smith col = *jj++ + ishift; 1213b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1223b2fbd54SBarry Smith } 1233b2fbd54SBarry Smith } 1243b2fbd54SBarry Smith PetscFree(collengths); 1253b2fbd54SBarry Smith *ia = cia; *ja = cja; 1263b2fbd54SBarry Smith } 1273b2fbd54SBarry Smith 1283a40ed3dSBarry Smith PetscFunctionReturn(0); 1293b2fbd54SBarry Smith } 1303b2fbd54SBarry Smith 1315615d1e5SSatish Balay #undef __FUNC__ 1325615d1e5SSatish Balay #define __FUNC__ "MatRestoreColumnIJ_SeqAIJ" 13343a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia, 1343b2fbd54SBarry Smith int **ja,PetscTruth *done) 1353b2fbd54SBarry Smith { 1363a40ed3dSBarry Smith PetscFunctionBegin; 1373a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1383b2fbd54SBarry Smith 1393b2fbd54SBarry Smith PetscFree(*ia); 1403b2fbd54SBarry Smith PetscFree(*ja); 1413b2fbd54SBarry Smith 1423a40ed3dSBarry Smith PetscFunctionReturn(0); 1433b2fbd54SBarry Smith } 1443b2fbd54SBarry Smith 145227d817aSBarry Smith #define CHUNKSIZE 15 14617ab2063SBarry Smith 1475615d1e5SSatish Balay #undef __FUNC__ 1485615d1e5SSatish Balay #define __FUNC__ "MatSetValues_SeqAIJ" 14961d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 15017ab2063SBarry Smith { 151416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 152416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted; 1534b0e389bSBarry Smith int *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented; 154d5d45c9bSBarry Smith int *aj = a->j, nonew = a->nonew,shift = a->indexshift; 155416022c9SBarry Smith Scalar *ap,value, *aa = a->a; 15617ab2063SBarry Smith 1573a40ed3dSBarry Smith PetscFunctionBegin; 15817ab2063SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 159416022c9SBarry Smith row = im[k]; 1603a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 161a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 162a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 1633b2fbd54SBarry Smith #endif 16417ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 16517ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 166416022c9SBarry Smith low = 0; 16717ab2063SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 1683a40ed3dSBarry Smith #if defined(USE_PETSC_BOPT_g) 169a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 170a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 1713b2fbd54SBarry Smith #endif 1724b0e389bSBarry Smith col = in[l] - shift; 1734b0e389bSBarry Smith if (roworiented) { 1744b0e389bSBarry Smith value = *v++; 175bef8e0ddSBarry Smith } else { 1764b0e389bSBarry Smith value = v[k + l*m]; 1774b0e389bSBarry Smith } 178416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 179416022c9SBarry Smith while (high-low > 5) { 180416022c9SBarry Smith t = (low+high)/2; 181416022c9SBarry Smith if (rp[t] > col) high = t; 182416022c9SBarry Smith else low = t; 18317ab2063SBarry Smith } 184416022c9SBarry Smith for ( i=low; i<high; i++ ) { 18517ab2063SBarry Smith if (rp[i] > col) break; 18617ab2063SBarry Smith if (rp[i] == col) { 187416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 18817ab2063SBarry Smith else ap[i] = value; 18917ab2063SBarry Smith goto noinsert; 19017ab2063SBarry Smith } 19117ab2063SBarry Smith } 192c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 193a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 19417ab2063SBarry Smith if (nrow >= rmax) { 19517ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 196416022c9SBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 19717ab2063SBarry Smith Scalar *new_a; 19817ab2063SBarry Smith 199a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 20096854ed6SLois Curfman McInnes 20117ab2063SBarry Smith /* malloc new storage space */ 202416022c9SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 2030452661fSBarry Smith new_a = (Scalar *) PetscMalloc( len ); CHKPTRQ(new_a); 20417ab2063SBarry Smith new_j = (int *) (new_a + new_nz); 20517ab2063SBarry Smith new_i = new_j + new_nz; 20617ab2063SBarry Smith 20717ab2063SBarry Smith /* copy over old data into new slots */ 20817ab2063SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 209416022c9SBarry Smith for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 210416022c9SBarry Smith PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int)); 211416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 212416022c9SBarry Smith PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow, 21317ab2063SBarry Smith len*sizeof(int)); 214416022c9SBarry Smith PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar)); 215416022c9SBarry Smith PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow, 21617ab2063SBarry Smith len*sizeof(Scalar)); 21717ab2063SBarry Smith /* free up old matrix storage */ 2180452661fSBarry Smith PetscFree(a->a); 2190452661fSBarry Smith if (!a->singlemalloc) {PetscFree(a->i);PetscFree(a->j);} 220416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 221416022c9SBarry Smith a->singlemalloc = 1; 22217ab2063SBarry Smith 22317ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 224416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 225416022c9SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 226416022c9SBarry Smith a->maxnz += CHUNKSIZE; 227b810aeb4SBarry Smith a->reallocs++; 22817ab2063SBarry Smith } 229416022c9SBarry Smith N = nrow++ - 1; a->nz++; 230416022c9SBarry Smith /* shift up all the later entries in this row */ 231416022c9SBarry Smith for ( ii=N; ii>=i; ii-- ) { 23217ab2063SBarry Smith rp[ii+1] = rp[ii]; 23317ab2063SBarry Smith ap[ii+1] = ap[ii]; 23417ab2063SBarry Smith } 23517ab2063SBarry Smith rp[i] = col; 23617ab2063SBarry Smith ap[i] = value; 23717ab2063SBarry Smith noinsert:; 238416022c9SBarry Smith low = i + 1; 23917ab2063SBarry Smith } 24017ab2063SBarry Smith ailen[row] = nrow; 24117ab2063SBarry Smith } 2423a40ed3dSBarry Smith PetscFunctionReturn(0); 24317ab2063SBarry Smith } 24417ab2063SBarry Smith 2455615d1e5SSatish Balay #undef __FUNC__ 2465615d1e5SSatish Balay #define __FUNC__ "MatGetValues_SeqAIJ" 2478f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 2487eb43aa7SLois Curfman McInnes { 2497eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 250b49de8d1SLois Curfman McInnes int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 2517eb43aa7SLois Curfman McInnes int *ai = a->i, *ailen = a->ilen, shift = a->indexshift; 2527eb43aa7SLois Curfman McInnes Scalar *ap, *aa = a->a, zero = 0.0; 2537eb43aa7SLois Curfman McInnes 2543a40ed3dSBarry Smith PetscFunctionBegin; 2557eb43aa7SLois Curfman McInnes for ( k=0; k<m; k++ ) { /* loop over rows */ 2567eb43aa7SLois Curfman McInnes row = im[k]; 257a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 258a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 2597eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2607eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2617eb43aa7SLois Curfman McInnes for ( l=0; l<n; l++ ) { /* loop over columns */ 262a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 263a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 2647eb43aa7SLois Curfman McInnes col = in[l] - shift; 2657eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2667eb43aa7SLois Curfman McInnes while (high-low > 5) { 2677eb43aa7SLois Curfman McInnes t = (low+high)/2; 2687eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2697eb43aa7SLois Curfman McInnes else low = t; 2707eb43aa7SLois Curfman McInnes } 2717eb43aa7SLois Curfman McInnes for ( i=low; i<high; i++ ) { 2727eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2737eb43aa7SLois Curfman McInnes if (rp[i] == col) { 274b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2757eb43aa7SLois Curfman McInnes goto finished; 2767eb43aa7SLois Curfman McInnes } 2777eb43aa7SLois Curfman McInnes } 278b49de8d1SLois Curfman McInnes *v++ = zero; 2797eb43aa7SLois Curfman McInnes finished:; 2807eb43aa7SLois Curfman McInnes } 2817eb43aa7SLois Curfman McInnes } 2823a40ed3dSBarry Smith PetscFunctionReturn(0); 2837eb43aa7SLois Curfman McInnes } 2847eb43aa7SLois Curfman McInnes 28517ab2063SBarry Smith 2865615d1e5SSatish Balay #undef __FUNC__ 2875615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_Binary" 288480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 28917ab2063SBarry Smith { 290416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 291416022c9SBarry Smith int i, fd, *col_lens, ierr; 29217ab2063SBarry Smith 2933a40ed3dSBarry Smith PetscFunctionBegin; 29490ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 2950452661fSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) ); CHKPTRQ(col_lens); 296416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 297416022c9SBarry Smith col_lens[1] = a->m; 298416022c9SBarry Smith col_lens[2] = a->n; 299416022c9SBarry Smith col_lens[3] = a->nz; 300416022c9SBarry Smith 301416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 302416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 303416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 30417ab2063SBarry Smith } 3050752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1); CHKERRQ(ierr); 3060452661fSBarry Smith PetscFree(col_lens); 307416022c9SBarry Smith 308416022c9SBarry Smith /* store column indices (zero start index) */ 309416022c9SBarry Smith if (a->indexshift) { 310416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]--; 31117ab2063SBarry Smith } 3120752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0); CHKERRQ(ierr); 313416022c9SBarry Smith if (a->indexshift) { 314416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]++; 31517ab2063SBarry Smith } 316416022c9SBarry Smith 317416022c9SBarry Smith /* store nonzero values */ 3180752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0); CHKERRQ(ierr); 3193a40ed3dSBarry Smith PetscFunctionReturn(0); 32017ab2063SBarry Smith } 321416022c9SBarry Smith 3225615d1e5SSatish Balay #undef __FUNC__ 3235615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_ASCII" 324480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 325416022c9SBarry Smith { 326416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 327496e697eSBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift, format, flg1,flg2; 32817ab2063SBarry Smith FILE *fd; 32917ab2063SBarry Smith char *outputname; 33017ab2063SBarry Smith 3313a40ed3dSBarry Smith PetscFunctionBegin; 33290ace30eSBarry Smith ierr = ViewerASCIIGetPointer(viewer,&fd); CHKERRQ(ierr); 333fb4b0f7fSBarry Smith ierr = ViewerGetOutputname(viewer,&outputname); CHKERRQ(ierr); 33490ace30eSBarry Smith ierr = ViewerGetFormat(viewer,&format); 335a93ec695SBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO) { 3363a40ed3dSBarry Smith PetscFunctionReturn(0); 3373a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_INFO_LONG) { 338496e697eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_aij_no_inode",&flg1); CHKERRQ(ierr); 339496e697eSBarry Smith ierr = OptionsHasName(PETSC_NULL,"-mat_no_unroll",&flg2); CHKERRQ(ierr); 340496e697eSBarry Smith if (flg1 || flg2) fprintf(fd," not using I-node routines\n"); 34195e01e2fSLois Curfman McInnes else fprintf(fd," using I-node routines: found %d nodes, limit used is %d\n", 34295e01e2fSLois Curfman McInnes a->inode.node_count,a->inode.limit); 3433a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 344d00d2cf4SBarry Smith int nofinalvalue = 0; 345d00d2cf4SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) { 346d00d2cf4SBarry Smith nofinalvalue = 1; 347d00d2cf4SBarry Smith } 348416022c9SBarry Smith fprintf(fd,"%% Size = %d %d \n",m,a->n); 3494e220ebcSLois Curfman McInnes fprintf(fd,"%% Nonzeros = %d \n",a->nz); 350d00d2cf4SBarry Smith fprintf(fd,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue); 35117ab2063SBarry Smith fprintf(fd,"zzz = [\n"); 35217ab2063SBarry Smith 35317ab2063SBarry Smith for (i=0; i<m; i++) { 354416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 3553a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 356e20fef11SSatish Balay fprintf(fd,"%d %d %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,PetscReal(a->a[j]),PetscImaginary(a->a[j])); 35717ab2063SBarry Smith #else 3587a743949SBarry Smith fprintf(fd,"%d %d %18.16e\n", i+1, a->j[j]+!shift, a->a[j]); 35917ab2063SBarry Smith #endif 36017ab2063SBarry Smith } 36117ab2063SBarry Smith } 362d00d2cf4SBarry Smith if (nofinalvalue) { 363d00d2cf4SBarry Smith fprintf(fd,"%d %d %18.16e\n", m, a->n, 0.0); 364d00d2cf4SBarry Smith } 365e24b481bSBarry Smith if (outputname) fprintf(fd,"];\n %s = spconvert(zzz);\n",outputname); 366e24b481bSBarry Smith else fprintf(fd,"];\n M = spconvert(zzz);\n"); 3673a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 36844cd7ae7SLois Curfman McInnes for ( i=0; i<m; i++ ) { 36944cd7ae7SLois Curfman McInnes fprintf(fd,"row %d:",i); 37044cd7ae7SLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 3713a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 372e20fef11SSatish Balay if (PetscImaginary(a->a[j]) > 0.0 && PetscReal(a->a[j]) != 0.0) 373e20fef11SSatish Balay fprintf(fd," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j])); 374e20fef11SSatish Balay else if (PetscImaginary(a->a[j]) < 0.0 && PetscReal(a->a[j]) != 0.0) 375e20fef11SSatish Balay fprintf(fd," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j])); 376e20fef11SSatish Balay else if (PetscReal(a->a[j]) != 0.0) 377e20fef11SSatish Balay fprintf(fd," %d %g ",a->j[j]+shift,PetscReal(a->a[j])); 37844cd7ae7SLois Curfman McInnes #else 37944cd7ae7SLois Curfman McInnes if (a->a[j] != 0.0) fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]); 38044cd7ae7SLois Curfman McInnes #endif 38144cd7ae7SLois Curfman McInnes } 38244cd7ae7SLois Curfman McInnes fprintf(fd,"\n"); 38344cd7ae7SLois Curfman McInnes } 38402594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) { 385496be53dSLois Curfman McInnes int nzd=0, fshift=1, *sptr; 3862e44a96cSLois Curfman McInnes sptr = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(sptr); 387496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 388496be53dSLois Curfman McInnes sptr[i] = nzd+1; 389496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 390496be53dSLois Curfman McInnes if (a->j[j] >= i) { 3913a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 392e20fef11SSatish Balay if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) nzd++; 393496be53dSLois Curfman McInnes #else 394496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 395496be53dSLois Curfman McInnes #endif 396496be53dSLois Curfman McInnes } 397496be53dSLois Curfman McInnes } 398496be53dSLois Curfman McInnes } 3992e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 400496be53dSLois Curfman McInnes fprintf(fd," %d %d\n\n",m,nzd); 4012e44a96cSLois Curfman McInnes for ( i=0; i<m+1; i+=6 ) { 4022e44a96cSLois Curfman McInnes if (i+4<m) fprintf(fd," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]); 4032e44a96cSLois Curfman McInnes else if (i+3<m) fprintf(fd," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]); 4042e44a96cSLois Curfman McInnes else if (i+2<m) fprintf(fd," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]); 4052e44a96cSLois Curfman McInnes else if (i+1<m) fprintf(fd," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]); 4062e44a96cSLois Curfman McInnes else if (i<m) fprintf(fd," %d %d\n",sptr[i],sptr[i+1]); 4077272d637SLois Curfman McInnes else fprintf(fd," %d\n",sptr[i]); 408496be53dSLois Curfman McInnes } 409496be53dSLois Curfman McInnes fprintf(fd,"\n"); 410496be53dSLois Curfman McInnes PetscFree(sptr); 411496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 412496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 413496be53dSLois Curfman McInnes if (a->j[j] >= i) fprintf(fd," %d ",a->j[j]+fshift); 414496be53dSLois Curfman McInnes } 415496be53dSLois Curfman McInnes fprintf(fd,"\n"); 416496be53dSLois Curfman McInnes } 417496be53dSLois Curfman McInnes fprintf(fd,"\n"); 418496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 419496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 420496be53dSLois Curfman McInnes if (a->j[j] >= i) { 4213a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 422e20fef11SSatish Balay if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) 423e20fef11SSatish Balay fprintf(fd," %18.16e %18.16e ",PetscReal(a->a[j]),PetscImaginary(a->a[j])); 424496be53dSLois Curfman McInnes #else 425496be53dSLois Curfman McInnes if (a->a[j] != 0.0) fprintf(fd," %18.16e ",a->a[j]); 426496be53dSLois Curfman McInnes #endif 427496be53dSLois Curfman McInnes } 428496be53dSLois Curfman McInnes } 429496be53dSLois Curfman McInnes fprintf(fd,"\n"); 430496be53dSLois Curfman McInnes } 43102594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_DENSE) { 43202594712SBarry Smith int cnt = 0,jcnt; 43302594712SBarry Smith Scalar value; 43402594712SBarry Smith 43502594712SBarry Smith for ( i=0; i<m; i++ ) { 43602594712SBarry Smith jcnt = 0; 43702594712SBarry Smith for ( j=0; j<a->n; j++ ) { 438e24b481bSBarry Smith if ( jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 43902594712SBarry Smith value = a->a[cnt++]; 440e24b481bSBarry Smith jcnt++; 44102594712SBarry Smith } else { 44202594712SBarry Smith value = 0.0; 44302594712SBarry Smith } 44402594712SBarry Smith #if defined(USE_PETSC_COMPLEX) 44502594712SBarry Smith fprintf(fd," %7.5e+%7.5e i ",PetscReal(value),PetscImaginary(value)); 44602594712SBarry Smith #else 44702594712SBarry Smith fprintf(fd," %7.5e ",value); 44802594712SBarry Smith #endif 44902594712SBarry Smith } 45002594712SBarry Smith fprintf(fd,"\n"); 45102594712SBarry Smith } 4523a40ed3dSBarry Smith } else { 45317ab2063SBarry Smith for ( i=0; i<m; i++ ) { 45417ab2063SBarry Smith fprintf(fd,"row %d:",i); 455416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 4563a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 457e20fef11SSatish Balay if (PetscImaginary(a->a[j]) > 0.0) { 458e20fef11SSatish Balay fprintf(fd," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j])); 459e20fef11SSatish Balay } else if (PetscImaginary(a->a[j]) < 0.0) { 460e20fef11SSatish Balay fprintf(fd," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j])); 4613a40ed3dSBarry Smith } else { 462e20fef11SSatish Balay fprintf(fd," %d %g ",a->j[j]+shift,PetscReal(a->a[j])); 46317ab2063SBarry Smith } 46417ab2063SBarry Smith #else 465416022c9SBarry Smith fprintf(fd," %d %g ",a->j[j]+shift,a->a[j]); 46617ab2063SBarry Smith #endif 46717ab2063SBarry Smith } 46817ab2063SBarry Smith fprintf(fd,"\n"); 46917ab2063SBarry Smith } 47017ab2063SBarry Smith } 47117ab2063SBarry Smith fflush(fd); 4723a40ed3dSBarry Smith PetscFunctionReturn(0); 473416022c9SBarry Smith } 474416022c9SBarry Smith 4755615d1e5SSatish Balay #undef __FUNC__ 476480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw_Zoom" 477480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa) 478416022c9SBarry Smith { 479480ef9eaSBarry Smith Mat A = (Mat) Aa; 480416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 481*77ed5343SBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift,color,rank; 4820513a670SBarry Smith int format; 483480ef9eaSBarry Smith double xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 484480ef9eaSBarry Smith Viewer viewer; 485*77ed5343SBarry Smith MPI_Comm comm; 486cddf8d76SBarry Smith 4873a40ed3dSBarry Smith PetscFunctionBegin; 488*77ed5343SBarry Smith /* 489*77ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 490*77ed5343SBarry Smith then all processes call this, but only the first has the matrix so the 491*77ed5343SBarry Smith rest should return immediately. 492*77ed5343SBarry Smith */ 493*77ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 494*77ed5343SBarry Smith MPI_Comm_rank(comm,&rank); 495*77ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 496*77ed5343SBarry Smith 497480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr); 4980513a670SBarry Smith ierr = ViewerGetFormat(viewer,&format); CHKERRQ(ierr); 49919bcc07fSBarry Smith 500480ef9eaSBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr); CHKERRQ(ierr); 501416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 5020513a670SBarry Smith 5030513a670SBarry Smith if (format != VIEWER_FORMAT_DRAW_CONTOUR) { 5040513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 505cddf8d76SBarry Smith color = DRAW_BLUE; 506416022c9SBarry Smith for ( i=0; i<m; i++ ) { 507cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 508416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 509cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 5103a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 511e20fef11SSatish Balay if (PetscReal(a->a[j]) >= 0.) continue; 512cddf8d76SBarry Smith #else 513cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 514cddf8d76SBarry Smith #endif 515480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 516cddf8d76SBarry Smith } 517cddf8d76SBarry Smith } 518cddf8d76SBarry Smith color = DRAW_CYAN; 519cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 520cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 521cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 522cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 523cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 524480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 525cddf8d76SBarry Smith } 526cddf8d76SBarry Smith } 527cddf8d76SBarry Smith color = DRAW_RED; 528cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 529cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 530cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 531cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 5323a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 533e20fef11SSatish Balay if (PetscReal(a->a[j]) <= 0.) continue; 534cddf8d76SBarry Smith #else 535cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 536cddf8d76SBarry Smith #endif 537480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 538416022c9SBarry Smith } 539416022c9SBarry Smith } 5400513a670SBarry Smith } else { 5410513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5420513a670SBarry Smith /* first determine max of all nonzero values */ 5430513a670SBarry Smith int nz = a->nz,count; 5440513a670SBarry Smith Draw popup; 545480ef9eaSBarry Smith double scale; 5460513a670SBarry Smith 5470513a670SBarry Smith for ( i=0; i<nz; i++ ) { 5480513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5490513a670SBarry Smith } 550480ef9eaSBarry Smith scale = (245.0 - DRAW_BASIC_COLORS)/maxv; 551522c5e43SBarry Smith ierr = DrawGetPopup(draw,&popup); CHKERRQ(ierr); 5520513a670SBarry Smith ierr = DrawScalePopup(popup,0.0,maxv); CHKERRQ(ierr); 5530513a670SBarry Smith count = 0; 5540513a670SBarry Smith for ( i=0; i<m; i++ ) { 5550513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 5560513a670SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 5570513a670SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 5586d6b6c30SSatish Balay color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 559480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5600513a670SBarry Smith count++; 5610513a670SBarry Smith } 5620513a670SBarry Smith } 5630513a670SBarry Smith } 564480ef9eaSBarry Smith PetscFunctionReturn(0); 565480ef9eaSBarry Smith } 566cddf8d76SBarry Smith 567480ef9eaSBarry Smith #undef __FUNC__ 568480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw" 569480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 570480ef9eaSBarry Smith { 571480ef9eaSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 572480ef9eaSBarry Smith int ierr; 573480ef9eaSBarry Smith Draw draw; 574480ef9eaSBarry Smith double xr,yr,xl,yl,h,w; 575480ef9eaSBarry Smith 576480ef9eaSBarry Smith PetscTruth isnull; 577480ef9eaSBarry Smith 578480ef9eaSBarry Smith PetscFunctionBegin; 579*77ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw); CHKERRQ(ierr); 580480ef9eaSBarry Smith ierr = DrawIsNull(draw,&isnull); CHKERRQ(ierr); 581480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 582480ef9eaSBarry Smith 583480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 584480ef9eaSBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 585480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 586cddf8d76SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr); CHKERRQ(ierr); 587480ef9eaSBarry Smith ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A); CHKERRQ(ierr); 588480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5893a40ed3dSBarry Smith PetscFunctionReturn(0); 590416022c9SBarry Smith } 591416022c9SBarry Smith 5925615d1e5SSatish Balay #undef __FUNC__ 593d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqAIJ" 594e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer) 595416022c9SBarry Smith { 596416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 597bcd2baecSBarry Smith ViewerType vtype; 598bcd2baecSBarry Smith int ierr; 599416022c9SBarry Smith 6003a40ed3dSBarry Smith PetscFunctionBegin; 601bcd2baecSBarry Smith ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 602*77ed5343SBarry Smith if (!PetscStrcmp(vtype,MATLAB_VIEWER)) { 6033a40ed3dSBarry Smith ierr = ViewerMatlabPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 604*77ed5343SBarry Smith } else if (!PetscStrcmp(vtype,ASCII_VIEWER)){ 6053a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer); CHKERRQ(ierr); 606*77ed5343SBarry Smith } else if (!PetscStrcmp(vtype,BINARY_VIEWER)) { 6073a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer); CHKERRQ(ierr); 608*77ed5343SBarry Smith } else if (!PetscStrcmp(vtype,DRAW_VIEWER)) { 6093a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer); CHKERRQ(ierr); 6105cd90555SBarry Smith } else { 6115cd90555SBarry Smith SETERRQ(1,1,"Viewer type not supported by PETSc object"); 61217ab2063SBarry Smith } 6133a40ed3dSBarry Smith PetscFunctionReturn(0); 61417ab2063SBarry Smith } 61519bcc07fSBarry Smith 616c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat); 6175615d1e5SSatish Balay #undef __FUNC__ 6185615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqAIJ" 6198f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 62017ab2063SBarry Smith { 621416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 62241c01911SSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr; 62343ee02c3SBarry Smith int m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift,rmax = 0; 624416022c9SBarry Smith Scalar *aa = a->a, *ap; 62517ab2063SBarry Smith 6263a40ed3dSBarry Smith PetscFunctionBegin; 6273a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 62817ab2063SBarry Smith 62943ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 63017ab2063SBarry Smith for ( i=1; i<m; i++ ) { 631416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 63217ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 63394a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 63417ab2063SBarry Smith if (fshift) { 635416022c9SBarry Smith ip = aj + ai[i] + shift; ap = aa + ai[i] + shift; 63617ab2063SBarry Smith N = ailen[i]; 63717ab2063SBarry Smith for ( j=0; j<N; j++ ) { 63817ab2063SBarry Smith ip[j-fshift] = ip[j]; 63917ab2063SBarry Smith ap[j-fshift] = ap[j]; 64017ab2063SBarry Smith } 64117ab2063SBarry Smith } 64217ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 64317ab2063SBarry Smith } 64417ab2063SBarry Smith if (m) { 64517ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 64617ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 64717ab2063SBarry Smith } 64817ab2063SBarry Smith /* reset ilen and imax for each row */ 64917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 65017ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 65117ab2063SBarry Smith } 652416022c9SBarry Smith a->nz = ai[m] + shift; 65317ab2063SBarry Smith 65417ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 655416022c9SBarry Smith if (fshift && a->diag) { 6560452661fSBarry Smith PetscFree(a->diag); 657416022c9SBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 658416022c9SBarry Smith a->diag = 0; 65917ab2063SBarry Smith } 6604e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n", 6614e220ebcSLois Curfman McInnes m,a->n,fshift,a->nz); 6624e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues is %d\n", 663b810aeb4SBarry Smith a->reallocs); 66494a9d846SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 665dd5f02e7SSatish Balay a->reallocs = 0; 6664e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 6674e220ebcSLois Curfman McInnes 66876dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 66941c01911SSatish Balay ierr = Mat_AIJ_CheckInode(A); CHKERRQ(ierr); 6703a40ed3dSBarry Smith PetscFunctionReturn(0); 67117ab2063SBarry Smith } 67217ab2063SBarry Smith 6735615d1e5SSatish Balay #undef __FUNC__ 6745615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_SeqAIJ" 6758f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 67617ab2063SBarry Smith { 677416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 6783a40ed3dSBarry Smith 6793a40ed3dSBarry Smith PetscFunctionBegin; 680cddf8d76SBarry Smith PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar)); 6813a40ed3dSBarry Smith PetscFunctionReturn(0); 68217ab2063SBarry Smith } 683416022c9SBarry Smith 6845615d1e5SSatish Balay #undef __FUNC__ 6855615d1e5SSatish Balay #define __FUNC__ "MatDestroy_SeqAIJ" 686e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 68717ab2063SBarry Smith { 688416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 68982bf6240SBarry Smith int ierr; 690d5d45c9bSBarry Smith 6913a40ed3dSBarry Smith PetscFunctionBegin; 69294d884c6SBarry Smith if (--A->refct > 0) PetscFunctionReturn(0); 69394d884c6SBarry Smith 69494d884c6SBarry Smith if (A->mapping) { 69594d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping); CHKERRQ(ierr); 69694d884c6SBarry Smith } 69794d884c6SBarry Smith if (A->bmapping) { 69894d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping); CHKERRQ(ierr); 69994d884c6SBarry Smith } 70061b13de0SBarry Smith if (A->rmap) { 70161b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 70261b13de0SBarry Smith } 70361b13de0SBarry Smith if (A->cmap) { 70461b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 70561b13de0SBarry Smith } 7063a40ed3dSBarry Smith #if defined(USE_PETSC_LOG) 707e1311b90SBarry Smith PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 70817ab2063SBarry Smith #endif 7090452661fSBarry Smith PetscFree(a->a); 7100452661fSBarry Smith if (!a->singlemalloc) { PetscFree(a->i); PetscFree(a->j);} 7110452661fSBarry Smith if (a->diag) PetscFree(a->diag); 7120452661fSBarry Smith if (a->ilen) PetscFree(a->ilen); 7130452661fSBarry Smith if (a->imax) PetscFree(a->imax); 7140452661fSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 71576dd722bSSatish Balay if (a->inode.size) PetscFree(a->inode.size); 71682bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 717be6bf707SBarry Smith if (a->saved_values) PetscFree(a->saved_values); 7180452661fSBarry Smith PetscFree(a); 719eed86810SBarry Smith 720f2655603SLois Curfman McInnes PLogObjectDestroy(A); 721f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 7223a40ed3dSBarry Smith PetscFunctionReturn(0); 72317ab2063SBarry Smith } 72417ab2063SBarry Smith 7255615d1e5SSatish Balay #undef __FUNC__ 7265615d1e5SSatish Balay #define __FUNC__ "MatCompress_SeqAIJ" 7278f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 72817ab2063SBarry Smith { 7293a40ed3dSBarry Smith PetscFunctionBegin; 7303a40ed3dSBarry Smith PetscFunctionReturn(0); 73117ab2063SBarry Smith } 73217ab2063SBarry Smith 7335615d1e5SSatish Balay #undef __FUNC__ 7345615d1e5SSatish Balay #define __FUNC__ "MatSetOption_SeqAIJ" 7358f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 73617ab2063SBarry Smith { 737416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7383a40ed3dSBarry Smith 7393a40ed3dSBarry Smith PetscFunctionBegin; 7406d4a8577SBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 7416d4a8577SBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 7426d4a8577SBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 743219d9a1aSLois Curfman McInnes else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 7446d4a8577SBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 745c2653b3dSLois Curfman McInnes else if (op == MAT_NEW_NONZERO_LOCATION_ERROR) a->nonew = -1; 74696854ed6SLois Curfman McInnes else if (op == MAT_NEW_NONZERO_ALLOCATION_ERROR) a->nonew = -2; 7476d4a8577SBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 7486d4a8577SBarry Smith else if (op == MAT_ROWS_SORTED || 749219d9a1aSLois Curfman McInnes op == MAT_ROWS_UNSORTED || 7506d4a8577SBarry Smith op == MAT_SYMMETRIC || 7516d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 75290f02eecSBarry Smith op == MAT_YES_NEW_DIAGONALS || 753b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES|| 754b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) 755981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 7563a40ed3dSBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) { 7573a40ed3dSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 7583a40ed3dSBarry Smith } else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 7596d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 7606d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 7616d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 7626d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 7633a40ed3dSBarry Smith else SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 7643a40ed3dSBarry Smith PetscFunctionReturn(0); 76517ab2063SBarry Smith } 76617ab2063SBarry Smith 7675615d1e5SSatish Balay #undef __FUNC__ 7685615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ" 7698f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 77017ab2063SBarry Smith { 771416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7723a40ed3dSBarry Smith int i,j, n,shift = a->indexshift,ierr; 77317ab2063SBarry Smith Scalar *x, zero = 0.0; 77417ab2063SBarry Smith 7753a40ed3dSBarry Smith PetscFunctionBegin; 7763a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 777e1311b90SBarry Smith ierr = VecGetArray(v,&x);;CHKERRQ(ierr); 778e1311b90SBarry Smith ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr); 779a8c6a408SBarry Smith if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector"); 780416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 781416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 782416022c9SBarry Smith if (a->j[j]+shift == i) { 783416022c9SBarry Smith x[i] = a->a[j]; 78417ab2063SBarry Smith break; 78517ab2063SBarry Smith } 78617ab2063SBarry Smith } 78717ab2063SBarry Smith } 788e1311b90SBarry Smith ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr); 7893a40ed3dSBarry Smith PetscFunctionReturn(0); 79017ab2063SBarry Smith } 79117ab2063SBarry Smith 79217ab2063SBarry Smith /* -------------------------------------------------------*/ 79317ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 79417ab2063SBarry Smith /* -------------------------------------------------------*/ 7955615d1e5SSatish Balay #undef __FUNC__ 7965615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ" 79744cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy) 79817ab2063SBarry Smith { 799416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 80017ab2063SBarry Smith Scalar *x, *y, *v, alpha; 801e1311b90SBarry Smith int ierr,m = a->m, n, i, *idx, shift = a->indexshift; 80217ab2063SBarry Smith 8033a40ed3dSBarry Smith PetscFunctionBegin; 804e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 805e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 806cddf8d76SBarry Smith PetscMemzero(y,a->n*sizeof(Scalar)); 80717ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 80817ab2063SBarry Smith for ( i=0; i<m; i++ ) { 809416022c9SBarry Smith idx = a->j + a->i[i] + shift; 810416022c9SBarry Smith v = a->a + a->i[i] + shift; 811416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 81217ab2063SBarry Smith alpha = x[i]; 81317ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 81417ab2063SBarry Smith } 815416022c9SBarry Smith PLogFlops(2*a->nz - a->n); 816e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 817e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8183a40ed3dSBarry Smith PetscFunctionReturn(0); 81917ab2063SBarry Smith } 820d5d45c9bSBarry Smith 8215615d1e5SSatish Balay #undef __FUNC__ 8225615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ" 82344cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 82417ab2063SBarry Smith { 825416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 82617ab2063SBarry Smith Scalar *x, *y, *v, alpha; 827e1311b90SBarry Smith int ierr,m = a->m, n, i, *idx,shift = a->indexshift; 82817ab2063SBarry Smith 8293a40ed3dSBarry Smith PetscFunctionBegin; 8302e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 831e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 832e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 83317ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 83417ab2063SBarry Smith for ( i=0; i<m; i++ ) { 835416022c9SBarry Smith idx = a->j + a->i[i] + shift; 836416022c9SBarry Smith v = a->a + a->i[i] + shift; 837416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 83817ab2063SBarry Smith alpha = x[i]; 83917ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 84017ab2063SBarry Smith } 84190f02eecSBarry Smith PLogFlops(2*a->nz); 842e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 843e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8443a40ed3dSBarry Smith PetscFunctionReturn(0); 84517ab2063SBarry Smith } 84617ab2063SBarry Smith 8475615d1e5SSatish Balay #undef __FUNC__ 8485615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ" 84944cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 85017ab2063SBarry Smith { 851416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 85217ab2063SBarry Smith Scalar *x, *y, *v, sum; 853e1311b90SBarry Smith int ierr,m = a->m, *idx, shift = a->indexshift,*ii; 8542e40c62eSSatish Balay #if !defined(USE_FORTRAN_KERNEL_MULTAIJ) 855e36a17ebSSatish Balay int n, i, jrow,j; 856e36a17ebSSatish Balay #endif 85717ab2063SBarry Smith 858fee21e36SBarry Smith #if defined(HAVE_PRAGMA_DISJOINT) 859fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 860fee21e36SBarry Smith #endif 861fee21e36SBarry Smith 8623a40ed3dSBarry Smith PetscFunctionBegin; 863e1311b90SBarry Smith ierr = VecGetArray(xx,&x); CHKERRQ(ierr); 864e1311b90SBarry Smith ierr = VecGetArray(yy,&y); CHKERRQ(ierr); 86517ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 866416022c9SBarry Smith idx = a->j; 867d64ed03dSBarry Smith v = a->a; 868416022c9SBarry Smith ii = a->i; 869acc4d009SSatish Balay #if defined(USE_FORTRAN_KERNEL_MULTAIJ) 87029b5ca8aSSatish Balay fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 8718d195f9aSBarry Smith #else 872d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 873d64ed03dSBarry Smith idx += shift; 87417ab2063SBarry Smith for ( i=0; i<m; i++ ) { 8759ea0dfa2SSatish Balay jrow = ii[i]; 8769ea0dfa2SSatish Balay n = ii[i+1] - jrow; 87717ab2063SBarry Smith sum = 0.0; 8789ea0dfa2SSatish Balay for ( j=0; j<n; j++) { 8799ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 8809ea0dfa2SSatish Balay } 88117ab2063SBarry Smith y[i] = sum; 88217ab2063SBarry Smith } 8838d195f9aSBarry Smith #endif 884416022c9SBarry Smith PLogFlops(2*a->nz - m); 885e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr); 886e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y); CHKERRQ(ierr); 8873a40ed3dSBarry Smith PetscFunctionReturn(0); 88817ab2063SBarry Smith } 88917ab2063SBarry Smith 8905615d1e5SSatish Balay #undef __FUNC__ 8915615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ" 89244cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 89317ab2063SBarry Smith { 894416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 89517ab2063SBarry Smith Scalar *x, *y, *z, *v, sum; 896e1311b90SBarry Smith int ierr,m = a->m, *idx, shift = a->indexshift,*ii; 8972e40c62eSSatish Balay #if !defined(USE_FORTRAN_KERNEL_MULTADDAIJ) 898e36a17ebSSatish Balay int n,i,jrow,j; 899e36a17ebSSatish Balay #endif 9009ea0dfa2SSatish Balay 9013a40ed3dSBarry Smith PetscFunctionBegin; 902e1311b90SBarry Smith ierr = VecGetArray(xx,&x); CHKERRQ(ierr); 903e1311b90SBarry Smith ierr = VecGetArray(yy,&y); CHKERRQ(ierr); 9042e8a6d31SBarry Smith if (zz != yy) { 905e1311b90SBarry Smith ierr = VecGetArray(zz,&z); CHKERRQ(ierr); 9062e8a6d31SBarry Smith } else { 9072e8a6d31SBarry Smith z = y; 9082e8a6d31SBarry Smith } 90917ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 910cddf8d76SBarry Smith idx = a->j; 911d64ed03dSBarry Smith v = a->a; 912cddf8d76SBarry Smith ii = a->i; 9132e40c62eSSatish Balay #if defined(USE_FORTRAN_KERNEL_MULTADDAIJ) 91429b5ca8aSSatish Balay fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 91502ab625aSSatish Balay #else 916d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 917d64ed03dSBarry Smith idx += shift; 91817ab2063SBarry Smith for ( i=0; i<m; i++ ) { 9199ea0dfa2SSatish Balay jrow = ii[i]; 9209ea0dfa2SSatish Balay n = ii[i+1] - jrow; 92117ab2063SBarry Smith sum = y[i]; 9229ea0dfa2SSatish Balay for ( j=0; j<n; j++) { 9239ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9249ea0dfa2SSatish Balay } 92517ab2063SBarry Smith z[i] = sum; 92617ab2063SBarry Smith } 92702ab625aSSatish Balay #endif 928416022c9SBarry Smith PLogFlops(2*a->nz); 929e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr); 930e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y); CHKERRQ(ierr); 9312e8a6d31SBarry Smith if (zz != yy) { 932e1311b90SBarry Smith ierr = VecRestoreArray(zz,&z); CHKERRQ(ierr); 9332e8a6d31SBarry Smith } 9343a40ed3dSBarry Smith PetscFunctionReturn(0); 93517ab2063SBarry Smith } 93617ab2063SBarry Smith 93717ab2063SBarry Smith /* 93817ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 93917ab2063SBarry Smith */ 94017ab2063SBarry Smith 9415615d1e5SSatish Balay #undef __FUNC__ 9425615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqAIJ" 943416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A) 94417ab2063SBarry Smith { 945416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 946416022c9SBarry Smith int i,j, *diag, m = a->m,shift = a->indexshift; 94717ab2063SBarry Smith 9483a40ed3dSBarry Smith PetscFunctionBegin; 9490452661fSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int)); CHKPTRQ(diag); 950416022c9SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 951416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 95235b0346bSBarry Smith diag[i] = a->i[i+1]; 953416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 954416022c9SBarry Smith if (a->j[j]+shift == i) { 95517ab2063SBarry Smith diag[i] = j - shift; 95617ab2063SBarry Smith break; 95717ab2063SBarry Smith } 95817ab2063SBarry Smith } 95917ab2063SBarry Smith } 960416022c9SBarry Smith a->diag = diag; 9613a40ed3dSBarry Smith PetscFunctionReturn(0); 96217ab2063SBarry Smith } 96317ab2063SBarry Smith 9645615d1e5SSatish Balay #undef __FUNC__ 9655615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ" 96644cd7ae7SLois Curfman McInnes int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag, 96717ab2063SBarry Smith double fshift,int its,Vec xx) 96817ab2063SBarry Smith { 969416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 970416022c9SBarry Smith Scalar *x, *b, *bs, d, *xs, sum, *v = a->a,*t,scale,*ts, *xb; 971d5d45c9bSBarry Smith int ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift; 97217ab2063SBarry Smith 9733a40ed3dSBarry Smith PetscFunctionBegin; 974e1311b90SBarry Smith ierr = VecGetArray(xx,&x); CHKERRQ(ierr); 975fb2e594dSBarry Smith if (xx != bb) { 976e1311b90SBarry Smith ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 977fb2e594dSBarry Smith } else { 978fb2e594dSBarry Smith b = x; 979fb2e594dSBarry Smith } 980fb2e594dSBarry Smith 981d00d2cf4SBarry Smith if (!a->diag) {ierr = MatMarkDiag_SeqAIJ(A);CHKERRQ(ierr);} 982416022c9SBarry Smith diag = a->diag; 983416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 98417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 98517ab2063SBarry Smith /* apply ( U + D/omega) to the vector */ 98617ab2063SBarry Smith bs = b + shift; 98717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 988416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 989416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 990488ecbafSBarry Smith PLogFlops(2*n-1); 991416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 992416022c9SBarry Smith v = a->a + diag[i] + (!shift); 99317ab2063SBarry Smith sum = b[i]*d/omega; 99417ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 99517ab2063SBarry Smith x[i] = sum; 99617ab2063SBarry Smith } 997cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr); 998fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 9993a40ed3dSBarry Smith PetscFunctionReturn(0); 100017ab2063SBarry Smith } 100117ab2063SBarry Smith if (flag == SOR_APPLY_LOWER) { 1002a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done"); 10033a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 100417ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 100517ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 100617ab2063SBarry Smith 100717ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 100817ab2063SBarry Smith 100917ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 101017ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 101117ab2063SBarry Smith is the relaxation factor. 101217ab2063SBarry Smith */ 10130452661fSBarry Smith t = (Scalar *) PetscMalloc( m*sizeof(Scalar) ); CHKPTRQ(t); 101417ab2063SBarry Smith scale = (2.0/omega) - 1.0; 101517ab2063SBarry Smith 101617ab2063SBarry Smith /* x = (E + U)^{-1} b */ 101717ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1018416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1019416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1020488ecbafSBarry Smith PLogFlops(2*n-1); 1021416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1022416022c9SBarry Smith v = a->a + diag[i] + (!shift); 102317ab2063SBarry Smith sum = b[i]; 102417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 102517ab2063SBarry Smith x[i] = omega*(sum/d); 102617ab2063SBarry Smith } 102717ab2063SBarry Smith 102817ab2063SBarry Smith /* t = b - (2*E - D)x */ 1029416022c9SBarry Smith v = a->a; 103017ab2063SBarry Smith for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 1031488ecbafSBarry Smith PLogFlops(2*m); 1032488ecbafSBarry Smith 103317ab2063SBarry Smith 103417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1035416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 1036416022c9SBarry Smith diag = a->diag; 103717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1038416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1039416022c9SBarry Smith n = diag[i] - a->i[i]; 1040488ecbafSBarry Smith PLogFlops(2*n-1); 1041416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1042416022c9SBarry Smith v = a->a + a->i[i] + shift; 104317ab2063SBarry Smith sum = t[i]; 104417ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 104517ab2063SBarry Smith t[i] = omega*(sum/d); 104617ab2063SBarry Smith } 104717ab2063SBarry Smith 104817ab2063SBarry Smith /* x = x + t */ 104917ab2063SBarry Smith for ( i=0; i<m; i++ ) { x[i] += t[i]; } 10500452661fSBarry Smith PetscFree(t); 1051cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr); 1052fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 10533a40ed3dSBarry Smith PetscFunctionReturn(0); 105417ab2063SBarry Smith } 105517ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 105617ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 105717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1058416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1059416022c9SBarry Smith n = diag[i] - a->i[i]; 1060488ecbafSBarry Smith PLogFlops(2*n-1); 1061416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1062416022c9SBarry Smith v = a->a + a->i[i] + shift; 106317ab2063SBarry Smith sum = b[i]; 106417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 106517ab2063SBarry Smith x[i] = omega*(sum/d); 106617ab2063SBarry Smith } 106717ab2063SBarry Smith xb = x; 10683a40ed3dSBarry Smith } else xb = b; 106917ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 107017ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 107117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1072416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 107317ab2063SBarry Smith } 1074488ecbafSBarry Smith PLogFlops(m); 107517ab2063SBarry Smith } 107617ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 107717ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1078416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1079416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1080488ecbafSBarry Smith PLogFlops(2*n-1); 1081416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1082416022c9SBarry Smith v = a->a + diag[i] + (!shift); 108317ab2063SBarry Smith sum = xb[i]; 108417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 108517ab2063SBarry Smith x[i] = omega*(sum/d); 108617ab2063SBarry Smith } 108717ab2063SBarry Smith } 108817ab2063SBarry Smith its--; 108917ab2063SBarry Smith } 109017ab2063SBarry Smith while (its--) { 109117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 109217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1093416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1094416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1095488ecbafSBarry Smith PLogFlops(2*n-1); 1096416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1097416022c9SBarry Smith v = a->a + a->i[i] + shift; 109817ab2063SBarry Smith sum = b[i]; 109917ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11007e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 110117ab2063SBarry Smith } 110217ab2063SBarry Smith } 110317ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 110417ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1105416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1106416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1107488ecbafSBarry Smith PLogFlops(2*n-1); 1108416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1109416022c9SBarry Smith v = a->a + a->i[i] + shift; 111017ab2063SBarry Smith sum = b[i]; 111117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11127e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 111317ab2063SBarry Smith } 111417ab2063SBarry Smith } 111517ab2063SBarry Smith } 1116cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x); CHKERRQ(ierr); 1117fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 11183a40ed3dSBarry Smith PetscFunctionReturn(0); 111917ab2063SBarry Smith } 112017ab2063SBarry Smith 11215615d1e5SSatish Balay #undef __FUNC__ 11225615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ" 11238f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 112417ab2063SBarry Smith { 1125416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 11264e220ebcSLois Curfman McInnes 11273a40ed3dSBarry Smith PetscFunctionBegin; 11284e220ebcSLois Curfman McInnes info->rows_global = (double)a->m; 11294e220ebcSLois Curfman McInnes info->columns_global = (double)a->n; 11304e220ebcSLois Curfman McInnes info->rows_local = (double)a->m; 11314e220ebcSLois Curfman McInnes info->columns_local = (double)a->n; 11324e220ebcSLois Curfman McInnes info->block_size = 1.0; 11334e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 11344e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 11354e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 11364e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 11374e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 11384e220ebcSLois Curfman McInnes info->memory = A->mem; 11394e220ebcSLois Curfman McInnes if (A->factor) { 11404e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 11414e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 11424e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 11434e220ebcSLois Curfman McInnes } else { 11444e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 11454e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 11464e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 11474e220ebcSLois Curfman McInnes } 11483a40ed3dSBarry Smith PetscFunctionReturn(0); 114917ab2063SBarry Smith } 115017ab2063SBarry Smith 115117ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*); 115217ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 115317ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double); 115417ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 115517ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 115617ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec); 115717ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec); 115817ab2063SBarry Smith 11595615d1e5SSatish Balay #undef __FUNC__ 11605615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ" 11618f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 116217ab2063SBarry Smith { 1163416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1164416022c9SBarry Smith int i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift; 116517ab2063SBarry Smith 11663a40ed3dSBarry Smith PetscFunctionBegin; 116777c4ece6SBarry Smith ierr = ISGetSize(is,&N); CHKERRQ(ierr); 116817ab2063SBarry Smith ierr = ISGetIndices(is,&rows); CHKERRQ(ierr); 116917ab2063SBarry Smith if (diag) { 117017ab2063SBarry Smith for ( i=0; i<N; i++ ) { 1171a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1172416022c9SBarry Smith if (a->ilen[rows[i]] > 0) { /* in case row was completely empty */ 1173416022c9SBarry Smith a->ilen[rows[i]] = 1; 1174416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1175416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 11763a40ed3dSBarry Smith } else { 1177d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 117817ab2063SBarry Smith } 117917ab2063SBarry Smith } 11803a40ed3dSBarry Smith } else { 118117ab2063SBarry Smith for ( i=0; i<N; i++ ) { 1182a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1183416022c9SBarry Smith a->ilen[rows[i]] = 0; 118417ab2063SBarry Smith } 118517ab2063SBarry Smith } 118617ab2063SBarry Smith ISRestoreIndices(is,&rows); 118743a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 11883a40ed3dSBarry Smith PetscFunctionReturn(0); 118917ab2063SBarry Smith } 119017ab2063SBarry Smith 11915615d1e5SSatish Balay #undef __FUNC__ 11925615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ" 11938f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 119417ab2063SBarry Smith { 1195416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 11963a40ed3dSBarry Smith 11973a40ed3dSBarry Smith PetscFunctionBegin; 11980752156aSBarry Smith if (m) *m = a->m; 11990752156aSBarry Smith if (n) *n = a->n; 12003a40ed3dSBarry Smith PetscFunctionReturn(0); 120117ab2063SBarry Smith } 120217ab2063SBarry Smith 12035615d1e5SSatish Balay #undef __FUNC__ 12045615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ" 12058f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 120617ab2063SBarry Smith { 1207416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12083a40ed3dSBarry Smith 12093a40ed3dSBarry Smith PetscFunctionBegin; 1210416022c9SBarry Smith *m = 0; *n = a->m; 12113a40ed3dSBarry Smith PetscFunctionReturn(0); 121217ab2063SBarry Smith } 1213026e39d0SSatish Balay 12145615d1e5SSatish Balay #undef __FUNC__ 12155615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ" 12164e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 121717ab2063SBarry Smith { 1218416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1219c456f294SBarry Smith int *itmp,i,shift = a->indexshift; 122017ab2063SBarry Smith 12213a40ed3dSBarry Smith PetscFunctionBegin; 1222a8c6a408SBarry Smith if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 122317ab2063SBarry Smith 1224416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1225416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 122617ab2063SBarry Smith if (idx) { 1227416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 12284e093b46SBarry Smith if (*nz && shift) { 12290452661fSBarry Smith *idx = (int *) PetscMalloc( (*nz)*sizeof(int) ); CHKPTRQ(*idx); 123017ab2063SBarry Smith for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;} 12314e093b46SBarry Smith } else if (*nz) { 12324e093b46SBarry Smith *idx = itmp; 123317ab2063SBarry Smith } 123417ab2063SBarry Smith else *idx = 0; 123517ab2063SBarry Smith } 12363a40ed3dSBarry Smith PetscFunctionReturn(0); 123717ab2063SBarry Smith } 123817ab2063SBarry Smith 12395615d1e5SSatish Balay #undef __FUNC__ 12405615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ" 12414e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 124217ab2063SBarry Smith { 12434e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12443a40ed3dSBarry Smith 12453a40ed3dSBarry Smith PetscFunctionBegin; 12464e093b46SBarry Smith if (idx) {if (*idx && a->indexshift) PetscFree(*idx);} 12473a40ed3dSBarry Smith PetscFunctionReturn(0); 124817ab2063SBarry Smith } 124917ab2063SBarry Smith 12505615d1e5SSatish Balay #undef __FUNC__ 12515615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ" 12528f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm) 125317ab2063SBarry Smith { 1254416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1255416022c9SBarry Smith Scalar *v = a->a; 125617ab2063SBarry Smith double sum = 0.0; 1257416022c9SBarry Smith int i, j,shift = a->indexshift; 125817ab2063SBarry Smith 12593a40ed3dSBarry Smith PetscFunctionBegin; 126017ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1261416022c9SBarry Smith for (i=0; i<a->nz; i++ ) { 12623a40ed3dSBarry Smith #if defined(USE_PETSC_COMPLEX) 1263e20fef11SSatish Balay sum += PetscReal(PetscConj(*v)*(*v)); v++; 126417ab2063SBarry Smith #else 126517ab2063SBarry Smith sum += (*v)*(*v); v++; 126617ab2063SBarry Smith #endif 126717ab2063SBarry Smith } 126817ab2063SBarry Smith *norm = sqrt(sum); 12693a40ed3dSBarry Smith } else if (type == NORM_1) { 127017ab2063SBarry Smith double *tmp; 1271416022c9SBarry Smith int *jj = a->j; 127266963ce1SSatish Balay tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) ); CHKPTRQ(tmp); 1273cddf8d76SBarry Smith PetscMemzero(tmp,a->n*sizeof(double)); 127417ab2063SBarry Smith *norm = 0.0; 1275416022c9SBarry Smith for ( j=0; j<a->nz; j++ ) { 1276a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 127717ab2063SBarry Smith } 1278416022c9SBarry Smith for ( j=0; j<a->n; j++ ) { 127917ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 128017ab2063SBarry Smith } 12810452661fSBarry Smith PetscFree(tmp); 12823a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 128317ab2063SBarry Smith *norm = 0.0; 1284416022c9SBarry Smith for ( j=0; j<a->m; j++ ) { 1285416022c9SBarry Smith v = a->a + a->i[j] + shift; 128617ab2063SBarry Smith sum = 0.0; 1287416022c9SBarry Smith for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) { 1288cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 128917ab2063SBarry Smith } 129017ab2063SBarry Smith if (sum > *norm) *norm = sum; 129117ab2063SBarry Smith } 12923a40ed3dSBarry Smith } else { 1293a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"No support for two norm"); 129417ab2063SBarry Smith } 12953a40ed3dSBarry Smith PetscFunctionReturn(0); 129617ab2063SBarry Smith } 129717ab2063SBarry Smith 12985615d1e5SSatish Balay #undef __FUNC__ 12995615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ" 13008f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 130117ab2063SBarry Smith { 1302416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1303416022c9SBarry Smith Mat C; 1304416022c9SBarry Smith int i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col; 1305416022c9SBarry Smith int shift = a->indexshift; 1306d5d45c9bSBarry Smith Scalar *array = a->a; 130717ab2063SBarry Smith 13083a40ed3dSBarry Smith PetscFunctionBegin; 1309a8c6a408SBarry Smith if (B == PETSC_NULL && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place"); 13100452661fSBarry Smith col = (int *) PetscMalloc((1+a->n)*sizeof(int)); CHKPTRQ(col); 1311cddf8d76SBarry Smith PetscMemzero(col,(1+a->n)*sizeof(int)); 131217ab2063SBarry Smith if (shift) { 131317ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1; 131417ab2063SBarry Smith } 131517ab2063SBarry Smith for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1; 1316416022c9SBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C); CHKERRQ(ierr); 13170452661fSBarry Smith PetscFree(col); 131817ab2063SBarry Smith for ( i=0; i<m; i++ ) { 131917ab2063SBarry Smith len = ai[i+1]-ai[i]; 1320416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES); CHKERRQ(ierr); 132117ab2063SBarry Smith array += len; aj += len; 132217ab2063SBarry Smith } 132317ab2063SBarry Smith if (shift) { 132417ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1; 132517ab2063SBarry Smith } 132617ab2063SBarry Smith 13276d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 13286d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 132917ab2063SBarry Smith 13303638b69dSLois Curfman McInnes if (B != PETSC_NULL) { 1331416022c9SBarry Smith *B = C; 133217ab2063SBarry Smith } else { 1333f830108cSBarry Smith PetscOps *Abops; 13340a6ffc59SBarry Smith MatOps Aops; 1335f830108cSBarry Smith 1336416022c9SBarry Smith /* This isn't really an in-place transpose */ 13370452661fSBarry Smith PetscFree(a->a); 13380452661fSBarry Smith if (!a->singlemalloc) {PetscFree(a->i); PetscFree(a->j);} 13390452661fSBarry Smith if (a->diag) PetscFree(a->diag); 13400452661fSBarry Smith if (a->ilen) PetscFree(a->ilen); 13410452661fSBarry Smith if (a->imax) PetscFree(a->imax); 13420452661fSBarry Smith if (a->solve_work) PetscFree(a->solve_work); 13431073c447SSatish Balay if (a->inode.size) PetscFree(a->inode.size); 13440452661fSBarry Smith PetscFree(a); 1345f830108cSBarry Smith 1346488ecbafSBarry Smith 1347488ecbafSBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 1348488ecbafSBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 1349488ecbafSBarry Smith 1350f830108cSBarry Smith /* 1351f830108cSBarry Smith This is horrible, horrible code. We need to keep the 13528f0f457cSSatish Balay the bops and ops Structures, copy everything from C 13538f0f457cSSatish Balay including the function pointers.. 1354f830108cSBarry Smith */ 13558f0f457cSSatish Balay PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps)); 13568f0f457cSSatish Balay PetscMemcpy(A->bops,C->bops,sizeof(PetscOps)); 1357f830108cSBarry Smith Abops = A->bops; 1358f830108cSBarry Smith Aops = A->ops; 1359f09e8eb9SSatish Balay PetscMemcpy(A,C,sizeof(struct _p_Mat)); 1360f830108cSBarry Smith A->bops = Abops; 1361f830108cSBarry Smith A->ops = Aops; 136227a8da17SBarry Smith A->qlist = 0; 1363f830108cSBarry Smith 13640452661fSBarry Smith PetscHeaderDestroy(C); 136517ab2063SBarry Smith } 13663a40ed3dSBarry Smith PetscFunctionReturn(0); 136717ab2063SBarry Smith } 136817ab2063SBarry Smith 13695615d1e5SSatish Balay #undef __FUNC__ 13705615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ" 13718f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 137217ab2063SBarry Smith { 1373416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 137417ab2063SBarry Smith Scalar *l,*r,x,*v; 1375e1311b90SBarry Smith int ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift; 137617ab2063SBarry Smith 13773a40ed3dSBarry Smith PetscFunctionBegin; 137817ab2063SBarry Smith if (ll) { 13793ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 13803ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1381e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1382a8c6a408SBarry Smith if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length"); 1383e1311b90SBarry Smith ierr = VecGetArray(ll,&l); CHKERRQ(ierr); 1384416022c9SBarry Smith v = a->a; 138517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 138617ab2063SBarry Smith x = l[i]; 1387416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 138817ab2063SBarry Smith for ( j=0; j<M; j++ ) { (*v++) *= x;} 138917ab2063SBarry Smith } 1390e1311b90SBarry Smith ierr = VecRestoreArray(ll,&l); CHKERRQ(ierr); 139144cd7ae7SLois Curfman McInnes PLogFlops(nz); 139217ab2063SBarry Smith } 139317ab2063SBarry Smith if (rr) { 1394e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1395a8c6a408SBarry Smith if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length"); 1396e1311b90SBarry Smith ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1397416022c9SBarry Smith v = a->a; jj = a->j; 139817ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 139917ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 140017ab2063SBarry Smith } 1401e1311b90SBarry Smith ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 140244cd7ae7SLois Curfman McInnes PLogFlops(nz); 140317ab2063SBarry Smith } 14043a40ed3dSBarry Smith PetscFunctionReturn(0); 140517ab2063SBarry Smith } 140617ab2063SBarry Smith 14075615d1e5SSatish Balay #undef __FUNC__ 14085615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ" 14096a6a5d1dSBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatGetSubMatrixCall scall,Mat *B) 141017ab2063SBarry Smith { 1411db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data,*c; 1412d5db1b72SBarry Smith int *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens; 141399141d43SSatish Balay int row,mat_i,*mat_j,tcol,first,step,*mat_ilen; 1414a2744918SBarry Smith register int sum,lensi; 141599141d43SSatish Balay int *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap; 141699141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen; 141799141d43SSatish Balay Scalar *a_new,*mat_a; 1418416022c9SBarry Smith Mat C; 1419fee21e36SBarry Smith PetscTruth stride; 142017ab2063SBarry Smith 14213a40ed3dSBarry Smith PetscFunctionBegin; 1422d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 1423a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted"); 1424d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 1425a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted"); 142699141d43SSatish Balay 142717ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow); CHKERRQ(ierr); 142817ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows); CHKERRQ(ierr); 142917ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols); CHKERRQ(ierr); 143017ab2063SBarry Smith 1431fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step); CHKERRQ(ierr); 1432fee21e36SBarry Smith ierr = ISStride(iscol,&stride); CHKERRQ(ierr); 1433fee21e36SBarry Smith if (stride && step == 1) { 143402834360SBarry Smith /* special case of contiguous rows */ 143557faeb66SBarry Smith lens = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int)); CHKPTRQ(lens); 143602834360SBarry Smith starts = lens + ncols; 143702834360SBarry Smith /* loop over new rows determining lens and starting points */ 143802834360SBarry Smith for (i=0; i<nrows; i++) { 1439a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1440a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 144102834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1442d8ced48eSBarry Smith if (aj[k]+shift >= first) { 144302834360SBarry Smith starts[i] = k; 144402834360SBarry Smith break; 144502834360SBarry Smith } 144602834360SBarry Smith } 1447a2744918SBarry Smith sum = 0; 144802834360SBarry Smith while (k < kend) { 1449d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1450a2744918SBarry Smith sum++; 145102834360SBarry Smith } 1452a2744918SBarry Smith lens[i] = sum; 145302834360SBarry Smith } 145402834360SBarry Smith /* create submatrix */ 1455cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 145608480c60SBarry Smith int n_cols,n_rows; 145708480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols); CHKERRQ(ierr); 1458a8c6a408SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1459d8ced48eSBarry Smith ierr = MatZeroEntries(*B); CHKERRQ(ierr); 146008480c60SBarry Smith C = *B; 14613a40ed3dSBarry Smith } else { 146202834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 146308480c60SBarry Smith } 1464db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*) C->data; 1465db02288aSLois Curfman McInnes 146602834360SBarry Smith /* loop over rows inserting into submatrix */ 1467db02288aSLois Curfman McInnes a_new = c->a; 1468db02288aSLois Curfman McInnes j_new = c->j; 1469db02288aSLois Curfman McInnes i_new = c->i; 1470db02288aSLois Curfman McInnes i_new[0] = -shift; 147102834360SBarry Smith for (i=0; i<nrows; i++) { 1472a2744918SBarry Smith ii = starts[i]; 1473a2744918SBarry Smith lensi = lens[i]; 1474a2744918SBarry Smith for ( k=0; k<lensi; k++ ) { 1475a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 147602834360SBarry Smith } 1477a2744918SBarry Smith PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar)); 1478a2744918SBarry Smith a_new += lensi; 1479a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1480a2744918SBarry Smith c->ilen[i] = lensi; 148102834360SBarry Smith } 14820452661fSBarry Smith PetscFree(lens); 14833a40ed3dSBarry Smith } else { 148402834360SBarry Smith ierr = ISGetIndices(iscol,&icol); CHKERRQ(ierr); 14850452661fSBarry Smith smap = (int *) PetscMalloc((1+oldcols)*sizeof(int)); CHKPTRQ(smap); 148602834360SBarry Smith ssmap = smap + shift; 148799141d43SSatish Balay lens = (int *) PetscMalloc((1+nrows)*sizeof(int)); CHKPTRQ(lens); 1488cddf8d76SBarry Smith PetscMemzero(smap,oldcols*sizeof(int)); 148917ab2063SBarry Smith for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 149002834360SBarry Smith /* determine lens of each row */ 149102834360SBarry Smith for (i=0; i<nrows; i++) { 1492d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 149302834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 149402834360SBarry Smith lens[i] = 0; 149502834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1496d8ced48eSBarry Smith if (ssmap[aj[k]]) { 149702834360SBarry Smith lens[i]++; 149802834360SBarry Smith } 149902834360SBarry Smith } 150002834360SBarry Smith } 150117ab2063SBarry Smith /* Create and fill new matrix */ 1502a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 150399141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1504a8c6a408SBarry Smith if (c->m != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size"); 150599141d43SSatish Balay if (PetscMemcmp(c->ilen,lens, c->m *sizeof(int))) { 1506a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros"); 150799141d43SSatish Balay } 150899141d43SSatish Balay PetscMemzero(c->ilen,c->m*sizeof(int)); 150908480c60SBarry Smith C = *B; 15103a40ed3dSBarry Smith } else { 151102834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 151208480c60SBarry Smith } 151399141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 151417ab2063SBarry Smith for (i=0; i<nrows; i++) { 151599141d43SSatish Balay row = irow[i]; 151699141d43SSatish Balay kstart = ai[row]+shift; 151799141d43SSatish Balay kend = kstart + a->ilen[row]; 151899141d43SSatish Balay mat_i = c->i[i]+shift; 151999141d43SSatish Balay mat_j = c->j + mat_i; 152099141d43SSatish Balay mat_a = c->a + mat_i; 152199141d43SSatish Balay mat_ilen = c->ilen + i; 152217ab2063SBarry Smith for ( k=kstart; k<kend; k++ ) { 152399141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 152499141d43SSatish Balay *mat_j++ = tcol - (!shift); 152599141d43SSatish Balay *mat_a++ = a->a[k]; 152699141d43SSatish Balay (*mat_ilen)++; 152799141d43SSatish Balay 152817ab2063SBarry Smith } 152917ab2063SBarry Smith } 153017ab2063SBarry Smith } 153102834360SBarry Smith /* Free work space */ 153202834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol); CHKERRQ(ierr); 153399141d43SSatish Balay PetscFree(smap); PetscFree(lens); 153402834360SBarry Smith } 15356d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 15366d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 153717ab2063SBarry Smith 153817ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow); CHKERRQ(ierr); 1539416022c9SBarry Smith *B = C; 15403a40ed3dSBarry Smith PetscFunctionReturn(0); 154117ab2063SBarry Smith } 154217ab2063SBarry Smith 1543a871dcd8SBarry Smith /* 154463b91edcSBarry Smith note: This can only work for identity for row and col. It would 154563b91edcSBarry Smith be good to check this and otherwise generate an error. 1546a871dcd8SBarry Smith */ 15475615d1e5SSatish Balay #undef __FUNC__ 15485615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ" 15498f6be9afSLois Curfman McInnes int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,double efill,int fill) 1550a871dcd8SBarry Smith { 155163b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 155208480c60SBarry Smith int ierr; 155363b91edcSBarry Smith Mat outA; 155463b91edcSBarry Smith 15553a40ed3dSBarry Smith PetscFunctionBegin; 1556a8c6a408SBarry Smith if (fill != 0) SETERRQ(PETSC_ERR_SUP,0,"Only fill=0 supported"); 1557a871dcd8SBarry Smith 155863b91edcSBarry Smith outA = inA; 155963b91edcSBarry Smith inA->factor = FACTOR_LU; 156063b91edcSBarry Smith a->row = row; 156163b91edcSBarry Smith a->col = col; 156263b91edcSBarry Smith 1563f0ec6fceSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1564f0ec6fceSSatish Balay ierr = ISInvertPermutation(col,&(a->icol)); CHKERRQ(ierr); 15651e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1566f0ec6fceSSatish Balay 156794a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 15680452661fSBarry Smith a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work); 156994a9d846SBarry Smith } 157063b91edcSBarry Smith 157108480c60SBarry Smith if (!a->diag) { 157208480c60SBarry Smith ierr = MatMarkDiag_SeqAIJ(inA); CHKERRQ(ierr); 157363b91edcSBarry Smith } 157463b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA); CHKERRQ(ierr); 15753a40ed3dSBarry Smith PetscFunctionReturn(0); 1576a871dcd8SBarry Smith } 1577a871dcd8SBarry Smith 157874cdf0dfSBarry Smith #include "pinclude/blaslapack.h" 15795615d1e5SSatish Balay #undef __FUNC__ 15805615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ" 15818f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1582f0b747eeSBarry Smith { 1583f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 1584f0b747eeSBarry Smith int one = 1; 15853a40ed3dSBarry Smith 15863a40ed3dSBarry Smith PetscFunctionBegin; 1587f0b747eeSBarry Smith BLscal_( &a->nz, alpha, a->a, &one ); 1588f0b747eeSBarry Smith PLogFlops(a->nz); 15893a40ed3dSBarry Smith PetscFunctionReturn(0); 1590f0b747eeSBarry Smith } 1591f0b747eeSBarry Smith 15925615d1e5SSatish Balay #undef __FUNC__ 15935615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ" 15946a6a5d1dSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatGetSubMatrixCall scall,Mat **B) 1595cddf8d76SBarry Smith { 1596cddf8d76SBarry Smith int ierr,i; 1597cddf8d76SBarry Smith 15983a40ed3dSBarry Smith PetscFunctionBegin; 1599cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 16000452661fSBarry Smith *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) ); CHKPTRQ(*B); 1601cddf8d76SBarry Smith } 1602cddf8d76SBarry Smith 1603cddf8d76SBarry Smith for ( i=0; i<n; i++ ) { 16046a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1605cddf8d76SBarry Smith } 16063a40ed3dSBarry Smith PetscFunctionReturn(0); 1607cddf8d76SBarry Smith } 1608cddf8d76SBarry Smith 16095615d1e5SSatish Balay #undef __FUNC__ 16105615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ" 16118f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs) 16125a838052SSatish Balay { 1613f830108cSBarry Smith PetscFunctionBegin; 16145a838052SSatish Balay *bs = 1; 16153a40ed3dSBarry Smith PetscFunctionReturn(0); 16165a838052SSatish Balay } 16175a838052SSatish Balay 16185615d1e5SSatish Balay #undef __FUNC__ 16195615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ" 16208f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov) 16214dcbc457SBarry Smith { 1622e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 162306763907SSatish Balay int shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val; 16248a047759SSatish Balay int start, end, *ai, *aj; 1625bbd702dbSSatish Balay BT table; 1626bbd702dbSSatish Balay 16273a40ed3dSBarry Smith PetscFunctionBegin; 16288a047759SSatish Balay shift = a->indexshift; 1629e4d965acSSatish Balay m = a->m; 1630e4d965acSSatish Balay ai = a->i; 16318a047759SSatish Balay aj = a->j+shift; 16328a047759SSatish Balay 1633a8c6a408SBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used"); 163406763907SSatish Balay 163506763907SSatish Balay nidx = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(nidx); 1636bbd702dbSSatish Balay ierr = BTCreate(m,table); CHKERRQ(ierr); 163706763907SSatish Balay 1638e4d965acSSatish Balay for ( i=0; i<is_max; i++ ) { 1639b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1640e4d965acSSatish Balay isz = 0; 1641bbd702dbSSatish Balay BTMemzero(m,table); 1642e4d965acSSatish Balay 1643e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 16444dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx); CHKERRQ(ierr); 164577c4ece6SBarry Smith ierr = ISGetSize(is[i],&n); CHKERRQ(ierr); 1646e4d965acSSatish Balay 1647dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1648e4d965acSSatish Balay for ( j=0; j<n ; ++j){ 1649bbd702dbSSatish Balay if(!BTLookupSet(table, idx[j])) { nidx[isz++] = idx[j];} 16504dcbc457SBarry Smith } 165106763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx); CHKERRQ(ierr); 165206763907SSatish Balay ierr = ISDestroy(is[i]); CHKERRQ(ierr); 1653e4d965acSSatish Balay 165404a348a9SBarry Smith k = 0; 165504a348a9SBarry Smith for ( j=0; j<ov; j++){ /* for each overlap */ 165604a348a9SBarry Smith n = isz; 165706763907SSatish Balay for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1658e4d965acSSatish Balay row = nidx[k]; 1659e4d965acSSatish Balay start = ai[row]; 1660e4d965acSSatish Balay end = ai[row+1]; 166104a348a9SBarry Smith for ( l = start; l<end ; l++){ 16628a047759SSatish Balay val = aj[l] + shift; 16632a8f2162SSatish Balay if (!BTLookupSet(table,val)) {nidx[isz++] = val;} 1664e4d965acSSatish Balay } 1665e4d965acSSatish Balay } 1666e4d965acSSatish Balay } 1667029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i)); CHKERRQ(ierr); 1668e4d965acSSatish Balay } 1669bbd702dbSSatish Balay BTDestroy(table); 167006763907SSatish Balay PetscFree(nidx); 16713a40ed3dSBarry Smith PetscFunctionReturn(0); 16724dcbc457SBarry Smith } 167317ab2063SBarry Smith 16740513a670SBarry Smith /* -------------------------------------------------------------- */ 16750513a670SBarry Smith #undef __FUNC__ 16760513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ" 16770513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B) 16780513a670SBarry Smith { 16790513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 16800513a670SBarry Smith Scalar *vwork; 16810513a670SBarry Smith int i, ierr, nz, m = a->m, n = a->n, *cwork; 16820513a670SBarry Smith int *row,*col,*cnew,j,*lens; 168356cd22aeSBarry Smith IS icolp,irowp; 16840513a670SBarry Smith 16853a40ed3dSBarry Smith PetscFunctionBegin; 168656cd22aeSBarry Smith ierr = ISInvertPermutation(rowp,&irowp); CHKERRQ(ierr); 168756cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row); CHKERRQ(ierr); 168856cd22aeSBarry Smith ierr = ISInvertPermutation(colp,&icolp); CHKERRQ(ierr); 168956cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col); CHKERRQ(ierr); 16900513a670SBarry Smith 16910513a670SBarry Smith /* determine lengths of permuted rows */ 16920513a670SBarry Smith lens = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(lens); 16930513a670SBarry Smith for (i=0; i<m; i++ ) { 16940513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 16950513a670SBarry Smith } 16960513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 16970513a670SBarry Smith PetscFree(lens); 16980513a670SBarry Smith 16990513a670SBarry Smith cnew = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(cnew); 17000513a670SBarry Smith for (i=0; i<m; i++) { 17010513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 17020513a670SBarry Smith for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];} 17030513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES); CHKERRQ(ierr); 17040513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork); CHKERRQ(ierr); 17050513a670SBarry Smith } 17060513a670SBarry Smith PetscFree(cnew); 17070513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 17080513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 170956cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row); CHKERRQ(ierr); 171056cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col); CHKERRQ(ierr); 171156cd22aeSBarry Smith ierr = ISDestroy(irowp); CHKERRQ(ierr); 171256cd22aeSBarry Smith ierr = ISDestroy(icolp); CHKERRQ(ierr); 17133a40ed3dSBarry Smith PetscFunctionReturn(0); 17140513a670SBarry Smith } 17150513a670SBarry Smith 17165615d1e5SSatish Balay #undef __FUNC__ 17175615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ" 1718682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1719682d7d0cSBarry Smith { 1720682d7d0cSBarry Smith static int called = 0; 1721682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1722682d7d0cSBarry Smith 17233a40ed3dSBarry Smith PetscFunctionBegin; 17243a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 172576be9ce4SBarry Smith (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n"); 172676be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n"); 172776be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n"); 172876be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n"); 172976be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n"); 1730682d7d0cSBarry Smith #if defined(HAVE_ESSL) 173176be9ce4SBarry Smith (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n"); 1732682d7d0cSBarry Smith #endif 17333a40ed3dSBarry Smith PetscFunctionReturn(0); 1734682d7d0cSBarry Smith } 17358f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg); 1736a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1737a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 1738a93ec695SBarry Smith 1739cb5b572fSBarry Smith #undef __FUNC__ 1740cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ" 1741cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1742cb5b572fSBarry Smith { 1743be6bf707SBarry Smith int ierr; 1744cb5b572fSBarry Smith 1745cb5b572fSBarry Smith PetscFunctionBegin; 1746be6bf707SBarry Smith if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) { 1747be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1748be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data; 1749be6bf707SBarry Smith 1750be6bf707SBarry Smith if (a->nonew != 1) SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 1751be6bf707SBarry Smith if (b->nonew != 1) SETERRQ(1,1,"Must call MatSetOption(B,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 1752be6bf707SBarry Smith if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) { 1753be6bf707SBarry Smith SETERRQ(1,1,"Number of nonzeros in two matrices are different"); 1754cb5b572fSBarry Smith } 1755be6bf707SBarry Smith PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar)); 1756cb5b572fSBarry Smith } else { 1757cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1758cb5b572fSBarry Smith } 1759cb5b572fSBarry Smith PetscFunctionReturn(0); 1760cb5b572fSBarry Smith } 1761cb5b572fSBarry Smith 1762682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 17630a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 1764cb5b572fSBarry Smith MatGetRow_SeqAIJ, 1765cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 1766cb5b572fSBarry Smith MatMult_SeqAIJ, 1767cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 1768cb5b572fSBarry Smith MatMultTrans_SeqAIJ, 1769cb5b572fSBarry Smith MatMultTransAdd_SeqAIJ, 1770cb5b572fSBarry Smith MatSolve_SeqAIJ, 1771cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 1772cb5b572fSBarry Smith MatSolveTrans_SeqAIJ, 1773cb5b572fSBarry Smith MatSolveTransAdd_SeqAIJ, 1774cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 1775cb5b572fSBarry Smith 0, 177617ab2063SBarry Smith MatRelax_SeqAIJ, 177717ab2063SBarry Smith MatTranspose_SeqAIJ, 1778cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 1779cb5b572fSBarry Smith MatEqual_SeqAIJ, 1780cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 1781cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 1782cb5b572fSBarry Smith MatNorm_SeqAIJ, 1783cb5b572fSBarry Smith 0, 1784cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 178517ab2063SBarry Smith MatCompress_SeqAIJ, 1786cb5b572fSBarry Smith MatSetOption_SeqAIJ, 1787cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 1788cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 1789cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 1790cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 1791cb5b572fSBarry Smith 0, 1792cb5b572fSBarry Smith 0, 1793cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1794cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1795cb5b572fSBarry Smith MatGetOwnershipRange_SeqAIJ, 1796cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 1797cb5b572fSBarry Smith 0, 1798cb5b572fSBarry Smith 0, 1799cb5b572fSBarry Smith 0, 1800be6bf707SBarry Smith MatDuplicate_SeqAIJ, 1801cb5b572fSBarry Smith 0, 1802cb5b572fSBarry Smith 0, 1803cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 1804cb5b572fSBarry Smith 0, 1805cb5b572fSBarry Smith 0, 1806cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 1807cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 1808cb5b572fSBarry Smith MatGetValues_SeqAIJ, 1809cb5b572fSBarry Smith MatCopy_SeqAIJ, 1810f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 1811cb5b572fSBarry Smith MatScale_SeqAIJ, 1812cb5b572fSBarry Smith 0, 1813cb5b572fSBarry Smith 0, 18146945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 18156945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 18163b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 18173b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 18183b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 1819a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 1820a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 18210513a670SBarry Smith MatColoringPatch_SeqAIJ, 18220513a670SBarry Smith 0, 1823cda55fadSBarry Smith MatPermute_SeqAIJ, 1824cda55fadSBarry Smith 0, 1825cda55fadSBarry Smith 0, 1826cda55fadSBarry Smith 0, 1827cda55fadSBarry Smith 0, 1828cda55fadSBarry Smith MatGetMaps_Petsc}; 182917ab2063SBarry Smith 183017ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 183117ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 183217ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 183317ab2063SBarry Smith 1834fb2e594dSBarry Smith EXTERN_C_BEGIN 18355615d1e5SSatish Balay #undef __FUNC__ 1836bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ" 1837bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 1838bef8e0ddSBarry Smith { 1839bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1840bef8e0ddSBarry Smith int i,nz,n; 1841bef8e0ddSBarry Smith 1842bef8e0ddSBarry Smith PetscFunctionBegin; 1843bef8e0ddSBarry Smith if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing"); 1844bef8e0ddSBarry Smith 1845bef8e0ddSBarry Smith nz = aij->maxnz; 1846bef8e0ddSBarry Smith n = aij->n; 1847bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 1848bef8e0ddSBarry Smith aij->j[i] = indices[i]; 1849bef8e0ddSBarry Smith } 1850bef8e0ddSBarry Smith aij->nz = nz; 1851bef8e0ddSBarry Smith for ( i=0; i<n; i++ ) { 1852bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 1853bef8e0ddSBarry Smith } 1854bef8e0ddSBarry Smith 1855bef8e0ddSBarry Smith PetscFunctionReturn(0); 1856bef8e0ddSBarry Smith } 1857fb2e594dSBarry Smith EXTERN_C_END 1858bef8e0ddSBarry Smith 1859bef8e0ddSBarry Smith #undef __FUNC__ 1860bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices" 1861bef8e0ddSBarry Smith /*@ 1862bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 1863bef8e0ddSBarry Smith in the matrix. 1864bef8e0ddSBarry Smith 1865bef8e0ddSBarry Smith Input Parameters: 1866bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 1867bef8e0ddSBarry Smith - indices - the column indices 1868bef8e0ddSBarry Smith 1869bef8e0ddSBarry Smith Notes: 1870bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 1871bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 1872bef8e0ddSBarry Smith of the MatSetValues() operation. 1873bef8e0ddSBarry Smith 1874bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 1875bef8e0ddSBarry Smith MatCreateSeqAIJ(). 1876bef8e0ddSBarry Smith 1877bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 1878bef8e0ddSBarry Smith 1879bef8e0ddSBarry Smith @*/ 1880bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 1881bef8e0ddSBarry Smith { 1882bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 1883bef8e0ddSBarry Smith 1884bef8e0ddSBarry Smith PetscFunctionBegin; 1885bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1886bef8e0ddSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f); 1887bef8e0ddSBarry Smith CHKERRQ(ierr); 1888bef8e0ddSBarry Smith if (f) { 1889bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 1890bef8e0ddSBarry Smith } else { 1891bef8e0ddSBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 1892bef8e0ddSBarry Smith } 1893bef8e0ddSBarry Smith PetscFunctionReturn(0); 1894bef8e0ddSBarry Smith } 1895bef8e0ddSBarry Smith 1896be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 1897be6bf707SBarry Smith 1898fb2e594dSBarry Smith EXTERN_C_BEGIN 1899be6bf707SBarry Smith #undef __FUNC__ 1900be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ" 1901be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 1902be6bf707SBarry Smith { 1903be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1904be6bf707SBarry Smith int nz = aij->i[aij->m]+aij->indexshift; 1905be6bf707SBarry Smith 1906be6bf707SBarry Smith PetscFunctionBegin; 1907be6bf707SBarry Smith if (aij->nonew != 1) { 1908be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 1909be6bf707SBarry Smith } 1910be6bf707SBarry Smith 1911be6bf707SBarry Smith /* allocate space for values if not already there */ 1912be6bf707SBarry Smith if (!aij->saved_values) { 1913be6bf707SBarry Smith aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values); 1914be6bf707SBarry Smith } 1915be6bf707SBarry Smith 1916be6bf707SBarry Smith /* copy values over */ 1917be6bf707SBarry Smith PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar)); 1918be6bf707SBarry Smith PetscFunctionReturn(0); 1919be6bf707SBarry Smith } 1920fb2e594dSBarry Smith EXTERN_C_END 1921be6bf707SBarry Smith 1922be6bf707SBarry Smith #undef __FUNC__ 1923be6bf707SBarry Smith #define __FUNC__ "MatStoreValues" 1924be6bf707SBarry Smith /*@ 1925be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 1926be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 1927be6bf707SBarry Smith nonlinear portion. 1928be6bf707SBarry Smith 1929be6bf707SBarry Smith Collect on Mat 1930be6bf707SBarry Smith 1931be6bf707SBarry Smith Input Parameters: 1932be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 1933be6bf707SBarry Smith 1934be6bf707SBarry Smith Common Usage, with SNESSolve(): 1935be6bf707SBarry Smith $ Create Jacobian matrix 1936be6bf707SBarry Smith $ Set linear terms into matrix 1937be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 1938be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 1939be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 1940be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 1941be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 1942be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 1943be6bf707SBarry Smith $ In your Jacobian routine 1944be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 1945be6bf707SBarry Smith $ Set nonlinear terms in matrix 1946be6bf707SBarry Smith 1947be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 1948be6bf707SBarry Smith $ // build linear portion of Jacobian 1949be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 1950be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 1951be6bf707SBarry Smith $ loop over nonlinear iterations 1952be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 1953be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 1954be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 1955be6bf707SBarry Smith $ Solve linear system with Jacobian 1956be6bf707SBarry Smith $ endloop 1957be6bf707SBarry Smith 1958be6bf707SBarry Smith Notes: 1959be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 1960be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 1961be6bf707SBarry Smith calling this routine. 1962be6bf707SBarry Smith 1963be6bf707SBarry Smith .seealso: MatRetrieveValues() 1964be6bf707SBarry Smith 1965be6bf707SBarry Smith @*/ 1966be6bf707SBarry Smith int MatStoreValues(Mat mat) 1967be6bf707SBarry Smith { 1968be6bf707SBarry Smith int ierr,(*f)(Mat); 1969be6bf707SBarry Smith 1970be6bf707SBarry Smith PetscFunctionBegin; 1971be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1972be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 1973be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 1974be6bf707SBarry Smith 1975be6bf707SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f); 1976be6bf707SBarry Smith CHKERRQ(ierr); 1977be6bf707SBarry Smith if (f) { 1978be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 1979be6bf707SBarry Smith } else { 1980be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to store values"); 1981be6bf707SBarry Smith } 1982be6bf707SBarry Smith PetscFunctionReturn(0); 1983be6bf707SBarry Smith } 1984be6bf707SBarry Smith 1985fb2e594dSBarry Smith EXTERN_C_BEGIN 1986be6bf707SBarry Smith #undef __FUNC__ 1987be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ" 1988be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 1989be6bf707SBarry Smith { 1990be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1991be6bf707SBarry Smith int nz = aij->i[aij->m]+aij->indexshift; 1992be6bf707SBarry Smith 1993be6bf707SBarry Smith PetscFunctionBegin; 1994be6bf707SBarry Smith if (aij->nonew != 1) { 1995be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 1996be6bf707SBarry Smith } 1997be6bf707SBarry Smith if (!aij->saved_values) { 1998be6bf707SBarry Smith SETERRQ(1,1,"Must call MatStoreValues(A);first"); 1999be6bf707SBarry Smith } 2000be6bf707SBarry Smith 2001be6bf707SBarry Smith /* copy values over */ 2002be6bf707SBarry Smith PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar)); 2003be6bf707SBarry Smith PetscFunctionReturn(0); 2004be6bf707SBarry Smith } 2005fb2e594dSBarry Smith EXTERN_C_END 2006be6bf707SBarry Smith 2007be6bf707SBarry Smith #undef __FUNC__ 2008be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues" 2009be6bf707SBarry Smith /*@ 2010be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2011be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2012be6bf707SBarry Smith nonlinear portion. 2013be6bf707SBarry Smith 2014be6bf707SBarry Smith Collect on Mat 2015be6bf707SBarry Smith 2016be6bf707SBarry Smith Input Parameters: 2017be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2018be6bf707SBarry Smith 2019be6bf707SBarry Smith .seealso: MatStoreValues() 2020be6bf707SBarry Smith 2021be6bf707SBarry Smith @*/ 2022be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2023be6bf707SBarry Smith { 2024be6bf707SBarry Smith int ierr,(*f)(Mat); 2025be6bf707SBarry Smith 2026be6bf707SBarry Smith PetscFunctionBegin; 2027be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2028be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2029be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2030be6bf707SBarry Smith 2031be6bf707SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f); 2032be6bf707SBarry Smith CHKERRQ(ierr); 2033be6bf707SBarry Smith if (f) { 2034be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2035be6bf707SBarry Smith } else { 2036be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to retrieve values"); 2037be6bf707SBarry Smith } 2038be6bf707SBarry Smith PetscFunctionReturn(0); 2039be6bf707SBarry Smith } 2040be6bf707SBarry Smith 2041be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 2042cb5b572fSBarry Smith 2043bef8e0ddSBarry Smith #undef __FUNC__ 20445615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ" 204517ab2063SBarry Smith /*@C 2046682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 20470d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 20486e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 20492bd5e0b2SLois Curfman McInnes (or the array nzz). By setting these parameters accurately, performance 20502bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 205117ab2063SBarry Smith 2052db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2053db81eaa0SLois Curfman McInnes 205417ab2063SBarry Smith Input Parameters: 2055db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 205617ab2063SBarry Smith . m - number of rows 205717ab2063SBarry Smith . n - number of columns 205817ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 2059db81eaa0SLois Curfman McInnes - nzz - array containing the number of nonzeros in the various rows 20602bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 206117ab2063SBarry Smith 206217ab2063SBarry Smith Output Parameter: 2063416022c9SBarry Smith . A - the matrix 206417ab2063SBarry Smith 2065b259b22eSLois Curfman McInnes Notes: 206617ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 206717ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 20680002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 206944cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 207017ab2063SBarry Smith 207117ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2072a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 20733d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 20746da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 207517ab2063SBarry Smith 2076682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 20774fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2078682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 20796c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 20806c7ebb05SLois Curfman McInnes 20816c7ebb05SLois Curfman McInnes Options Database Keys: 2082db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2083db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2084db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2085db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2086db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 208717ab2063SBarry Smith 2088bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices() 208917ab2063SBarry Smith @*/ 2090416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A) 209117ab2063SBarry Smith { 2092416022c9SBarry Smith Mat B; 2093416022c9SBarry Smith Mat_SeqAIJ *b; 20946945ee14SBarry Smith int i, len, ierr, flg,size; 20956945ee14SBarry Smith 20963a40ed3dSBarry Smith PetscFunctionBegin; 20976945ee14SBarry Smith MPI_Comm_size(comm,&size); 2098a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1"); 2099d5d45c9bSBarry Smith 2100416022c9SBarry Smith *A = 0; 2101f830108cSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,comm,MatDestroy,MatView); 2102416022c9SBarry Smith PLogObjectCreate(B); 21030452661fSBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqAIJ)); CHKPTRQ(b); 210444cd7ae7SLois Curfman McInnes PetscMemzero(b,sizeof(Mat_SeqAIJ)); 21050a6ffc59SBarry Smith PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)); 2106e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqAIJ; 2107e1311b90SBarry Smith B->ops->view = MatView_SeqAIJ; 2108416022c9SBarry Smith B->factor = 0; 2109416022c9SBarry Smith B->lupivotthreshold = 1.0; 211090f02eecSBarry Smith B->mapping = 0; 2111e1311b90SBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,&flg);CHKERRQ(ierr); 21127a743949SBarry Smith b->ilu_preserve_row_sums = PETSC_FALSE; 2113e1311b90SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",(int*)&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2114416022c9SBarry Smith b->row = 0; 2115416022c9SBarry Smith b->col = 0; 211682bf6240SBarry Smith b->icol = 0; 2117416022c9SBarry Smith b->indexshift = 0; 2118b810aeb4SBarry Smith b->reallocs = 0; 211969957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg); CHKERRQ(ierr); 212069957df2SSatish Balay if (flg) b->indexshift = -1; 212117ab2063SBarry Smith 212244cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 212344cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 2124a5ae1ecdSBarry Smith 21254d197716SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 21264d197716SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 2127a5ae1ecdSBarry Smith 21280452661fSBarry Smith b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(b->imax); 2129b4fd4287SBarry Smith if (nnz == PETSC_NULL) { 21307b8455f0SLois Curfman McInnes if (nz == PETSC_DEFAULT) nz = 10; 21317b8455f0SLois Curfman McInnes else if (nz <= 0) nz = 1; 2132416022c9SBarry Smith for ( i=0; i<m; i++ ) b->imax[i] = nz; 213317ab2063SBarry Smith nz = nz*m; 21343a40ed3dSBarry Smith } else { 213517ab2063SBarry Smith nz = 0; 2136416022c9SBarry Smith for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 213717ab2063SBarry Smith } 213817ab2063SBarry Smith 213917ab2063SBarry Smith /* allocate the matrix space */ 2140416022c9SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 21410452661fSBarry Smith b->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(b->a); 2142416022c9SBarry Smith b->j = (int *) (b->a + nz); 2143cddf8d76SBarry Smith PetscMemzero(b->j,nz*sizeof(int)); 2144416022c9SBarry Smith b->i = b->j + nz; 2145416022c9SBarry Smith b->singlemalloc = 1; 214617ab2063SBarry Smith 2147416022c9SBarry Smith b->i[0] = -b->indexshift; 214817ab2063SBarry Smith for (i=1; i<m+1; i++) { 2149416022c9SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 215017ab2063SBarry Smith } 215117ab2063SBarry Smith 2152416022c9SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 21530452661fSBarry Smith b->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); 2154f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2155416022c9SBarry Smith for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;} 215617ab2063SBarry Smith 2157416022c9SBarry Smith b->nz = 0; 2158416022c9SBarry Smith b->maxnz = nz; 2159416022c9SBarry Smith b->sorted = 0; 2160416022c9SBarry Smith b->roworiented = 1; 2161416022c9SBarry Smith b->nonew = 0; 2162416022c9SBarry Smith b->diag = 0; 2163416022c9SBarry Smith b->solve_work = 0; 216471bd300dSLois Curfman McInnes b->spptr = 0; 2165754ec7b1SSatish Balay b->inode.node_count = 0; 2166754ec7b1SSatish Balay b->inode.size = 0; 21676c7ebb05SLois Curfman McInnes b->inode.limit = 5; 21686c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2169be6bf707SBarry Smith b->saved_values = 0; 21704e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 217117ab2063SBarry Smith 2172416022c9SBarry Smith *A = B; 21734e220ebcSLois Curfman McInnes 21744b14c69eSBarry Smith /* SuperLU is not currently supported through PETSc */ 21754b14c69eSBarry Smith #if defined(HAVE_SUPERLU) 217669957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg); CHKERRQ(ierr); 217769957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B); CHKERRQ(ierr); } 21784b14c69eSBarry Smith #endif 217969957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg); CHKERRQ(ierr); 218069957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B); CHKERRQ(ierr); } 218169957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg); CHKERRQ(ierr); 218269957df2SSatish Balay if (flg) { 2183a8c6a408SBarry Smith if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml"); 2184416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B); CHKERRQ(ierr); 218517ab2063SBarry Smith } 218669957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 218769957df2SSatish Balay if (flg) {ierr = MatPrintHelp(B); CHKERRQ(ierr); } 2188bef8e0ddSBarry Smith 2189bef8e0ddSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2190bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2191bef8e0ddSBarry Smith (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2192be6bf707SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C", 2193be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2194be6bf707SBarry Smith (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2195be6bf707SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C", 2196be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2197be6bf707SBarry Smith (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 21983a40ed3dSBarry Smith PetscFunctionReturn(0); 219917ab2063SBarry Smith } 220017ab2063SBarry Smith 22015615d1e5SSatish Balay #undef __FUNC__ 2202be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ" 2203be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 220417ab2063SBarry Smith { 2205416022c9SBarry Smith Mat C; 2206416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data; 2207bef8e0ddSBarry Smith int i,len, m = a->m,shift = a->indexshift,ierr; 220817ab2063SBarry Smith 22093a40ed3dSBarry Smith PetscFunctionBegin; 22104043dd9cSLois Curfman McInnes *B = 0; 2211f830108cSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,A->comm,MatDestroy,MatView); 2212416022c9SBarry Smith PLogObjectCreate(C); 22130452661fSBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqAIJ)); CHKPTRQ(c); 2214f830108cSBarry Smith PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps)); 2215e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqAIJ; 2216e1311b90SBarry Smith C->ops->view = MatView_SeqAIJ; 2217416022c9SBarry Smith C->factor = A->factor; 2218416022c9SBarry Smith c->row = 0; 2219416022c9SBarry Smith c->col = 0; 222082bf6240SBarry Smith c->icol = 0; 2221416022c9SBarry Smith c->indexshift = shift; 2222c456f294SBarry Smith C->assembled = PETSC_TRUE; 222317ab2063SBarry Smith 222444cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 222544cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 222644cd7ae7SLois Curfman McInnes C->M = a->m; 222744cd7ae7SLois Curfman McInnes C->N = a->n; 222817ab2063SBarry Smith 22290452661fSBarry Smith c->imax = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->imax); 22300452661fSBarry Smith c->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); CHKPTRQ(c->ilen); 223117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 2232416022c9SBarry Smith c->imax[i] = a->imax[i]; 2233416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 223417ab2063SBarry Smith } 223517ab2063SBarry Smith 223617ab2063SBarry Smith /* allocate the matrix space */ 2237416022c9SBarry Smith c->singlemalloc = 1; 2238416022c9SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 22390452661fSBarry Smith c->a = (Scalar *) PetscMalloc( len ); CHKPTRQ(c->a); 2240416022c9SBarry Smith c->j = (int *) (c->a + a->i[m] + shift); 2241416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 2242416022c9SBarry Smith PetscMemcpy(c->i,a->i,(m+1)*sizeof(int)); 224317ab2063SBarry Smith if (m > 0) { 2244416022c9SBarry Smith PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int)); 2245be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2246416022c9SBarry Smith PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar)); 2247be6bf707SBarry Smith } else { 2248be6bf707SBarry Smith PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar)); 224917ab2063SBarry Smith } 225008480c60SBarry Smith } 225117ab2063SBarry Smith 2252f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2253416022c9SBarry Smith c->sorted = a->sorted; 2254416022c9SBarry Smith c->roworiented = a->roworiented; 2255416022c9SBarry Smith c->nonew = a->nonew; 22567a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2257be6bf707SBarry Smith c->saved_values = 0; 225817ab2063SBarry Smith 2259416022c9SBarry Smith if (a->diag) { 22600452661fSBarry Smith c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->diag); 2261416022c9SBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 226217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 2263416022c9SBarry Smith c->diag[i] = a->diag[i]; 226417ab2063SBarry Smith } 22653a40ed3dSBarry Smith } else c->diag = 0; 22666c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 22676c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2268754ec7b1SSatish Balay if (a->inode.size){ 2269daed632aSSatish Balay c->inode.size = (int *) PetscMalloc( (m+1)*sizeof(int) ); CHKPTRQ(c->inode.size); 2270754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2271daed632aSSatish Balay PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int)); 2272754ec7b1SSatish Balay } else { 2273754ec7b1SSatish Balay c->inode.size = 0; 2274754ec7b1SSatish Balay c->inode.node_count = 0; 2275754ec7b1SSatish Balay } 2276416022c9SBarry Smith c->nz = a->nz; 2277416022c9SBarry Smith c->maxnz = a->maxnz; 2278416022c9SBarry Smith c->solve_work = 0; 227976dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2280754ec7b1SSatish Balay 2281416022c9SBarry Smith *B = C; 2282bef8e0ddSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)C,"MatSeqAIJSetColumnIndices_C", 2283bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2284bef8e0ddSBarry Smith (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 22853a40ed3dSBarry Smith PetscFunctionReturn(0); 228617ab2063SBarry Smith } 228717ab2063SBarry Smith 22885615d1e5SSatish Balay #undef __FUNC__ 22895615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ" 229019bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 229117ab2063SBarry Smith { 2292416022c9SBarry Smith Mat_SeqAIJ *a; 2293416022c9SBarry Smith Mat B; 229417699dbbSLois Curfman McInnes int i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift; 2295bcd2baecSBarry Smith MPI_Comm comm; 229617ab2063SBarry Smith 22973a40ed3dSBarry Smith PetscFunctionBegin; 229819bcc07fSBarry Smith PetscObjectGetComm((PetscObject) viewer,&comm); 229917699dbbSLois Curfman McInnes MPI_Comm_size(comm,&size); 2300a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor"); 230190ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd); CHKERRQ(ierr); 23020752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT); CHKERRQ(ierr); 2303a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file"); 230417ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 230517ab2063SBarry Smith 2306d64ed03dSBarry Smith if (nz < 0) { 2307a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 2308d64ed03dSBarry Smith } 2309d64ed03dSBarry Smith 231017ab2063SBarry Smith /* read in row lengths */ 23110452661fSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) ); CHKPTRQ(rowlengths); 23120752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT); CHKERRQ(ierr); 231317ab2063SBarry Smith 231417ab2063SBarry Smith /* create our matrix */ 2315416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A); CHKERRQ(ierr); 2316416022c9SBarry Smith B = *A; 2317416022c9SBarry Smith a = (Mat_SeqAIJ *) B->data; 2318416022c9SBarry Smith shift = a->indexshift; 231917ab2063SBarry Smith 232017ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 23210752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT); CHKERRQ(ierr); 232217ab2063SBarry Smith if (shift) { 232317ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 2324416022c9SBarry Smith a->j[i] += 1; 232517ab2063SBarry Smith } 232617ab2063SBarry Smith } 232717ab2063SBarry Smith 232817ab2063SBarry Smith /* read in nonzero values */ 23290752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR); CHKERRQ(ierr); 233017ab2063SBarry Smith 233117ab2063SBarry Smith /* set matrix "i" values */ 2332416022c9SBarry Smith a->i[0] = -shift; 233317ab2063SBarry Smith for ( i=1; i<= M; i++ ) { 2334416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2335416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 233617ab2063SBarry Smith } 23370452661fSBarry Smith PetscFree(rowlengths); 233817ab2063SBarry Smith 23396d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 23406d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY); CHKERRQ(ierr); 23413a40ed3dSBarry Smith PetscFunctionReturn(0); 234217ab2063SBarry Smith } 234317ab2063SBarry Smith 23445615d1e5SSatish Balay #undef __FUNC__ 23455615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ" 23468f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg) 23477264ac53SSatish Balay { 23487264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data; 23497264ac53SSatish Balay 23503a40ed3dSBarry Smith PetscFunctionBegin; 2351a8c6a408SBarry Smith if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 23527264ac53SSatish Balay 23537264ac53SSatish Balay /* If the matrix dimensions are not equal, or no of nonzeros or shift */ 23547264ac53SSatish Balay if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)|| 2355bcd2baecSBarry Smith (a->indexshift != b->indexshift)) { 23563a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 2357bcd2baecSBarry Smith } 23587264ac53SSatish Balay 23597264ac53SSatish Balay /* if the a->i are the same */ 23608108c231SLois Curfman McInnes if (PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int))) { 23613a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 23627264ac53SSatish Balay } 23637264ac53SSatish Balay 23647264ac53SSatish Balay /* if a->j are the same */ 2365bcd2baecSBarry Smith if (PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int))) { 23663a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 2367bcd2baecSBarry Smith } 2368bcd2baecSBarry Smith 2369bcd2baecSBarry Smith /* if a->a are the same */ 237019bcc07fSBarry Smith if (PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar))) { 23713a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 23727264ac53SSatish Balay } 237377c4ece6SBarry Smith *flg = PETSC_TRUE; 23743a40ed3dSBarry Smith PetscFunctionReturn(0); 23757264ac53SSatish Balay 23767264ac53SSatish Balay } 2377