1a5eb4965SSatish Balay #ifdef PETSC_RCS_HEADER 2*6831982aSBarry Smith static char vcid[] = "$Id: aij.c,v 1.329 1999/10/13 20:37:19 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 263a40ed3dSBarry Smith PetscFunctionBegin; 273f1db9ecSBarry Smith SETERRQ(1,0,"Not implemented"); 28aa482453SBarry Smith #if !defined(PETSC_USE_DEBUG) 29d64ed03dSBarry Smith PetscFunctionReturn(0); 30d64ed03dSBarry Smith #endif 31a2ce50c7SBarry Smith } 32a2ce50c7SBarry Smith 33bcd2baecSBarry Smith extern int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 3417ab2063SBarry Smith 355615d1e5SSatish Balay #undef __FUNC__ 365615d1e5SSatish Balay #define __FUNC__ "MatGetRowIJ_SeqAIJ" 378f6be9afSLois Curfman McInnes int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int **ia,int **ja, 386945ee14SBarry Smith PetscTruth *done) 3917ab2063SBarry Smith { 40416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 416945ee14SBarry Smith int ierr,i,ishift; 4217ab2063SBarry Smith 433a40ed3dSBarry Smith PetscFunctionBegin; 4431625ec5SSatish Balay *m = A->m; 453a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 466945ee14SBarry Smith ishift = a->indexshift; 476945ee14SBarry Smith if (symmetric) { 4831625ec5SSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 496945ee14SBarry Smith } else if (oshift == 0 && ishift == -1) { 5031625ec5SSatish Balay int nz = a->i[a->m]; 513b2fbd54SBarry Smith /* malloc space and subtract 1 from i and j indices */ 5231625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia); 533b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja); 543b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] - 1; 5531625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] - 1; 566945ee14SBarry Smith } else if (oshift == 1 && ishift == 0) { 5731625ec5SSatish Balay int nz = a->i[a->m] + 1; 583b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 5931625ec5SSatish Balay *ia = (int *) PetscMalloc( (a->m+1)*sizeof(int) );CHKPTRQ(*ia); 603b2fbd54SBarry Smith *ja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(*ja); 613b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) (*ja)[i] = a->j[i] + 1; 6231625ec5SSatish Balay for ( i=0; i<a->m+1; i++ ) (*ia)[i] = a->i[i] + 1; 636945ee14SBarry Smith } else { 646945ee14SBarry Smith *ia = a->i; *ja = a->j; 65a2ce50c7SBarry Smith } 66a2ce50c7SBarry Smith 673a40ed3dSBarry Smith PetscFunctionReturn(0); 68a2744918SBarry Smith } 69a2744918SBarry Smith 705615d1e5SSatish Balay #undef __FUNC__ 715615d1e5SSatish Balay #define __FUNC__ "MatRestoreRowIJ_SeqAIJ" 728f6be9afSLois Curfman McInnes int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia,int **ja, 736945ee14SBarry Smith PetscTruth *done) 746945ee14SBarry Smith { 756945ee14SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 76606d414cSSatish Balay int ishift = a->indexshift,ierr; 776945ee14SBarry Smith 783a40ed3dSBarry Smith PetscFunctionBegin; 793a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 803b2fbd54SBarry Smith if (symmetric || (oshift == 0 && ishift == -1) || (oshift == 1 && ishift == 0)) { 81606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 82606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 83bcd2baecSBarry Smith } 843a40ed3dSBarry Smith PetscFunctionReturn(0); 8517ab2063SBarry Smith } 8617ab2063SBarry Smith 875615d1e5SSatish Balay #undef __FUNC__ 885615d1e5SSatish Balay #define __FUNC__ "MatGetColumnIJ_SeqAIJ" 8943a90d84SBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int **ia,int **ja, 903b2fbd54SBarry Smith PetscTruth *done) 913b2fbd54SBarry Smith { 923b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 93a93ec695SBarry Smith int ierr,i,ishift = a->indexshift,*collengths,*cia,*cja,n = A->n,m = A->m; 94a93ec695SBarry Smith int nz = a->i[m]+ishift,row,*jj,mr,col; 953b2fbd54SBarry Smith 963a40ed3dSBarry Smith PetscFunctionBegin; 973b2fbd54SBarry Smith *nn = A->n; 983a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 993b2fbd54SBarry Smith if (symmetric) { 100179192dfSSatish Balay ierr = MatToSymmetricIJ_SeqAIJ(a->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 1013b2fbd54SBarry Smith } else { 10261d2ded1SBarry Smith collengths = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(collengths); 103549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 1043b2fbd54SBarry Smith cia = (int *) PetscMalloc( (n+1)*sizeof(int) );CHKPTRQ(cia); 105a93ec695SBarry Smith cja = (int *) PetscMalloc( (nz+1)*sizeof(int) );CHKPTRQ(cja); 1063b2fbd54SBarry Smith jj = a->j; 1073b2fbd54SBarry Smith for ( i=0; i<nz; i++ ) { 1083b2fbd54SBarry Smith collengths[jj[i] + ishift]++; 1093b2fbd54SBarry Smith } 1103b2fbd54SBarry Smith cia[0] = oshift; 1113b2fbd54SBarry Smith for ( i=0; i<n; i++) { 1123b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 1133b2fbd54SBarry Smith } 114549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 1153b2fbd54SBarry Smith jj = a->j; 116a93ec695SBarry Smith for ( row=0; row<m; row++ ) { 117a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 118a93ec695SBarry Smith for ( i=0; i<mr; i++ ) { 1193b2fbd54SBarry Smith col = *jj++ + ishift; 1203b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 1213b2fbd54SBarry Smith } 1223b2fbd54SBarry Smith } 123606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 1243b2fbd54SBarry Smith *ia = cia; *ja = cja; 1253b2fbd54SBarry Smith } 1263b2fbd54SBarry Smith 1273a40ed3dSBarry Smith PetscFunctionReturn(0); 1283b2fbd54SBarry Smith } 1293b2fbd54SBarry Smith 1305615d1e5SSatish Balay #undef __FUNC__ 1315615d1e5SSatish Balay #define __FUNC__ "MatRestoreColumnIJ_SeqAIJ" 13243a90d84SBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int **ia, 1333b2fbd54SBarry Smith int **ja,PetscTruth *done) 1343b2fbd54SBarry Smith { 135606d414cSSatish Balay int ierr; 136606d414cSSatish Balay 1373a40ed3dSBarry Smith PetscFunctionBegin; 1383a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1393b2fbd54SBarry Smith 140606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 141606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1423b2fbd54SBarry Smith 1433a40ed3dSBarry Smith PetscFunctionReturn(0); 1443b2fbd54SBarry Smith } 1453b2fbd54SBarry Smith 146227d817aSBarry Smith #define CHUNKSIZE 15 14717ab2063SBarry Smith 1485615d1e5SSatish Balay #undef __FUNC__ 1495615d1e5SSatish Balay #define __FUNC__ "MatSetValues_SeqAIJ" 15061d2ded1SBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v,InsertMode is) 15117ab2063SBarry Smith { 152416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 153416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax, N, sorted = a->sorted; 1544b0e389bSBarry Smith int *imax = a->imax, *ai = a->i, *ailen = a->ilen,roworiented = a->roworiented; 155549d3d68SSatish Balay int *aj = a->j, nonew = a->nonew,shift = a->indexshift,ierr; 156416022c9SBarry Smith Scalar *ap,value, *aa = a->a; 15717ab2063SBarry Smith 1583a40ed3dSBarry Smith PetscFunctionBegin; 15917ab2063SBarry Smith for ( k=0; k<m; k++ ) { /* loop over added rows */ 160416022c9SBarry Smith row = im[k]; 1615ef9f2a5SBarry Smith if (row < 0) continue; 162aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 16332e87ba3SBarry Smith if (row >= a->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large: row %d max %d",row,a->m); 1643b2fbd54SBarry Smith #endif 16517ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 16617ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 167416022c9SBarry Smith low = 0; 16817ab2063SBarry Smith for ( l=0; l<n; l++ ) { /* loop over added columns */ 1695ef9f2a5SBarry Smith if (in[l] < 0) continue; 170aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 17132e87ba3SBarry Smith if (in[l] >= a->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large: col %d max %d",in[l],a->n); 1723b2fbd54SBarry Smith #endif 1734b0e389bSBarry Smith col = in[l] - shift; 1744b0e389bSBarry Smith if (roworiented) { 1755ef9f2a5SBarry Smith value = v[l + k*n]; 176bef8e0ddSBarry Smith } else { 1774b0e389bSBarry Smith value = v[k + l*m]; 1784b0e389bSBarry Smith } 179416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 180416022c9SBarry Smith while (high-low > 5) { 181416022c9SBarry Smith t = (low+high)/2; 182416022c9SBarry Smith if (rp[t] > col) high = t; 183416022c9SBarry Smith else low = t; 18417ab2063SBarry Smith } 185416022c9SBarry Smith for ( i=low; i<high; i++ ) { 18617ab2063SBarry Smith if (rp[i] > col) break; 18717ab2063SBarry Smith if (rp[i] == col) { 188416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 18917ab2063SBarry Smith else ap[i] = value; 19017ab2063SBarry Smith goto noinsert; 19117ab2063SBarry Smith } 19217ab2063SBarry Smith } 193c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 194a8c6a408SBarry Smith else if (nonew == -1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 19517ab2063SBarry Smith if (nrow >= rmax) { 19617ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 197416022c9SBarry Smith int new_nz = ai[a->m] + CHUNKSIZE,len,*new_i,*new_j; 19817ab2063SBarry Smith Scalar *new_a; 19917ab2063SBarry Smith 200a8c6a408SBarry Smith if (nonew == -2) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Inserting a new nonzero in the matrix"); 20196854ed6SLois Curfman McInnes 20217ab2063SBarry Smith /* malloc new storage space */ 203416022c9SBarry Smith len = new_nz*(sizeof(int)+sizeof(Scalar))+(a->m+1)*sizeof(int); 2040452661fSBarry Smith new_a = (Scalar *) PetscMalloc( len );CHKPTRQ(new_a); 20517ab2063SBarry Smith new_j = (int *) (new_a + new_nz); 20617ab2063SBarry Smith new_i = new_j + new_nz; 20717ab2063SBarry Smith 20817ab2063SBarry Smith /* copy over old data into new slots */ 20917ab2063SBarry Smith for ( ii=0; ii<row+1; ii++ ) {new_i[ii] = ai[ii];} 210416022c9SBarry Smith for ( ii=row+1; ii<a->m+1; ii++ ) {new_i[ii] = ai[ii]+CHUNKSIZE;} 211549d3d68SSatish Balay ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow+shift)*sizeof(int));CHKERRQ(ierr); 212416022c9SBarry Smith len = (new_nz - CHUNKSIZE - ai[row] - nrow - shift); 213549d3d68SSatish Balay ierr = PetscMemcpy(new_j+ai[row]+shift+nrow+CHUNKSIZE,aj+ai[row]+shift+nrow,len*sizeof(int));CHKERRQ(ierr); 214549d3d68SSatish Balay ierr = PetscMemcpy(new_a,aa,(ai[row]+nrow+shift)*sizeof(Scalar));CHKERRQ(ierr); 215549d3d68SSatish Balay ierr = PetscMemcpy(new_a+ai[row]+shift+nrow+CHUNKSIZE,aa+ai[row]+shift+nrow,len*sizeof(Scalar));CHKERRQ(ierr); 21617ab2063SBarry Smith /* free up old matrix storage */ 217606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 218606d414cSSatish Balay if (!a->singlemalloc) { 219606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 220606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 221606d414cSSatish Balay } 222416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 223416022c9SBarry Smith a->singlemalloc = 1; 22417ab2063SBarry Smith 22517ab2063SBarry Smith rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 226416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 227416022c9SBarry Smith PLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(Scalar))); 228416022c9SBarry Smith a->maxnz += CHUNKSIZE; 229b810aeb4SBarry Smith a->reallocs++; 23017ab2063SBarry Smith } 231416022c9SBarry Smith N = nrow++ - 1; a->nz++; 232416022c9SBarry Smith /* shift up all the later entries in this row */ 233416022c9SBarry Smith for ( ii=N; ii>=i; ii-- ) { 23417ab2063SBarry Smith rp[ii+1] = rp[ii]; 23517ab2063SBarry Smith ap[ii+1] = ap[ii]; 23617ab2063SBarry Smith } 23717ab2063SBarry Smith rp[i] = col; 23817ab2063SBarry Smith ap[i] = value; 23917ab2063SBarry Smith noinsert:; 240416022c9SBarry Smith low = i + 1; 24117ab2063SBarry Smith } 24217ab2063SBarry Smith ailen[row] = nrow; 24317ab2063SBarry Smith } 2443a40ed3dSBarry Smith PetscFunctionReturn(0); 24517ab2063SBarry Smith } 24617ab2063SBarry Smith 2475615d1e5SSatish Balay #undef __FUNC__ 2485615d1e5SSatish Balay #define __FUNC__ "MatGetValues_SeqAIJ" 2498f6be9afSLois Curfman McInnes int MatGetValues_SeqAIJ(Mat A,int m,int *im,int n,int *in,Scalar *v) 2507eb43aa7SLois Curfman McInnes { 2517eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 252b49de8d1SLois Curfman McInnes int *rp, k, low, high, t, row, nrow, i, col, l, *aj = a->j; 2537eb43aa7SLois Curfman McInnes int *ai = a->i, *ailen = a->ilen, shift = a->indexshift; 2547eb43aa7SLois Curfman McInnes Scalar *ap, *aa = a->a, zero = 0.0; 2557eb43aa7SLois Curfman McInnes 2563a40ed3dSBarry Smith PetscFunctionBegin; 2577eb43aa7SLois Curfman McInnes for ( k=0; k<m; k++ ) { /* loop over rows */ 2587eb43aa7SLois Curfman McInnes row = im[k]; 259a8c6a408SBarry Smith if (row < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative row"); 260a8c6a408SBarry Smith if (row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row too large"); 2617eb43aa7SLois Curfman McInnes rp = aj + ai[row] + shift; ap = aa + ai[row] + shift; 2627eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2637eb43aa7SLois Curfman McInnes for ( l=0; l<n; l++ ) { /* loop over columns */ 264a8c6a408SBarry Smith if (in[l] < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Negative column"); 265a8c6a408SBarry Smith if (in[l] >= a->n) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Column too large"); 2667eb43aa7SLois Curfman McInnes col = in[l] - shift; 2677eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2687eb43aa7SLois Curfman McInnes while (high-low > 5) { 2697eb43aa7SLois Curfman McInnes t = (low+high)/2; 2707eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2717eb43aa7SLois Curfman McInnes else low = t; 2727eb43aa7SLois Curfman McInnes } 2737eb43aa7SLois Curfman McInnes for ( i=low; i<high; i++ ) { 2747eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2757eb43aa7SLois Curfman McInnes if (rp[i] == col) { 276b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2777eb43aa7SLois Curfman McInnes goto finished; 2787eb43aa7SLois Curfman McInnes } 2797eb43aa7SLois Curfman McInnes } 280b49de8d1SLois Curfman McInnes *v++ = zero; 2817eb43aa7SLois Curfman McInnes finished:; 2827eb43aa7SLois Curfman McInnes } 2837eb43aa7SLois Curfman McInnes } 2843a40ed3dSBarry Smith PetscFunctionReturn(0); 2857eb43aa7SLois Curfman McInnes } 2867eb43aa7SLois Curfman McInnes 28717ab2063SBarry Smith 2885615d1e5SSatish Balay #undef __FUNC__ 2895615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_Binary" 290480ef9eaSBarry Smith int MatView_SeqAIJ_Binary(Mat A,Viewer viewer) 29117ab2063SBarry Smith { 292416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 293416022c9SBarry Smith int i, fd, *col_lens, ierr; 29417ab2063SBarry Smith 2953a40ed3dSBarry Smith PetscFunctionBegin; 29690ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 2970452661fSBarry Smith col_lens = (int *) PetscMalloc( (4+a->m)*sizeof(int) );CHKPTRQ(col_lens); 298416022c9SBarry Smith col_lens[0] = MAT_COOKIE; 299416022c9SBarry Smith col_lens[1] = a->m; 300416022c9SBarry Smith col_lens[2] = a->n; 301416022c9SBarry Smith col_lens[3] = a->nz; 302416022c9SBarry Smith 303416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 304416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 305416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 30617ab2063SBarry Smith } 3070752156aSBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+a->m,PETSC_INT,1);CHKERRQ(ierr); 308606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 309416022c9SBarry Smith 310416022c9SBarry Smith /* store column indices (zero start index) */ 311416022c9SBarry Smith if (a->indexshift) { 312416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]--; 31317ab2063SBarry Smith } 3140752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 315416022c9SBarry Smith if (a->indexshift) { 316416022c9SBarry Smith for ( i=0; i<a->nz; i++ ) a->j[i]++; 31717ab2063SBarry Smith } 318416022c9SBarry Smith 319416022c9SBarry Smith /* store nonzero values */ 3200752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 3213a40ed3dSBarry Smith PetscFunctionReturn(0); 32217ab2063SBarry Smith } 323416022c9SBarry Smith 3245615d1e5SSatish Balay #undef __FUNC__ 3255615d1e5SSatish Balay #define __FUNC__ "MatView_SeqAIJ_ASCII" 326480ef9eaSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,Viewer viewer) 327416022c9SBarry Smith { 328416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 329*6831982aSBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift, format; 33017ab2063SBarry Smith char *outputname; 33117ab2063SBarry Smith 3323a40ed3dSBarry Smith PetscFunctionBegin; 333fb4b0f7fSBarry Smith ierr = ViewerGetOutputname(viewer,&outputname);CHKERRQ(ierr); 334888f2ed8SSatish Balay ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 335*6831982aSBarry Smith if (format == VIEWER_FORMAT_ASCII_INFO_LONG || format == VIEWER_FORMAT_ASCII_INFO) { 336*6831982aSBarry Smith if (a->inode.size) { 337*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 338*6831982aSBarry Smith } else { 339*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 340*6831982aSBarry Smith } 3413a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_MATLAB) { 342d00d2cf4SBarry Smith int nofinalvalue = 0; 343d00d2cf4SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != a->n-!shift)) { 344d00d2cf4SBarry Smith nofinalvalue = 1; 345d00d2cf4SBarry Smith } 346*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 347*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,a->n);CHKERRQ(ierr); 348*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 349*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 350*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 35117ab2063SBarry Smith 35217ab2063SBarry Smith for (i=0; i<m; i++) { 353416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 354aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 355*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e + %18.16e i \n",i+1,a->j[j]+!shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 35617ab2063SBarry Smith #else 357*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n", i+1, a->j[j]+!shift, a->a[j]);CHKERRQ(ierr); 35817ab2063SBarry Smith #endif 35917ab2063SBarry Smith } 36017ab2063SBarry Smith } 361d00d2cf4SBarry Smith if (nofinalvalue) { 362*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"%d %d %18.16e\n", m, a->n, 0.0);CHKERRQ(ierr); 363d00d2cf4SBarry Smith } 364*6831982aSBarry Smith if (outputname) {ierr = ViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",outputname);CHKERRQ(ierr);} 365*6831982aSBarry Smith else {ierr = ViewerASCIIPrintf(viewer,"];\n M = spconvert(zzz);\n");CHKERRQ(ierr);} 366*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 3673a40ed3dSBarry Smith } else if (format == VIEWER_FORMAT_ASCII_COMMON) { 368*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 36944cd7ae7SLois Curfman McInnes for ( i=0; i<m; i++ ) { 370*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 37144cd7ae7SLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 372aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 373*6831982aSBarry Smith if (PetscImaginary(a->a[j]) > 0.0 && PetscReal(a->a[j]) != 0.0) { 374*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 375*6831982aSBarry Smith } else if (PetscImaginary(a->a[j]) < 0.0 && PetscReal(a->a[j]) != 0.0) { 376*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr); 377*6831982aSBarry Smith } else if (PetscReal(a->a[j]) != 0.0) { 378*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr); 379*6831982aSBarry Smith } 38044cd7ae7SLois Curfman McInnes #else 381*6831982aSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 38244cd7ae7SLois Curfman McInnes #endif 38344cd7ae7SLois Curfman McInnes } 384*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 38544cd7ae7SLois Curfman McInnes } 386*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 38702594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_SYMMODU) { 388496be53dSLois Curfman McInnes int nzd=0, fshift=1, *sptr; 389*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 3902e44a96cSLois Curfman McInnes sptr = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(sptr); 391496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 392496be53dSLois Curfman McInnes sptr[i] = nzd+1; 393496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 394496be53dSLois Curfman McInnes if (a->j[j] >= i) { 395aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 396e20fef11SSatish Balay if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) nzd++; 397496be53dSLois Curfman McInnes #else 398496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 399496be53dSLois Curfman McInnes #endif 400496be53dSLois Curfman McInnes } 401496be53dSLois Curfman McInnes } 402496be53dSLois Curfman McInnes } 4032e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 404*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 4052e44a96cSLois Curfman McInnes for ( i=0; i<m+1; i+=6 ) { 406*6831982aSBarry Smith if (i+4<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4],sptr[i+5]);CHKERRQ(ierr);} 407*6831982aSBarry Smith else if (i+3<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);} 408*6831982aSBarry Smith else if (i+2<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);} 409*6831982aSBarry Smith else if (i+1<m) {ierr = ViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 410*6831982aSBarry Smith else if (i<m) {ierr = ViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 411*6831982aSBarry Smith else {ierr = ViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 412496be53dSLois Curfman McInnes } 413*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 414606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 415496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 416496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 417*6831982aSBarry Smith if (a->j[j] >= i) {ierr = ViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 418496be53dSLois Curfman McInnes } 419*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 420496be53dSLois Curfman McInnes } 421*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 422496be53dSLois Curfman McInnes for ( i=0; i<m; i++ ) { 423496be53dSLois Curfman McInnes for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 424496be53dSLois Curfman McInnes if (a->j[j] >= i) { 425aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 426*6831982aSBarry Smith if (PetscImaginary(a->a[j]) != 0.0 || PetscReal(a->a[j]) != 0.0) { 427*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 428*6831982aSBarry Smith } 429496be53dSLois Curfman McInnes #else 430*6831982aSBarry Smith if (a->a[j] != 0.0) {ierr = ViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 431496be53dSLois Curfman McInnes #endif 432496be53dSLois Curfman McInnes } 433496be53dSLois Curfman McInnes } 434*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 435496be53dSLois Curfman McInnes } 436*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 43702594712SBarry Smith } else if (format == VIEWER_FORMAT_ASCII_DENSE) { 43802594712SBarry Smith int cnt = 0,jcnt; 43902594712SBarry Smith Scalar value; 44002594712SBarry Smith 441*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 44202594712SBarry Smith for ( i=0; i<m; i++ ) { 44302594712SBarry Smith jcnt = 0; 44402594712SBarry Smith for ( j=0; j<a->n; j++ ) { 445e24b481bSBarry Smith if ( jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 44602594712SBarry Smith value = a->a[cnt++]; 447e24b481bSBarry Smith jcnt++; 44802594712SBarry Smith } else { 44902594712SBarry Smith value = 0.0; 45002594712SBarry Smith } 451aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 452*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscReal(value),PetscImaginary(value));CHKERRQ(ierr); 45302594712SBarry Smith #else 454*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 45502594712SBarry Smith #endif 45602594712SBarry Smith } 457*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45802594712SBarry Smith } 459*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4603a40ed3dSBarry Smith } else { 461*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 46217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 463*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 464416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 465aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 466e20fef11SSatish Balay if (PetscImaginary(a->a[j]) > 0.0) { 467*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g + %g i",a->j[j]+shift,PetscReal(a->a[j]),PetscImaginary(a->a[j]));CHKERRQ(ierr); 468e20fef11SSatish Balay } else if (PetscImaginary(a->a[j]) < 0.0) { 469*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g - %g i",a->j[j]+shift,PetscReal(a->a[j]),-PetscImaginary(a->a[j]));CHKERRQ(ierr); 4703a40ed3dSBarry Smith } else { 471*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,PetscReal(a->a[j]));CHKERRQ(ierr); 47217ab2063SBarry Smith } 47317ab2063SBarry Smith #else 474*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer," %d %g ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 47517ab2063SBarry Smith #endif 47617ab2063SBarry Smith } 477*6831982aSBarry Smith ierr = ViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 47817ab2063SBarry Smith } 479*6831982aSBarry Smith ierr = ViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 48017ab2063SBarry Smith } 481*6831982aSBarry Smith ierr = ViewerFlush(viewer);CHKERRQ(ierr); 4823a40ed3dSBarry Smith PetscFunctionReturn(0); 483416022c9SBarry Smith } 484416022c9SBarry Smith 4855615d1e5SSatish Balay #undef __FUNC__ 486480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw_Zoom" 487480ef9eaSBarry Smith int MatView_SeqAIJ_Draw_Zoom(Draw draw,void *Aa) 488416022c9SBarry Smith { 489480ef9eaSBarry Smith Mat A = (Mat) Aa; 490416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 49177ed5343SBarry Smith int ierr, i,j, m = a->m, shift = a->indexshift,color,rank; 4920513a670SBarry Smith int format; 493480ef9eaSBarry Smith double xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 494480ef9eaSBarry Smith Viewer viewer; 49577ed5343SBarry Smith MPI_Comm comm; 496cddf8d76SBarry Smith 4973a40ed3dSBarry Smith PetscFunctionBegin; 49877ed5343SBarry Smith /* 49977ed5343SBarry Smith This is nasty. If this is called from an originally parallel matrix 50077ed5343SBarry Smith then all processes call this, but only the first has the matrix so the 50177ed5343SBarry Smith rest should return immediately. 50277ed5343SBarry Smith */ 50377ed5343SBarry Smith ierr = PetscObjectGetComm((PetscObject)draw,&comm);CHKERRQ(ierr); 504d132466eSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 50577ed5343SBarry Smith if (rank) PetscFunctionReturn(0); 50677ed5343SBarry Smith 507480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*) &viewer);CHKERRQ(ierr); 5080513a670SBarry Smith ierr = ViewerGetFormat(viewer,&format);CHKERRQ(ierr); 50919bcc07fSBarry Smith 510480ef9eaSBarry Smith ierr = DrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 511416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 5120513a670SBarry Smith 5130513a670SBarry Smith if (format != VIEWER_FORMAT_DRAW_CONTOUR) { 5140513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 515cddf8d76SBarry Smith color = DRAW_BLUE; 516416022c9SBarry Smith for ( i=0; i<m; i++ ) { 517cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 518416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 519cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 520aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 521e20fef11SSatish Balay if (PetscReal(a->a[j]) >= 0.) continue; 522cddf8d76SBarry Smith #else 523cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 524cddf8d76SBarry Smith #endif 525480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 526cddf8d76SBarry Smith } 527cddf8d76SBarry Smith } 528cddf8d76SBarry Smith color = DRAW_CYAN; 529cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 530cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 531cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 532cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 533cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 534480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 535cddf8d76SBarry Smith } 536cddf8d76SBarry Smith } 537cddf8d76SBarry Smith color = DRAW_RED; 538cddf8d76SBarry Smith for ( i=0; i<m; i++ ) { 539cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 540cddf8d76SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 541cddf8d76SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 542aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 543e20fef11SSatish Balay if (PetscReal(a->a[j]) <= 0.) continue; 544cddf8d76SBarry Smith #else 545cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 546cddf8d76SBarry Smith #endif 547480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 548416022c9SBarry Smith } 549416022c9SBarry Smith } 5500513a670SBarry Smith } else { 5510513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5520513a670SBarry Smith /* first determine max of all nonzero values */ 5530513a670SBarry Smith int nz = a->nz,count; 5540513a670SBarry Smith Draw popup; 555480ef9eaSBarry Smith double scale; 5560513a670SBarry Smith 5570513a670SBarry Smith for ( i=0; i<nz; i++ ) { 5580513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5590513a670SBarry Smith } 560480ef9eaSBarry Smith scale = (245.0 - DRAW_BASIC_COLORS)/maxv; 561522c5e43SBarry Smith ierr = DrawGetPopup(draw,&popup);CHKERRQ(ierr); 5620513a670SBarry Smith ierr = DrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr); 5630513a670SBarry Smith count = 0; 5640513a670SBarry Smith for ( i=0; i<m; i++ ) { 5650513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 5660513a670SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 5670513a670SBarry Smith x_l = a->j[j] + shift; x_r = x_l + 1.0; 5686d6b6c30SSatish Balay color = DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 569480ef9eaSBarry Smith ierr = DrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5700513a670SBarry Smith count++; 5710513a670SBarry Smith } 5720513a670SBarry Smith } 5730513a670SBarry Smith } 574480ef9eaSBarry Smith PetscFunctionReturn(0); 575480ef9eaSBarry Smith } 576cddf8d76SBarry Smith 577480ef9eaSBarry Smith #undef __FUNC__ 578480ef9eaSBarry Smith #define __FUNC__ "MatView_SeqAIJ_Draw" 579480ef9eaSBarry Smith int MatView_SeqAIJ_Draw(Mat A,Viewer viewer) 580480ef9eaSBarry Smith { 581480ef9eaSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 582480ef9eaSBarry Smith int ierr; 583480ef9eaSBarry Smith Draw draw; 584480ef9eaSBarry Smith double xr,yr,xl,yl,h,w; 585480ef9eaSBarry Smith PetscTruth isnull; 586480ef9eaSBarry Smith 587480ef9eaSBarry Smith PetscFunctionBegin; 58877ed5343SBarry Smith ierr = ViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 589480ef9eaSBarry Smith ierr = DrawIsNull(draw,&isnull);CHKERRQ(ierr); 590480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 591480ef9eaSBarry Smith 592480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 593480ef9eaSBarry Smith xr = a->n; yr = a->m; h = yr/10.0; w = xr/10.0; 594480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 595cddf8d76SBarry Smith ierr = DrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 596480ef9eaSBarry Smith ierr = DrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 597480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5983a40ed3dSBarry Smith PetscFunctionReturn(0); 599416022c9SBarry Smith } 600416022c9SBarry Smith 6015615d1e5SSatish Balay #undef __FUNC__ 602d4bb536fSBarry Smith #define __FUNC__ "MatView_SeqAIJ" 603e1311b90SBarry Smith int MatView_SeqAIJ(Mat A,Viewer viewer) 604416022c9SBarry Smith { 605416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 606bcd2baecSBarry Smith int ierr; 607*6831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 608416022c9SBarry Smith 6093a40ed3dSBarry Smith PetscFunctionBegin; 610*6831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,SOCKET_VIEWER,&issocket);CHKERRQ(ierr); 611*6831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,ASCII_VIEWER,&isascii);CHKERRQ(ierr); 612*6831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr); 613*6831982aSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,DRAW_VIEWER,&isdraw);CHKERRQ(ierr); 6140f5bd95cSBarry Smith if (issocket) { 6157b2a1423SBarry Smith ierr = ViewerSocketPutSparse_Private(viewer,a->m,a->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 6160f5bd95cSBarry Smith } else if (isascii) { 6173a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 6180f5bd95cSBarry Smith } else if (isbinary) { 6193a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 6200f5bd95cSBarry Smith } else if (isdraw) { 6213a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 6225cd90555SBarry Smith } else { 6230f5bd95cSBarry Smith SETERRQ1(1,1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 62417ab2063SBarry Smith } 6253a40ed3dSBarry Smith PetscFunctionReturn(0); 62617ab2063SBarry Smith } 62719bcc07fSBarry Smith 628c456f294SBarry Smith extern int Mat_AIJ_CheckInode(Mat); 6295615d1e5SSatish Balay #undef __FUNC__ 6305615d1e5SSatish Balay #define __FUNC__ "MatAssemblyEnd_SeqAIJ" 6318f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 63217ab2063SBarry Smith { 633416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 63441c01911SSatish Balay int fshift = 0,i,j,*ai = a->i, *aj = a->j, *imax = a->imax,ierr; 63543ee02c3SBarry Smith int m = a->m, *ip, N, *ailen = a->ilen,shift = a->indexshift,rmax = 0; 636416022c9SBarry Smith Scalar *aa = a->a, *ap; 63717ab2063SBarry Smith 6383a40ed3dSBarry Smith PetscFunctionBegin; 6393a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 64017ab2063SBarry Smith 64143ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 64217ab2063SBarry Smith for ( i=1; i<m; i++ ) { 643416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 64417ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 64594a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 64617ab2063SBarry Smith if (fshift) { 6470f5bd95cSBarry Smith ip = aj + ai[i] + shift; 6480f5bd95cSBarry Smith ap = aa + ai[i] + shift; 64917ab2063SBarry Smith N = ailen[i]; 65017ab2063SBarry Smith for ( j=0; j<N; j++ ) { 65117ab2063SBarry Smith ip[j-fshift] = ip[j]; 65217ab2063SBarry Smith ap[j-fshift] = ap[j]; 65317ab2063SBarry Smith } 65417ab2063SBarry Smith } 65517ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 65617ab2063SBarry Smith } 65717ab2063SBarry Smith if (m) { 65817ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 65917ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 66017ab2063SBarry Smith } 66117ab2063SBarry Smith /* reset ilen and imax for each row */ 66217ab2063SBarry Smith for ( i=0; i<m; i++ ) { 66317ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 66417ab2063SBarry Smith } 665416022c9SBarry Smith a->nz = ai[m] + shift; 66617ab2063SBarry Smith 66717ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 668416022c9SBarry Smith if (fshift && a->diag) { 669606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 670416022c9SBarry Smith PLogObjectMemory(A,-(m+1)*sizeof(int)); 671416022c9SBarry Smith a->diag = 0; 67217ab2063SBarry Smith } 6734e220ebcSLois Curfman McInnes PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded, %d used\n", 6744e220ebcSLois Curfman McInnes m,a->n,fshift,a->nz); 67514bcb312SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n", 676b810aeb4SBarry Smith a->reallocs); 67794a9d846SBarry Smith PLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 678dd5f02e7SSatish Balay a->reallocs = 0; 6794e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 6804e220ebcSLois Curfman McInnes 68176dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 68241c01911SSatish Balay ierr = Mat_AIJ_CheckInode(A);CHKERRQ(ierr); 6833a40ed3dSBarry Smith PetscFunctionReturn(0); 68417ab2063SBarry Smith } 68517ab2063SBarry Smith 6865615d1e5SSatish Balay #undef __FUNC__ 6875615d1e5SSatish Balay #define __FUNC__ "MatZeroEntries_SeqAIJ" 6888f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 68917ab2063SBarry Smith { 690416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 691549d3d68SSatish Balay int ierr; 6923a40ed3dSBarry Smith 6933a40ed3dSBarry Smith PetscFunctionBegin; 694549d3d68SSatish Balay ierr = PetscMemzero(a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 6953a40ed3dSBarry Smith PetscFunctionReturn(0); 69617ab2063SBarry Smith } 697416022c9SBarry Smith 6985615d1e5SSatish Balay #undef __FUNC__ 6995615d1e5SSatish Balay #define __FUNC__ "MatDestroy_SeqAIJ" 700e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 70117ab2063SBarry Smith { 702416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 70382bf6240SBarry Smith int ierr; 704d5d45c9bSBarry Smith 7053a40ed3dSBarry Smith PetscFunctionBegin; 70694d884c6SBarry Smith 70794d884c6SBarry Smith if (A->mapping) { 70894d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->mapping);CHKERRQ(ierr); 70994d884c6SBarry Smith } 71094d884c6SBarry Smith if (A->bmapping) { 71194d884c6SBarry Smith ierr = ISLocalToGlobalMappingDestroy(A->bmapping);CHKERRQ(ierr); 71294d884c6SBarry Smith } 71361b13de0SBarry Smith if (A->rmap) { 71461b13de0SBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 71561b13de0SBarry Smith } 71661b13de0SBarry Smith if (A->cmap) { 71761b13de0SBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 71861b13de0SBarry Smith } 719606d414cSSatish Balay if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 720aa482453SBarry Smith #if defined(PETSC_USE_LOG) 721e1311b90SBarry Smith PLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",a->m,a->n,a->nz); 72217ab2063SBarry Smith #endif 723606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 724606d414cSSatish Balay if (!a->singlemalloc) { 725606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 726606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 727606d414cSSatish Balay } 728606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 729606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 730606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 731606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 732606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 73382bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 734606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 735606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 736eed86810SBarry Smith 737f2655603SLois Curfman McInnes PLogObjectDestroy(A); 738f2655603SLois Curfman McInnes PetscHeaderDestroy(A); 7393a40ed3dSBarry Smith PetscFunctionReturn(0); 74017ab2063SBarry Smith } 74117ab2063SBarry Smith 7425615d1e5SSatish Balay #undef __FUNC__ 7435615d1e5SSatish Balay #define __FUNC__ "MatCompress_SeqAIJ" 7448f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 74517ab2063SBarry Smith { 7463a40ed3dSBarry Smith PetscFunctionBegin; 7473a40ed3dSBarry Smith PetscFunctionReturn(0); 74817ab2063SBarry Smith } 74917ab2063SBarry Smith 7505615d1e5SSatish Balay #undef __FUNC__ 7515615d1e5SSatish Balay #define __FUNC__ "MatSetOption_SeqAIJ" 7528f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 75317ab2063SBarry Smith { 754416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7553a40ed3dSBarry Smith 7563a40ed3dSBarry Smith PetscFunctionBegin; 7576d4a8577SBarry Smith if (op == MAT_ROW_ORIENTED) a->roworiented = 1; 7586d4a8577SBarry Smith else if (op == MAT_COLUMN_ORIENTED) a->roworiented = 0; 7596d4a8577SBarry Smith else if (op == MAT_COLUMNS_SORTED) a->sorted = 1; 760219d9a1aSLois Curfman McInnes else if (op == MAT_COLUMNS_UNSORTED) a->sorted = 0; 7616d4a8577SBarry Smith else if (op == MAT_NO_NEW_NONZERO_LOCATIONS) a->nonew = 1; 7624787f768SSatish Balay else if (op == MAT_NEW_NONZERO_LOCATION_ERR) a->nonew = -1; 7634787f768SSatish Balay else if (op == MAT_NEW_NONZERO_ALLOCATION_ERR) a->nonew = -2; 7646d4a8577SBarry Smith else if (op == MAT_YES_NEW_NONZERO_LOCATIONS) a->nonew = 0; 7656d4a8577SBarry Smith else if (op == MAT_ROWS_SORTED || 766219d9a1aSLois Curfman McInnes op == MAT_ROWS_UNSORTED || 7676d4a8577SBarry Smith op == MAT_SYMMETRIC || 7686d4a8577SBarry Smith op == MAT_STRUCTURALLY_SYMMETRIC || 76990f02eecSBarry Smith op == MAT_YES_NEW_DIAGONALS || 770b51ba29fSSatish Balay op == MAT_IGNORE_OFF_PROC_ENTRIES|| 771b51ba29fSSatish Balay op == MAT_USE_HASH_TABLE) 772981c4779SBarry Smith PLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 7733a40ed3dSBarry Smith else if (op == MAT_NO_NEW_DIAGONALS) { 7743a40ed3dSBarry Smith SETERRQ(PETSC_ERR_SUP,0,"MAT_NO_NEW_DIAGONALS"); 7753a40ed3dSBarry Smith } else if (op == MAT_INODE_LIMIT_1) a->inode.limit = 1; 7766d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_2) a->inode.limit = 2; 7776d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_3) a->inode.limit = 3; 7786d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_4) a->inode.limit = 4; 7796d4a8577SBarry Smith else if (op == MAT_INODE_LIMIT_5) a->inode.limit = 5; 7803a40ed3dSBarry Smith else SETERRQ(PETSC_ERR_SUP,0,"unknown option"); 7813a40ed3dSBarry Smith PetscFunctionReturn(0); 78217ab2063SBarry Smith } 78317ab2063SBarry Smith 7845615d1e5SSatish Balay #undef __FUNC__ 7855615d1e5SSatish Balay #define __FUNC__ "MatGetDiagonal_SeqAIJ" 7868f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 78717ab2063SBarry Smith { 788416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 7893a40ed3dSBarry Smith int i,j, n,shift = a->indexshift,ierr; 79017ab2063SBarry Smith Scalar *x, zero = 0.0; 79117ab2063SBarry Smith 7923a40ed3dSBarry Smith PetscFunctionBegin; 7933a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 794e1311b90SBarry Smith ierr = VecGetArray(v,&x);;CHKERRQ(ierr); 795e1311b90SBarry Smith ierr = VecGetLocalSize(v,&n);;CHKERRQ(ierr); 796a8c6a408SBarry Smith if (n != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Nonconforming matrix and vector"); 797416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 798416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 799416022c9SBarry Smith if (a->j[j]+shift == i) { 800416022c9SBarry Smith x[i] = a->a[j]; 80117ab2063SBarry Smith break; 80217ab2063SBarry Smith } 80317ab2063SBarry Smith } 80417ab2063SBarry Smith } 805e1311b90SBarry Smith ierr = VecRestoreArray(v,&x);;CHKERRQ(ierr); 8063a40ed3dSBarry Smith PetscFunctionReturn(0); 80717ab2063SBarry Smith } 80817ab2063SBarry Smith 80917ab2063SBarry Smith /* -------------------------------------------------------*/ 81017ab2063SBarry Smith /* Should check that shapes of vectors and matrices match */ 81117ab2063SBarry Smith /* -------------------------------------------------------*/ 8125615d1e5SSatish Balay #undef __FUNC__ 8135615d1e5SSatish Balay #define __FUNC__ "MatMultTrans_SeqAIJ" 81444cd7ae7SLois Curfman McInnes int MatMultTrans_SeqAIJ(Mat A,Vec xx,Vec yy) 81517ab2063SBarry Smith { 816416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 81717ab2063SBarry Smith Scalar *x, *y, *v, alpha; 818e1311b90SBarry Smith int ierr,m = a->m, n, i, *idx, shift = a->indexshift; 81917ab2063SBarry Smith 8203a40ed3dSBarry Smith PetscFunctionBegin; 821e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 822e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 823549d3d68SSatish Balay ierr = PetscMemzero(y,a->n*sizeof(Scalar));CHKERRQ(ierr); 82417ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 82517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 826416022c9SBarry Smith idx = a->j + a->i[i] + shift; 827416022c9SBarry Smith v = a->a + a->i[i] + shift; 828416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 82917ab2063SBarry Smith alpha = x[i]; 83017ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 83117ab2063SBarry Smith } 832416022c9SBarry Smith PLogFlops(2*a->nz - a->n); 833e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 834e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8353a40ed3dSBarry Smith PetscFunctionReturn(0); 83617ab2063SBarry Smith } 837d5d45c9bSBarry Smith 8385615d1e5SSatish Balay #undef __FUNC__ 8395615d1e5SSatish Balay #define __FUNC__ "MatMultTransAdd_SeqAIJ" 84044cd7ae7SLois Curfman McInnes int MatMultTransAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 84117ab2063SBarry Smith { 842416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 84317ab2063SBarry Smith Scalar *x, *y, *v, alpha; 844e1311b90SBarry Smith int ierr,m = a->m, n, i, *idx,shift = a->indexshift; 84517ab2063SBarry Smith 8463a40ed3dSBarry Smith PetscFunctionBegin; 8472e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 848e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 849e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 85017ab2063SBarry Smith y = y + shift; /* shift for Fortran start by 1 indexing */ 85117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 852416022c9SBarry Smith idx = a->j + a->i[i] + shift; 853416022c9SBarry Smith v = a->a + a->i[i] + shift; 854416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 85517ab2063SBarry Smith alpha = x[i]; 85617ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 85717ab2063SBarry Smith } 85890f02eecSBarry Smith PLogFlops(2*a->nz); 859e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 860e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 8613a40ed3dSBarry Smith PetscFunctionReturn(0); 86217ab2063SBarry Smith } 86317ab2063SBarry Smith 8645615d1e5SSatish Balay #undef __FUNC__ 8655615d1e5SSatish Balay #define __FUNC__ "MatMult_SeqAIJ" 86644cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 86717ab2063SBarry Smith { 868416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 86917ab2063SBarry Smith Scalar *x, *y, *v, sum; 870e1311b90SBarry Smith int ierr,m = a->m, *idx, shift = a->indexshift,*ii; 871aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 872e36a17ebSSatish Balay int n, i, jrow,j; 873e36a17ebSSatish Balay #endif 87417ab2063SBarry Smith 875aa482453SBarry Smith #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 876fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 877fee21e36SBarry Smith #endif 878fee21e36SBarry Smith 8793a40ed3dSBarry Smith PetscFunctionBegin; 880e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 881e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 88217ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 883416022c9SBarry Smith idx = a->j; 884d64ed03dSBarry Smith v = a->a; 885416022c9SBarry Smith ii = a->i; 886aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 88729b5ca8aSSatish Balay fortranmultaij_(&m,x,ii,idx+shift,v+shift,y); 8888d195f9aSBarry Smith #else 889d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 890d64ed03dSBarry Smith idx += shift; 89117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 8929ea0dfa2SSatish Balay jrow = ii[i]; 8939ea0dfa2SSatish Balay n = ii[i+1] - jrow; 89417ab2063SBarry Smith sum = 0.0; 8959ea0dfa2SSatish Balay for ( j=0; j<n; j++) { 8969ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 8979ea0dfa2SSatish Balay } 89817ab2063SBarry Smith y[i] = sum; 89917ab2063SBarry Smith } 9008d195f9aSBarry Smith #endif 901416022c9SBarry Smith PLogFlops(2*a->nz - m); 902e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 903e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9043a40ed3dSBarry Smith PetscFunctionReturn(0); 90517ab2063SBarry Smith } 90617ab2063SBarry Smith 9075615d1e5SSatish Balay #undef __FUNC__ 9085615d1e5SSatish Balay #define __FUNC__ "MatMultAdd_SeqAIJ" 90944cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 91017ab2063SBarry Smith { 911416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 91217ab2063SBarry Smith Scalar *x, *y, *z, *v, sum; 913e1311b90SBarry Smith int ierr,m = a->m, *idx, shift = a->indexshift,*ii; 914aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 915e36a17ebSSatish Balay int n,i,jrow,j; 916e36a17ebSSatish Balay #endif 9179ea0dfa2SSatish Balay 9183a40ed3dSBarry Smith PetscFunctionBegin; 919e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 920e1311b90SBarry Smith ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 9212e8a6d31SBarry Smith if (zz != yy) { 922e1311b90SBarry Smith ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 9232e8a6d31SBarry Smith } else { 9242e8a6d31SBarry Smith z = y; 9252e8a6d31SBarry Smith } 92617ab2063SBarry Smith x = x + shift; /* shift for Fortran start by 1 indexing */ 927cddf8d76SBarry Smith idx = a->j; 928d64ed03dSBarry Smith v = a->a; 929cddf8d76SBarry Smith ii = a->i; 930aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 93129b5ca8aSSatish Balay fortranmultaddaij_(&m,x,ii,idx+shift,v+shift,y,z); 93202ab625aSSatish Balay #else 933d64ed03dSBarry Smith v += shift; /* shift for Fortran start by 1 indexing */ 934d64ed03dSBarry Smith idx += shift; 93517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 9369ea0dfa2SSatish Balay jrow = ii[i]; 9379ea0dfa2SSatish Balay n = ii[i+1] - jrow; 93817ab2063SBarry Smith sum = y[i]; 9399ea0dfa2SSatish Balay for ( j=0; j<n; j++) { 9409ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 9419ea0dfa2SSatish Balay } 94217ab2063SBarry Smith z[i] = sum; 94317ab2063SBarry Smith } 94402ab625aSSatish Balay #endif 945416022c9SBarry Smith PLogFlops(2*a->nz); 946e1311b90SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 947e1311b90SBarry Smith ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 9482e8a6d31SBarry Smith if (zz != yy) { 949e1311b90SBarry Smith ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 9502e8a6d31SBarry Smith } 9513a40ed3dSBarry Smith PetscFunctionReturn(0); 95217ab2063SBarry Smith } 95317ab2063SBarry Smith 95417ab2063SBarry Smith /* 95517ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 95617ab2063SBarry Smith */ 9575615d1e5SSatish Balay #undef __FUNC__ 9585615d1e5SSatish Balay #define __FUNC__ "MatMarkDiag_SeqAIJ" 959416022c9SBarry Smith int MatMarkDiag_SeqAIJ(Mat A) 96017ab2063SBarry Smith { 961416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 962416022c9SBarry Smith int i,j, *diag, m = a->m,shift = a->indexshift; 96317ab2063SBarry Smith 9643a40ed3dSBarry Smith PetscFunctionBegin; 9650452661fSBarry Smith diag = (int *) PetscMalloc( (m+1)*sizeof(int));CHKPTRQ(diag); 966416022c9SBarry Smith PLogObjectMemory(A,(m+1)*sizeof(int)); 967416022c9SBarry Smith for ( i=0; i<a->m; i++ ) { 96835b0346bSBarry Smith diag[i] = a->i[i+1]; 969416022c9SBarry Smith for ( j=a->i[i]+shift; j<a->i[i+1]+shift; j++ ) { 970416022c9SBarry Smith if (a->j[j]+shift == i) { 97117ab2063SBarry Smith diag[i] = j - shift; 97217ab2063SBarry Smith break; 97317ab2063SBarry Smith } 97417ab2063SBarry Smith } 97517ab2063SBarry Smith } 976416022c9SBarry Smith a->diag = diag; 9773a40ed3dSBarry Smith PetscFunctionReturn(0); 97817ab2063SBarry Smith } 97917ab2063SBarry Smith 980be5855fcSBarry Smith /* 981be5855fcSBarry Smith Checks for missing diagonals 982be5855fcSBarry Smith */ 983be5855fcSBarry Smith #undef __FUNC__ 984be5855fcSBarry Smith #define __FUNC__ "MatMissingDiag_SeqAIJ" 985be5855fcSBarry Smith int MatMissingDiag_SeqAIJ(Mat A) 986be5855fcSBarry Smith { 987be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 988be5855fcSBarry Smith int *diag = a->diag, *jj = a->j,i,shift = a->indexshift; 989be5855fcSBarry Smith 990be5855fcSBarry Smith PetscFunctionBegin; 991be5855fcSBarry Smith for ( i=0; i<a->m; i++ ) { 992be5855fcSBarry Smith if (jj[diag[i]+shift] != i-shift) { 993be5855fcSBarry Smith SETERRQ1(1,1,"Matrix is missing diagonal number %d",i); 994be5855fcSBarry Smith } 995be5855fcSBarry Smith } 996be5855fcSBarry Smith PetscFunctionReturn(0); 997be5855fcSBarry Smith } 998be5855fcSBarry Smith 9995615d1e5SSatish Balay #undef __FUNC__ 10005615d1e5SSatish Balay #define __FUNC__ "MatRelax_SeqAIJ" 1001be5855fcSBarry Smith int MatRelax_SeqAIJ(Mat A,Vec bb,double omega,MatSORType flag,double fshift,int its,Vec xx) 100217ab2063SBarry Smith { 1003416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1004d6ed3216SSatish Balay Scalar *x, *b, *bs, d, *xs, sum, *v = a->a,*t=0,scale,*ts, *xb,*idiag=0; 1005d5d45c9bSBarry Smith int ierr, *idx, *diag,n = a->n, m = a->m, i, shift = a->indexshift; 100617ab2063SBarry Smith 10073a40ed3dSBarry Smith PetscFunctionBegin; 1008e1311b90SBarry Smith ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 1009fb2e594dSBarry Smith if (xx != bb) { 1010e1311b90SBarry Smith ierr = VecGetArray(bb,&b);CHKERRQ(ierr); 1011fb2e594dSBarry Smith } else { 1012fb2e594dSBarry Smith b = x; 1013fb2e594dSBarry Smith } 1014fb2e594dSBarry Smith 1015d00d2cf4SBarry Smith if (!a->diag) {ierr = MatMarkDiag_SeqAIJ(A);CHKERRQ(ierr);} 1016416022c9SBarry Smith diag = a->diag; 1017416022c9SBarry Smith xs = x + shift; /* shifted by one for index start of a or a->j*/ 101817ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 101917ab2063SBarry Smith /* apply ( U + D/omega) to the vector */ 102017ab2063SBarry Smith bs = b + shift; 102117ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1022416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1023416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1024488ecbafSBarry Smith PLogFlops(2*n-1); 1025416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1026416022c9SBarry Smith v = a->a + diag[i] + (!shift); 102717ab2063SBarry Smith sum = b[i]*d/omega; 102817ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 102917ab2063SBarry Smith x[i] = sum; 103017ab2063SBarry Smith } 1031cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1032fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 10333a40ed3dSBarry Smith PetscFunctionReturn(0); 103417ab2063SBarry Smith } 1035c783ea89SBarry Smith 1036c783ea89SBarry Smith /* setup workspace for Eisenstat */ 1037c783ea89SBarry Smith if (flag & SOR_EISENSTAT) { 1038c783ea89SBarry Smith if (!a->idiag) { 1039c783ea89SBarry Smith a->idiag = (Scalar *) PetscMalloc(2*m*sizeof(Scalar));CHKPTRQ(a->idiag); 1040c783ea89SBarry Smith a->ssor = a->idiag + m; 1041c783ea89SBarry Smith v = a->a; 1042c783ea89SBarry Smith for ( i=0; i<m; i++ ) { a->idiag[i] = 1.0/v[diag[i]];} 1043c783ea89SBarry Smith } 1044c783ea89SBarry Smith t = a->ssor; 1045c783ea89SBarry Smith idiag = a->idiag; 1046c783ea89SBarry Smith } 1047fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1048fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1049fc3d8934SBarry Smith 1050fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1051fc3d8934SBarry Smith 1052fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1053fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 105448af12d7SBarry Smith is the relaxation factor. 1055fc3d8934SBarry Smith */ 1056fc3d8934SBarry Smith 105748af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 105848af12d7SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"SOR_APPLY_LOWER is not done"); 105948af12d7SBarry Smith } else if ((flag & SOR_EISENSTAT) && omega == 1.0 && shift == 0 && fshift == 0.0) { 106048af12d7SBarry Smith /* special case for omega = 1.0 saves flops and some integer ops */ 1061733d66baSBarry Smith Scalar *v2; 106248af12d7SBarry Smith 1063733d66baSBarry Smith v2 = a->a; 1064fc3d8934SBarry Smith /* x = (E + U)^{-1} b */ 1065fc3d8934SBarry Smith for ( i=m-1; i>=0; i-- ) { 1066fc3d8934SBarry Smith n = a->i[i+1] - diag[i] - 1; 1067fc3d8934SBarry Smith idx = a->j + diag[i] + 1; 1068fc3d8934SBarry Smith v = a->a + diag[i] + 1; 1069fc3d8934SBarry Smith sum = b[i]; 1070fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1071b4632166SBarry Smith x[i] = sum*idiag[i]; 1072fc3d8934SBarry Smith 1073fc3d8934SBarry Smith /* t = b - (2*E - D)x */ 1074733d66baSBarry Smith t[i] = b[i] - (v2[diag[i]])*x[i]; 1075733d66baSBarry Smith } 1076fc3d8934SBarry Smith 1077fc3d8934SBarry Smith /* t = (E + L)^{-1}t */ 1078fc3d8934SBarry Smith diag = a->diag; 1079fc3d8934SBarry Smith for ( i=0; i<m; i++ ) { 1080fc3d8934SBarry Smith n = diag[i] - a->i[i]; 1081fc3d8934SBarry Smith idx = a->j + a->i[i]; 1082fc3d8934SBarry Smith v = a->a + a->i[i]; 1083fc3d8934SBarry Smith sum = t[i]; 1084fc3d8934SBarry Smith SPARSEDENSEMDOT(sum,t,v,idx,n); 1085b4632166SBarry Smith t[i] = sum*idiag[i]; 1086fc3d8934SBarry Smith 1087fc3d8934SBarry Smith /* x = x + t */ 1088733d66baSBarry Smith x[i] += t[i]; 1089733d66baSBarry Smith } 1090733d66baSBarry Smith 1091a4d9cbf6SBarry Smith PLogFlops(3*m-1 + 2*a->nz); 1092fc3d8934SBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1093fc3d8934SBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 1094fc3d8934SBarry Smith PetscFunctionReturn(0); 10953a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 109617ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 109717ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 109817ab2063SBarry Smith 109917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 110017ab2063SBarry Smith 110117ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 110217ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 110317ab2063SBarry Smith is the relaxation factor. 110417ab2063SBarry Smith */ 110517ab2063SBarry Smith scale = (2.0/omega) - 1.0; 110617ab2063SBarry Smith 110717ab2063SBarry Smith /* x = (E + U)^{-1} b */ 110817ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1109416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1110416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1111416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1112416022c9SBarry Smith v = a->a + diag[i] + (!shift); 111317ab2063SBarry Smith sum = b[i]; 111417ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 111517ab2063SBarry Smith x[i] = omega*(sum/d); 111617ab2063SBarry Smith } 111717ab2063SBarry Smith 111817ab2063SBarry Smith /* t = b - (2*E - D)x */ 1119416022c9SBarry Smith v = a->a; 112017ab2063SBarry Smith for ( i=0; i<m; i++ ) { t[i] = b[i] - scale*(v[*diag++ + shift])*x[i]; } 112117ab2063SBarry Smith 112217ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1123416022c9SBarry Smith ts = t + shift; /* shifted by one for index start of a or a->j*/ 1124416022c9SBarry Smith diag = a->diag; 112517ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1126416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1127416022c9SBarry Smith n = diag[i] - a->i[i]; 1128416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1129416022c9SBarry Smith v = a->a + a->i[i] + shift; 113017ab2063SBarry Smith sum = t[i]; 113117ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 113217ab2063SBarry Smith t[i] = omega*(sum/d); 1133733d66baSBarry Smith /* x = x + t */ 1134733d66baSBarry Smith x[i] += t[i]; 113517ab2063SBarry Smith } 113617ab2063SBarry Smith 1137c783ea89SBarry Smith PLogFlops(6*m-1 + 2*a->nz); 1138cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1139fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 11403a40ed3dSBarry Smith PetscFunctionReturn(0); 114117ab2063SBarry Smith } 114217ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 114317ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 114417ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1145416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1146416022c9SBarry Smith n = diag[i] - a->i[i]; 1147488ecbafSBarry Smith PLogFlops(2*n-1); 1148416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1149416022c9SBarry Smith v = a->a + a->i[i] + shift; 115017ab2063SBarry Smith sum = b[i]; 115117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 115217ab2063SBarry Smith x[i] = omega*(sum/d); 115317ab2063SBarry Smith } 115417ab2063SBarry Smith xb = x; 11553a40ed3dSBarry Smith } else xb = b; 115617ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 115717ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 115817ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1159416022c9SBarry Smith x[i] *= a->a[diag[i]+shift]; 116017ab2063SBarry Smith } 1161488ecbafSBarry Smith PLogFlops(m); 116217ab2063SBarry Smith } 116317ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 116417ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1165416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1166416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1167488ecbafSBarry Smith PLogFlops(2*n-1); 1168416022c9SBarry Smith idx = a->j + diag[i] + (!shift); 1169416022c9SBarry Smith v = a->a + diag[i] + (!shift); 117017ab2063SBarry Smith sum = xb[i]; 117117ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 117217ab2063SBarry Smith x[i] = omega*(sum/d); 117317ab2063SBarry Smith } 117417ab2063SBarry Smith } 117517ab2063SBarry Smith its--; 117617ab2063SBarry Smith } 117717ab2063SBarry Smith while (its--) { 117817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 117917ab2063SBarry Smith for ( i=0; i<m; i++ ) { 1180416022c9SBarry Smith d = fshift + a->a[diag[i]+shift]; 1181416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1182488ecbafSBarry Smith PLogFlops(2*n-1); 1183416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1184416022c9SBarry Smith v = a->a + a->i[i] + shift; 118517ab2063SBarry Smith sum = b[i]; 118617ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11877e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 118817ab2063SBarry Smith } 118917ab2063SBarry Smith } 119017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 119117ab2063SBarry Smith for ( i=m-1; i>=0; i-- ) { 1192416022c9SBarry Smith d = fshift + a->a[diag[i] + shift]; 1193416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1194488ecbafSBarry Smith PLogFlops(2*n-1); 1195416022c9SBarry Smith idx = a->j + a->i[i] + shift; 1196416022c9SBarry Smith v = a->a + a->i[i] + shift; 119717ab2063SBarry Smith sum = b[i]; 119817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 11997e33a6baSBarry Smith x[i] = (1. - omega)*x[i] + omega*(sum + a->a[diag[i]+shift]*x[i])/d; 120017ab2063SBarry Smith } 120117ab2063SBarry Smith } 120217ab2063SBarry Smith } 1203cb5b572fSBarry Smith ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 1204fb2e594dSBarry Smith if (bb != xx) {ierr = VecRestoreArray(bb,&b);CHKERRQ(ierr);} 12053a40ed3dSBarry Smith PetscFunctionReturn(0); 120617ab2063SBarry Smith } 120717ab2063SBarry Smith 12085615d1e5SSatish Balay #undef __FUNC__ 12095615d1e5SSatish Balay #define __FUNC__ "MatGetInfo_SeqAIJ" 12108f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 121117ab2063SBarry Smith { 1212416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12134e220ebcSLois Curfman McInnes 12143a40ed3dSBarry Smith PetscFunctionBegin; 12154e220ebcSLois Curfman McInnes info->rows_global = (double)a->m; 12164e220ebcSLois Curfman McInnes info->columns_global = (double)a->n; 12174e220ebcSLois Curfman McInnes info->rows_local = (double)a->m; 12184e220ebcSLois Curfman McInnes info->columns_local = (double)a->n; 12194e220ebcSLois Curfman McInnes info->block_size = 1.0; 12204e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12214e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12224e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12234e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12244e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12254e220ebcSLois Curfman McInnes info->memory = A->mem; 12264e220ebcSLois Curfman McInnes if (A->factor) { 12274e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12284e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12294e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12304e220ebcSLois Curfman McInnes } else { 12314e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12324e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12334e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12344e220ebcSLois Curfman McInnes } 12353a40ed3dSBarry Smith PetscFunctionReturn(0); 123617ab2063SBarry Smith } 123717ab2063SBarry Smith 123817ab2063SBarry Smith extern int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,double,Mat*); 123917ab2063SBarry Smith extern int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 124017ab2063SBarry Smith extern int MatLUFactor_SeqAIJ(Mat,IS,IS,double); 124117ab2063SBarry Smith extern int MatSolve_SeqAIJ(Mat,Vec,Vec); 124217ab2063SBarry Smith extern int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 124317ab2063SBarry Smith extern int MatSolveTrans_SeqAIJ(Mat,Vec,Vec); 124417ab2063SBarry Smith extern int MatSolveTransAdd_SeqAIJ(Mat,Vec,Vec,Vec); 124517ab2063SBarry Smith 12465615d1e5SSatish Balay #undef __FUNC__ 12475615d1e5SSatish Balay #define __FUNC__ "MatZeroRows_SeqAIJ" 12488f6be9afSLois Curfman McInnes int MatZeroRows_SeqAIJ(Mat A,IS is,Scalar *diag) 124917ab2063SBarry Smith { 1250416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1251416022c9SBarry Smith int i,ierr,N, *rows,m = a->m - 1,shift = a->indexshift; 125217ab2063SBarry Smith 12533a40ed3dSBarry Smith PetscFunctionBegin; 125477c4ece6SBarry Smith ierr = ISGetSize(is,&N);CHKERRQ(ierr); 125517ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 125617ab2063SBarry Smith if (diag) { 125717ab2063SBarry Smith for ( i=0; i<N; i++ ) { 1258a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 12597ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1260416022c9SBarry Smith a->ilen[rows[i]] = 1; 1261416022c9SBarry Smith a->a[a->i[rows[i]]+shift] = *diag; 1262416022c9SBarry Smith a->j[a->i[rows[i]]+shift] = rows[i]+shift; 12637ae801bdSBarry Smith } else { /* in case row was completely empty */ 1264d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 126517ab2063SBarry Smith } 126617ab2063SBarry Smith } 12673a40ed3dSBarry Smith } else { 126817ab2063SBarry Smith for ( i=0; i<N; i++ ) { 1269a8c6a408SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"row out of range"); 1270416022c9SBarry Smith a->ilen[rows[i]] = 0; 127117ab2063SBarry Smith } 127217ab2063SBarry Smith } 12737ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 127443a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12753a40ed3dSBarry Smith PetscFunctionReturn(0); 127617ab2063SBarry Smith } 127717ab2063SBarry Smith 12785615d1e5SSatish Balay #undef __FUNC__ 12795615d1e5SSatish Balay #define __FUNC__ "MatGetSize_SeqAIJ" 12808f6be9afSLois Curfman McInnes int MatGetSize_SeqAIJ(Mat A,int *m,int *n) 128117ab2063SBarry Smith { 1282416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12833a40ed3dSBarry Smith 12843a40ed3dSBarry Smith PetscFunctionBegin; 12850752156aSBarry Smith if (m) *m = a->m; 12860752156aSBarry Smith if (n) *n = a->n; 12873a40ed3dSBarry Smith PetscFunctionReturn(0); 128817ab2063SBarry Smith } 128917ab2063SBarry Smith 12905615d1e5SSatish Balay #undef __FUNC__ 12915615d1e5SSatish Balay #define __FUNC__ "MatGetOwnershipRange_SeqAIJ" 12928f6be9afSLois Curfman McInnes int MatGetOwnershipRange_SeqAIJ(Mat A,int *m,int *n) 129317ab2063SBarry Smith { 1294416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 12953a40ed3dSBarry Smith 12963a40ed3dSBarry Smith PetscFunctionBegin; 1297416022c9SBarry Smith *m = 0; *n = a->m; 12983a40ed3dSBarry Smith PetscFunctionReturn(0); 129917ab2063SBarry Smith } 1300026e39d0SSatish Balay 13015615d1e5SSatish Balay #undef __FUNC__ 13025615d1e5SSatish Balay #define __FUNC__ "MatGetRow_SeqAIJ" 13034e093b46SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 130417ab2063SBarry Smith { 1305416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1306c456f294SBarry Smith int *itmp,i,shift = a->indexshift; 130717ab2063SBarry Smith 13083a40ed3dSBarry Smith PetscFunctionBegin; 1309a8c6a408SBarry Smith if (row < 0 || row >= a->m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Row out of range"); 131017ab2063SBarry Smith 1311416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1312416022c9SBarry Smith if (v) *v = a->a + a->i[row] + shift; 131317ab2063SBarry Smith if (idx) { 1314416022c9SBarry Smith itmp = a->j + a->i[row] + shift; 13154e093b46SBarry Smith if (*nz && shift) { 13160452661fSBarry Smith *idx = (int *) PetscMalloc( (*nz)*sizeof(int) );CHKPTRQ(*idx); 131717ab2063SBarry Smith for ( i=0; i<(*nz); i++ ) {(*idx)[i] = itmp[i] + shift;} 13184e093b46SBarry Smith } else if (*nz) { 13194e093b46SBarry Smith *idx = itmp; 132017ab2063SBarry Smith } 132117ab2063SBarry Smith else *idx = 0; 132217ab2063SBarry Smith } 13233a40ed3dSBarry Smith PetscFunctionReturn(0); 132417ab2063SBarry Smith } 132517ab2063SBarry Smith 13265615d1e5SSatish Balay #undef __FUNC__ 13275615d1e5SSatish Balay #define __FUNC__ "MatRestoreRow_SeqAIJ" 13284e093b46SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,Scalar **v) 132917ab2063SBarry Smith { 13304e093b46SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1331606d414cSSatish Balay int ierr; 13323a40ed3dSBarry Smith 13333a40ed3dSBarry Smith PetscFunctionBegin; 1334606d414cSSatish Balay if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} 13353a40ed3dSBarry Smith PetscFunctionReturn(0); 133617ab2063SBarry Smith } 133717ab2063SBarry Smith 13385615d1e5SSatish Balay #undef __FUNC__ 13395615d1e5SSatish Balay #define __FUNC__ "MatNorm_SeqAIJ" 13408f6be9afSLois Curfman McInnes int MatNorm_SeqAIJ(Mat A,NormType type,double *norm) 134117ab2063SBarry Smith { 1342416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1343416022c9SBarry Smith Scalar *v = a->a; 134417ab2063SBarry Smith double sum = 0.0; 1345549d3d68SSatish Balay int i, j,shift = a->indexshift,ierr; 134617ab2063SBarry Smith 13473a40ed3dSBarry Smith PetscFunctionBegin; 134817ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1349416022c9SBarry Smith for (i=0; i<a->nz; i++ ) { 1350aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1351e20fef11SSatish Balay sum += PetscReal(PetscConj(*v)*(*v)); v++; 135217ab2063SBarry Smith #else 135317ab2063SBarry Smith sum += (*v)*(*v); v++; 135417ab2063SBarry Smith #endif 135517ab2063SBarry Smith } 135617ab2063SBarry Smith *norm = sqrt(sum); 13573a40ed3dSBarry Smith } else if (type == NORM_1) { 135817ab2063SBarry Smith double *tmp; 1359416022c9SBarry Smith int *jj = a->j; 136066963ce1SSatish Balay tmp = (double *) PetscMalloc( (a->n+1)*sizeof(double) );CHKPTRQ(tmp); 1361549d3d68SSatish Balay ierr = PetscMemzero(tmp,a->n*sizeof(double));CHKERRQ(ierr); 136217ab2063SBarry Smith *norm = 0.0; 1363416022c9SBarry Smith for ( j=0; j<a->nz; j++ ) { 1364a2744918SBarry Smith tmp[*jj++ + shift] += PetscAbsScalar(*v); v++; 136517ab2063SBarry Smith } 1366416022c9SBarry Smith for ( j=0; j<a->n; j++ ) { 136717ab2063SBarry Smith if (tmp[j] > *norm) *norm = tmp[j]; 136817ab2063SBarry Smith } 1369606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13703a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 137117ab2063SBarry Smith *norm = 0.0; 1372416022c9SBarry Smith for ( j=0; j<a->m; j++ ) { 1373416022c9SBarry Smith v = a->a + a->i[j] + shift; 137417ab2063SBarry Smith sum = 0.0; 1375416022c9SBarry Smith for ( i=0; i<a->i[j+1]-a->i[j]; i++ ) { 1376cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 137717ab2063SBarry Smith } 137817ab2063SBarry Smith if (sum > *norm) *norm = sum; 137917ab2063SBarry Smith } 13803a40ed3dSBarry Smith } else { 1381a8c6a408SBarry Smith SETERRQ(PETSC_ERR_SUP,0,"No support for two norm"); 138217ab2063SBarry Smith } 13833a40ed3dSBarry Smith PetscFunctionReturn(0); 138417ab2063SBarry Smith } 138517ab2063SBarry Smith 13865615d1e5SSatish Balay #undef __FUNC__ 13875615d1e5SSatish Balay #define __FUNC__ "MatTranspose_SeqAIJ" 13888f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 138917ab2063SBarry Smith { 1390416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1391416022c9SBarry Smith Mat C; 1392416022c9SBarry Smith int i, ierr, *aj = a->j, *ai = a->i, m = a->m, len, *col; 1393416022c9SBarry Smith int shift = a->indexshift; 1394d5d45c9bSBarry Smith Scalar *array = a->a; 139517ab2063SBarry Smith 13963a40ed3dSBarry Smith PetscFunctionBegin; 1397a8c6a408SBarry Smith if (B == PETSC_NULL && m != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Square matrix only for in-place"); 13980452661fSBarry Smith col = (int *) PetscMalloc((1+a->n)*sizeof(int));CHKPTRQ(col); 1399549d3d68SSatish Balay ierr = PetscMemzero(col,(1+a->n)*sizeof(int));CHKERRQ(ierr); 140017ab2063SBarry Smith if (shift) { 140117ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] -= 1; 140217ab2063SBarry Smith } 140317ab2063SBarry Smith for ( i=0; i<ai[m]+shift; i++ ) col[aj[i]] += 1; 1404416022c9SBarry Smith ierr = MatCreateSeqAIJ(A->comm,a->n,m,0,col,&C);CHKERRQ(ierr); 1405606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 140617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 140717ab2063SBarry Smith len = ai[i+1]-ai[i]; 1408416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 140917ab2063SBarry Smith array += len; aj += len; 141017ab2063SBarry Smith } 141117ab2063SBarry Smith if (shift) { 141217ab2063SBarry Smith for ( i=0; i<ai[m]-1; i++ ) aj[i] += 1; 141317ab2063SBarry Smith } 141417ab2063SBarry Smith 14156d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14166d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 141717ab2063SBarry Smith 14183638b69dSLois Curfman McInnes if (B != PETSC_NULL) { 1419416022c9SBarry Smith *B = C; 142017ab2063SBarry Smith } else { 1421f830108cSBarry Smith PetscOps *Abops; 14220a6ffc59SBarry Smith MatOps Aops; 1423f830108cSBarry Smith 1424416022c9SBarry Smith /* This isn't really an in-place transpose */ 1425606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 1426606d414cSSatish Balay if (!a->singlemalloc) { 1427606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 1428606d414cSSatish Balay ierr = PetscFree(a->j); 1429606d414cSSatish Balay } 1430606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 1431606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 1432606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 1433606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 1434606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 1435606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 1436f830108cSBarry Smith 1437488ecbafSBarry Smith 1438488ecbafSBarry Smith ierr = MapDestroy(A->rmap);CHKERRQ(ierr); 1439488ecbafSBarry Smith ierr = MapDestroy(A->cmap);CHKERRQ(ierr); 1440488ecbafSBarry Smith 1441f830108cSBarry Smith /* 1442f830108cSBarry Smith This is horrible, horrible code. We need to keep the 14438f0f457cSSatish Balay the bops and ops Structures, copy everything from C 14448f0f457cSSatish Balay including the function pointers.. 1445f830108cSBarry Smith */ 1446549d3d68SSatish Balay ierr = PetscMemcpy(A->ops,C->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 1447549d3d68SSatish Balay ierr = PetscMemcpy(A->bops,C->bops,sizeof(PetscOps));CHKERRQ(ierr); 1448f830108cSBarry Smith Abops = A->bops; 1449f830108cSBarry Smith Aops = A->ops; 1450549d3d68SSatish Balay ierr = PetscMemcpy(A,C,sizeof(struct _p_Mat));CHKERRQ(ierr); 1451f830108cSBarry Smith A->bops = Abops; 1452f830108cSBarry Smith A->ops = Aops; 145327a8da17SBarry Smith A->qlist = 0; 1454f830108cSBarry Smith 14550452661fSBarry Smith PetscHeaderDestroy(C); 145617ab2063SBarry Smith } 14573a40ed3dSBarry Smith PetscFunctionReturn(0); 145817ab2063SBarry Smith } 145917ab2063SBarry Smith 14605615d1e5SSatish Balay #undef __FUNC__ 14615615d1e5SSatish Balay #define __FUNC__ "MatDiagonalScale_SeqAIJ" 14628f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 146317ab2063SBarry Smith { 1464416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 146517ab2063SBarry Smith Scalar *l,*r,x,*v; 1466e1311b90SBarry Smith int ierr,i,j,m = a->m, n = a->n, M, nz = a->nz, *jj,shift = a->indexshift; 146717ab2063SBarry Smith 14683a40ed3dSBarry Smith PetscFunctionBegin; 146917ab2063SBarry Smith if (ll) { 14703ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 14713ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1472e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1473a8c6a408SBarry Smith if (m != a->m) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Left scaling vector wrong length"); 1474e1311b90SBarry Smith ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1475416022c9SBarry Smith v = a->a; 147617ab2063SBarry Smith for ( i=0; i<m; i++ ) { 147717ab2063SBarry Smith x = l[i]; 1478416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 147917ab2063SBarry Smith for ( j=0; j<M; j++ ) { (*v++) *= x;} 148017ab2063SBarry Smith } 1481e1311b90SBarry Smith ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 148244cd7ae7SLois Curfman McInnes PLogFlops(nz); 148317ab2063SBarry Smith } 148417ab2063SBarry Smith if (rr) { 1485e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1486a8c6a408SBarry Smith if (n != a->n) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Right scaling vector wrong length"); 1487e1311b90SBarry Smith ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1488416022c9SBarry Smith v = a->a; jj = a->j; 148917ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 149017ab2063SBarry Smith (*v++) *= r[*jj++ + shift]; 149117ab2063SBarry Smith } 1492e1311b90SBarry Smith ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 149344cd7ae7SLois Curfman McInnes PLogFlops(nz); 149417ab2063SBarry Smith } 14953a40ed3dSBarry Smith PetscFunctionReturn(0); 149617ab2063SBarry Smith } 149717ab2063SBarry Smith 14985615d1e5SSatish Balay #undef __FUNC__ 14995615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrix_SeqAIJ" 15007b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 150117ab2063SBarry Smith { 1502db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data,*c; 1503d5db1b72SBarry Smith int *smap, i, k, kstart, kend, ierr, oldcols = a->n,*lens; 150499141d43SSatish Balay int row,mat_i,*mat_j,tcol,first,step,*mat_ilen; 1505a2744918SBarry Smith register int sum,lensi; 150699141d43SSatish Balay int *irow, *icol, nrows, ncols, shift = a->indexshift,*ssmap; 150799141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j, *ai = a->i,ii,*ailen = a->ilen; 150899141d43SSatish Balay Scalar *a_new,*mat_a; 1509416022c9SBarry Smith Mat C; 1510fee21e36SBarry Smith PetscTruth stride; 151117ab2063SBarry Smith 15123a40ed3dSBarry Smith PetscFunctionBegin; 1513d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 1514a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"ISrow is not sorted"); 1515d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 1516a8c6a408SBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"IScol is not sorted"); 151799141d43SSatish Balay 151817ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 151917ab2063SBarry Smith ierr = ISGetSize(isrow,&nrows);CHKERRQ(ierr); 152017ab2063SBarry Smith ierr = ISGetSize(iscol,&ncols);CHKERRQ(ierr); 152117ab2063SBarry Smith 1522fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1523fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1524fee21e36SBarry Smith if (stride && step == 1) { 152502834360SBarry Smith /* special case of contiguous rows */ 152657faeb66SBarry Smith lens = (int *) PetscMalloc((ncols+nrows+1)*sizeof(int));CHKPTRQ(lens); 152702834360SBarry Smith starts = lens + ncols; 152802834360SBarry Smith /* loop over new rows determining lens and starting points */ 152902834360SBarry Smith for (i=0; i<nrows; i++) { 1530a2744918SBarry Smith kstart = ai[irow[i]]+shift; 1531a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 153202834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1533d8ced48eSBarry Smith if (aj[k]+shift >= first) { 153402834360SBarry Smith starts[i] = k; 153502834360SBarry Smith break; 153602834360SBarry Smith } 153702834360SBarry Smith } 1538a2744918SBarry Smith sum = 0; 153902834360SBarry Smith while (k < kend) { 1540d8ced48eSBarry Smith if (aj[k++]+shift >= first+ncols) break; 1541a2744918SBarry Smith sum++; 154202834360SBarry Smith } 1543a2744918SBarry Smith lens[i] = sum; 154402834360SBarry Smith } 154502834360SBarry Smith /* create submatrix */ 1546cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 154708480c60SBarry Smith int n_cols,n_rows; 154808480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 1549a8c6a408SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Reused submatrix wrong size"); 1550d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 155108480c60SBarry Smith C = *B; 15523a40ed3dSBarry Smith } else { 155302834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 155408480c60SBarry Smith } 1555db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*) C->data; 1556db02288aSLois Curfman McInnes 155702834360SBarry Smith /* loop over rows inserting into submatrix */ 1558db02288aSLois Curfman McInnes a_new = c->a; 1559db02288aSLois Curfman McInnes j_new = c->j; 1560db02288aSLois Curfman McInnes i_new = c->i; 1561db02288aSLois Curfman McInnes i_new[0] = -shift; 156202834360SBarry Smith for (i=0; i<nrows; i++) { 1563a2744918SBarry Smith ii = starts[i]; 1564a2744918SBarry Smith lensi = lens[i]; 1565a2744918SBarry Smith for ( k=0; k<lensi; k++ ) { 1566a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 156702834360SBarry Smith } 1568549d3d68SSatish Balay ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(Scalar));CHKERRQ(ierr); 1569a2744918SBarry Smith a_new += lensi; 1570a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1571a2744918SBarry Smith c->ilen[i] = lensi; 157202834360SBarry Smith } 1573606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 15743a40ed3dSBarry Smith } else { 157502834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 15760452661fSBarry Smith smap = (int *) PetscMalloc((1+oldcols)*sizeof(int));CHKPTRQ(smap); 157702834360SBarry Smith ssmap = smap + shift; 157899141d43SSatish Balay lens = (int *) PetscMalloc((1+nrows)*sizeof(int));CHKPTRQ(lens); 1579549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 158017ab2063SBarry Smith for ( i=0; i<ncols; i++ ) smap[icol[i]] = i+1; 158102834360SBarry Smith /* determine lens of each row */ 158202834360SBarry Smith for (i=0; i<nrows; i++) { 1583d8ced48eSBarry Smith kstart = ai[irow[i]]+shift; 158402834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 158502834360SBarry Smith lens[i] = 0; 158602834360SBarry Smith for ( k=kstart; k<kend; k++ ) { 1587d8ced48eSBarry Smith if (ssmap[aj[k]]) { 158802834360SBarry Smith lens[i]++; 158902834360SBarry Smith } 159002834360SBarry Smith } 159102834360SBarry Smith } 159217ab2063SBarry Smith /* Create and fill new matrix */ 1593a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 15940f5bd95cSBarry Smith PetscTruth equal; 15950f5bd95cSBarry Smith 159699141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1597a8c6a408SBarry Smith if (c->m != nrows || c->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong size"); 15980f5bd95cSBarry Smith ierr = PetscMemcmp(c->ilen,lens, c->m*sizeof(int),&equal);CHKERRQ(ierr); 15990f5bd95cSBarry Smith if (!equal) { 1600a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,0,"Cannot reuse matrix. wrong no of nonzeros"); 160199141d43SSatish Balay } 1602549d3d68SSatish Balay ierr = PetscMemzero(c->ilen,c->m*sizeof(int));CHKERRQ(ierr); 160308480c60SBarry Smith C = *B; 16043a40ed3dSBarry Smith } else { 160502834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 160608480c60SBarry Smith } 160799141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 160817ab2063SBarry Smith for (i=0; i<nrows; i++) { 160999141d43SSatish Balay row = irow[i]; 161099141d43SSatish Balay kstart = ai[row]+shift; 161199141d43SSatish Balay kend = kstart + a->ilen[row]; 161299141d43SSatish Balay mat_i = c->i[i]+shift; 161399141d43SSatish Balay mat_j = c->j + mat_i; 161499141d43SSatish Balay mat_a = c->a + mat_i; 161599141d43SSatish Balay mat_ilen = c->ilen + i; 161617ab2063SBarry Smith for ( k=kstart; k<kend; k++ ) { 161799141d43SSatish Balay if ((tcol=ssmap[a->j[k]])) { 161899141d43SSatish Balay *mat_j++ = tcol - (!shift); 161999141d43SSatish Balay *mat_a++ = a->a[k]; 162099141d43SSatish Balay (*mat_ilen)++; 162199141d43SSatish Balay 162217ab2063SBarry Smith } 162317ab2063SBarry Smith } 162417ab2063SBarry Smith } 162502834360SBarry Smith /* Free work space */ 162602834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1627606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1628606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 162902834360SBarry Smith } 16306d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16316d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 163217ab2063SBarry Smith 163317ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1634416022c9SBarry Smith *B = C; 16353a40ed3dSBarry Smith PetscFunctionReturn(0); 163617ab2063SBarry Smith } 163717ab2063SBarry Smith 1638a871dcd8SBarry Smith /* 1639a871dcd8SBarry Smith */ 16405615d1e5SSatish Balay #undef __FUNC__ 16415615d1e5SSatish Balay #define __FUNC__ "MatILUFactor_SeqAIJ" 16425ef9f2a5SBarry Smith int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatILUInfo *info) 1643a871dcd8SBarry Smith { 164463b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 164508480c60SBarry Smith int ierr; 164663b91edcSBarry Smith Mat outA; 1647b8a78c4aSBarry Smith PetscTruth row_identity, col_identity; 164863b91edcSBarry Smith 16493a40ed3dSBarry Smith PetscFunctionBegin; 1650b8a78c4aSBarry Smith if (info && info->levels != 0) SETERRQ(PETSC_ERR_SUP,0,"Only levels=0 supported for in-place ilu"); 1651b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1652b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1653b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 1654b8a78c4aSBarry Smith SETERRQ(1,1,"Row and column permutations must be identity for in-place ILU"); 1655b8a78c4aSBarry Smith } 1656a871dcd8SBarry Smith 165763b91edcSBarry Smith outA = inA; 165863b91edcSBarry Smith inA->factor = FACTOR_LU; 165963b91edcSBarry Smith a->row = row; 166063b91edcSBarry Smith a->col = col; 166163b91edcSBarry Smith 1662f0ec6fceSSatish Balay /* Create the invert permutation so that it can be used in MatLUFactorNumeric() */ 1663f0ec6fceSSatish Balay ierr = ISInvertPermutation(col,&(a->icol));CHKERRQ(ierr); 16641e4dd532SSatish Balay PLogObjectParent(inA,a->icol); 1665f0ec6fceSSatish Balay 166694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 16670452661fSBarry Smith a->solve_work = (Scalar *) PetscMalloc( (a->m+1)*sizeof(Scalar));CHKPTRQ(a->solve_work); 166894a9d846SBarry Smith } 166963b91edcSBarry Smith 167008480c60SBarry Smith if (!a->diag) { 167108480c60SBarry Smith ierr = MatMarkDiag_SeqAIJ(inA);CHKERRQ(ierr); 167263b91edcSBarry Smith } 167363b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 16743a40ed3dSBarry Smith PetscFunctionReturn(0); 1675a871dcd8SBarry Smith } 1676a871dcd8SBarry Smith 167774cdf0dfSBarry Smith #include "pinclude/blaslapack.h" 16785615d1e5SSatish Balay #undef __FUNC__ 16795615d1e5SSatish Balay #define __FUNC__ "MatScale_SeqAIJ" 16808f6be9afSLois Curfman McInnes int MatScale_SeqAIJ(Scalar *alpha,Mat inA) 1681f0b747eeSBarry Smith { 1682f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) inA->data; 1683f0b747eeSBarry Smith int one = 1; 16843a40ed3dSBarry Smith 16853a40ed3dSBarry Smith PetscFunctionBegin; 1686f0b747eeSBarry Smith BLscal_( &a->nz, alpha, a->a, &one ); 1687f0b747eeSBarry Smith PLogFlops(a->nz); 16883a40ed3dSBarry Smith PetscFunctionReturn(0); 1689f0b747eeSBarry Smith } 1690f0b747eeSBarry Smith 16915615d1e5SSatish Balay #undef __FUNC__ 16925615d1e5SSatish Balay #define __FUNC__ "MatGetSubMatrices_SeqAIJ" 16937b2a1423SBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n, IS *irow,IS *icol,MatReuse scall,Mat **B) 1694cddf8d76SBarry Smith { 1695cddf8d76SBarry Smith int ierr,i; 1696cddf8d76SBarry Smith 16973a40ed3dSBarry Smith PetscFunctionBegin; 1698cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 16990452661fSBarry Smith *B = (Mat *) PetscMalloc( (n+1)*sizeof(Mat) );CHKPTRQ(*B); 1700cddf8d76SBarry Smith } 1701cddf8d76SBarry Smith 1702cddf8d76SBarry Smith for ( i=0; i<n; i++ ) { 17036a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1704cddf8d76SBarry Smith } 17053a40ed3dSBarry Smith PetscFunctionReturn(0); 1706cddf8d76SBarry Smith } 1707cddf8d76SBarry Smith 17085615d1e5SSatish Balay #undef __FUNC__ 17095615d1e5SSatish Balay #define __FUNC__ "MatGetBlockSize_SeqAIJ" 17108f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A, int *bs) 17115a838052SSatish Balay { 1712f830108cSBarry Smith PetscFunctionBegin; 17135a838052SSatish Balay *bs = 1; 17143a40ed3dSBarry Smith PetscFunctionReturn(0); 17155a838052SSatish Balay } 17165a838052SSatish Balay 17175615d1e5SSatish Balay #undef __FUNC__ 17185615d1e5SSatish Balay #define __FUNC__ "MatIncreaseOverlap_SeqAIJ" 17198f6be9afSLois Curfman McInnes int MatIncreaseOverlap_SeqAIJ(Mat A, int is_max, IS *is, int ov) 17204dcbc457SBarry Smith { 1721e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 172206763907SSatish Balay int shift, row, i,j,k,l,m,n, *idx,ierr, *nidx, isz, val; 17238a047759SSatish Balay int start, end, *ai, *aj; 1724*6831982aSBarry Smith BTPetsc table; 1725bbd702dbSSatish Balay 17263a40ed3dSBarry Smith PetscFunctionBegin; 17278a047759SSatish Balay shift = a->indexshift; 1728e4d965acSSatish Balay m = a->m; 1729e4d965acSSatish Balay ai = a->i; 17308a047759SSatish Balay aj = a->j+shift; 17318a047759SSatish Balay 1732a8c6a408SBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"illegal overlap value used"); 173306763907SSatish Balay 173406763907SSatish Balay nidx = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(nidx); 1735*6831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 173606763907SSatish Balay 1737e4d965acSSatish Balay for ( i=0; i<is_max; i++ ) { 1738b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1739e4d965acSSatish Balay isz = 0; 1740*6831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1741e4d965acSSatish Balay 1742e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17434dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 174477c4ece6SBarry Smith ierr = ISGetSize(is[i],&n);CHKERRQ(ierr); 1745e4d965acSSatish Balay 1746dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1747e4d965acSSatish Balay for ( j=0; j<n ; ++j){ 1748*6831982aSBarry Smith if(!PetscBTLoopupSet(table, idx[j])) { nidx[isz++] = idx[j];} 17494dcbc457SBarry Smith } 175006763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 175106763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1752e4d965acSSatish Balay 175304a348a9SBarry Smith k = 0; 175404a348a9SBarry Smith for ( j=0; j<ov; j++){ /* for each overlap */ 175504a348a9SBarry Smith n = isz; 175606763907SSatish Balay for ( ; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1757e4d965acSSatish Balay row = nidx[k]; 1758e4d965acSSatish Balay start = ai[row]; 1759e4d965acSSatish Balay end = ai[row+1]; 176004a348a9SBarry Smith for ( l = start; l<end ; l++){ 17618a047759SSatish Balay val = aj[l] + shift; 1762*6831982aSBarry Smith if (!PetscBTLoopupSet(table,val)) {nidx[isz++] = val;} 1763e4d965acSSatish Balay } 1764e4d965acSSatish Balay } 1765e4d965acSSatish Balay } 1766029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF, isz, nidx, (is+i));CHKERRQ(ierr); 1767e4d965acSSatish Balay } 1768*6831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1769606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 17703a40ed3dSBarry Smith PetscFunctionReturn(0); 17714dcbc457SBarry Smith } 177217ab2063SBarry Smith 17730513a670SBarry Smith /* -------------------------------------------------------------- */ 17740513a670SBarry Smith #undef __FUNC__ 17750513a670SBarry Smith #define __FUNC__ "MatPermute_SeqAIJ" 17760513a670SBarry Smith int MatPermute_SeqAIJ(Mat A, IS rowp, IS colp, Mat *B) 17770513a670SBarry Smith { 17780513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 17790513a670SBarry Smith Scalar *vwork; 17800513a670SBarry Smith int i, ierr, nz, m = a->m, n = a->n, *cwork; 17810513a670SBarry Smith int *row,*col,*cnew,j,*lens; 178256cd22aeSBarry Smith IS icolp,irowp; 17830513a670SBarry Smith 17843a40ed3dSBarry Smith PetscFunctionBegin; 178556cd22aeSBarry Smith ierr = ISInvertPermutation(rowp,&irowp);CHKERRQ(ierr); 178656cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 178756cd22aeSBarry Smith ierr = ISInvertPermutation(colp,&icolp);CHKERRQ(ierr); 178856cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 17890513a670SBarry Smith 17900513a670SBarry Smith /* determine lengths of permuted rows */ 17910513a670SBarry Smith lens = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(lens); 17920513a670SBarry Smith for (i=0; i<m; i++ ) { 17930513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 17940513a670SBarry Smith } 17950513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1796606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 17970513a670SBarry Smith 17980513a670SBarry Smith cnew = (int *) PetscMalloc( n*sizeof(int) );CHKPTRQ(cnew); 17990513a670SBarry Smith for (i=0; i<m; i++) { 18000513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18010513a670SBarry Smith for (j=0; j<nz; j++ ) { cnew[j] = col[cwork[j]];} 18020513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 18030513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18040513a670SBarry Smith } 1805606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18060513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18070513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180856cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 180956cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 181056cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 181156cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18123a40ed3dSBarry Smith PetscFunctionReturn(0); 18130513a670SBarry Smith } 18140513a670SBarry Smith 18155615d1e5SSatish Balay #undef __FUNC__ 18165615d1e5SSatish Balay #define __FUNC__ "MatPrintHelp_SeqAIJ" 1817682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1818682d7d0cSBarry Smith { 1819682d7d0cSBarry Smith static int called = 0; 1820682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1821d132466eSBarry Smith int ierr; 1822682d7d0cSBarry Smith 18233a40ed3dSBarry Smith PetscFunctionBegin; 18243a40ed3dSBarry Smith if (called) {PetscFunctionReturn(0);} else called = 1; 1825d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1826d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1827d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1828d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1829d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 1830aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL) 1831d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1832682d7d0cSBarry Smith #endif 18333a40ed3dSBarry Smith PetscFunctionReturn(0); 1834682d7d0cSBarry Smith } 18358f6be9afSLois Curfman McInnes extern int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg); 1836a93ec695SBarry Smith extern int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1837a93ec695SBarry Smith extern int MatColoringPatch_SeqAIJ(Mat,int,int *,ISColoring *); 1838a93ec695SBarry Smith 1839cb5b572fSBarry Smith #undef __FUNC__ 1840cb5b572fSBarry Smith #define __FUNC__ "MatCopy_SeqAIJ" 1841cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1842cb5b572fSBarry Smith { 1843be6bf707SBarry Smith int ierr; 1844cb5b572fSBarry Smith 1845cb5b572fSBarry Smith PetscFunctionBegin; 1846be6bf707SBarry Smith if (str == SAME_NONZERO_PATTERN && B->type == MATSEQAIJ) { 1847be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) A->data; 1848be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ *) B->data; 1849be6bf707SBarry Smith 1850be6bf707SBarry Smith if (a->i[a->m]+a->indexshift != b->i[b->m]+a->indexshift) { 1851be6bf707SBarry Smith SETERRQ(1,1,"Number of nonzeros in two matrices are different"); 1852cb5b572fSBarry Smith } 1853549d3d68SSatish Balay ierr = PetscMemcpy(b->a,a->a,(a->i[a->m]+a->indexshift)*sizeof(Scalar));CHKERRQ(ierr); 1854cb5b572fSBarry Smith } else { 1855cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1856cb5b572fSBarry Smith } 1857cb5b572fSBarry Smith PetscFunctionReturn(0); 1858cb5b572fSBarry Smith } 1859cb5b572fSBarry Smith 1860682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 18610a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 1862cb5b572fSBarry Smith MatGetRow_SeqAIJ, 1863cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 1864cb5b572fSBarry Smith MatMult_SeqAIJ, 1865cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 1866cb5b572fSBarry Smith MatMultTrans_SeqAIJ, 1867cb5b572fSBarry Smith MatMultTransAdd_SeqAIJ, 1868cb5b572fSBarry Smith MatSolve_SeqAIJ, 1869cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 1870cb5b572fSBarry Smith MatSolveTrans_SeqAIJ, 1871cb5b572fSBarry Smith MatSolveTransAdd_SeqAIJ, 1872cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 1873cb5b572fSBarry Smith 0, 187417ab2063SBarry Smith MatRelax_SeqAIJ, 187517ab2063SBarry Smith MatTranspose_SeqAIJ, 1876cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 1877cb5b572fSBarry Smith MatEqual_SeqAIJ, 1878cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 1879cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 1880cb5b572fSBarry Smith MatNorm_SeqAIJ, 1881cb5b572fSBarry Smith 0, 1882cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 188317ab2063SBarry Smith MatCompress_SeqAIJ, 1884cb5b572fSBarry Smith MatSetOption_SeqAIJ, 1885cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 1886cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 1887cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 1888cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 1889cb5b572fSBarry Smith 0, 1890cb5b572fSBarry Smith 0, 1891cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1892cb5b572fSBarry Smith MatGetSize_SeqAIJ, 1893cb5b572fSBarry Smith MatGetOwnershipRange_SeqAIJ, 1894cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 1895cb5b572fSBarry Smith 0, 1896cb5b572fSBarry Smith 0, 1897cb5b572fSBarry Smith 0, 1898be6bf707SBarry Smith MatDuplicate_SeqAIJ, 1899cb5b572fSBarry Smith 0, 1900cb5b572fSBarry Smith 0, 1901cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 1902cb5b572fSBarry Smith 0, 1903cb5b572fSBarry Smith 0, 1904cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 1905cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 1906cb5b572fSBarry Smith MatGetValues_SeqAIJ, 1907cb5b572fSBarry Smith MatCopy_SeqAIJ, 1908f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 1909cb5b572fSBarry Smith MatScale_SeqAIJ, 1910cb5b572fSBarry Smith 0, 1911cb5b572fSBarry Smith 0, 19126945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 19136945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 19143b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 19153b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 19163b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 1917a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 1918a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 19190513a670SBarry Smith MatColoringPatch_SeqAIJ, 19200513a670SBarry Smith 0, 1921cda55fadSBarry Smith MatPermute_SeqAIJ, 1922cda55fadSBarry Smith 0, 1923cda55fadSBarry Smith 0, 1924cda55fadSBarry Smith 0, 1925cda55fadSBarry Smith 0, 1926cda55fadSBarry Smith MatGetMaps_Petsc}; 192717ab2063SBarry Smith 192817ab2063SBarry Smith extern int MatUseSuperLU_SeqAIJ(Mat); 192917ab2063SBarry Smith extern int MatUseEssl_SeqAIJ(Mat); 193017ab2063SBarry Smith extern int MatUseDXML_SeqAIJ(Mat); 193117ab2063SBarry Smith 1932fb2e594dSBarry Smith EXTERN_C_BEGIN 19335615d1e5SSatish Balay #undef __FUNC__ 1934bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices_SeqAIJ" 193515091d37SBarry Smith 1936bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 1937bef8e0ddSBarry Smith { 1938bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 1939bef8e0ddSBarry Smith int i,nz,n; 1940bef8e0ddSBarry Smith 1941bef8e0ddSBarry Smith PetscFunctionBegin; 1942bef8e0ddSBarry Smith if (aij->indexshift) SETERRQ(1,1,"No support with 1 based indexing"); 1943bef8e0ddSBarry Smith 1944bef8e0ddSBarry Smith nz = aij->maxnz; 1945bef8e0ddSBarry Smith n = aij->n; 1946bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 1947bef8e0ddSBarry Smith aij->j[i] = indices[i]; 1948bef8e0ddSBarry Smith } 1949bef8e0ddSBarry Smith aij->nz = nz; 1950bef8e0ddSBarry Smith for ( i=0; i<n; i++ ) { 1951bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 1952bef8e0ddSBarry Smith } 1953bef8e0ddSBarry Smith 1954bef8e0ddSBarry Smith PetscFunctionReturn(0); 1955bef8e0ddSBarry Smith } 1956fb2e594dSBarry Smith EXTERN_C_END 1957bef8e0ddSBarry Smith 1958bef8e0ddSBarry Smith #undef __FUNC__ 1959bef8e0ddSBarry Smith #define __FUNC__ "MatSeqAIJSetColumnIndices" 1960bef8e0ddSBarry Smith /*@ 1961bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 1962bef8e0ddSBarry Smith in the matrix. 1963bef8e0ddSBarry Smith 1964bef8e0ddSBarry Smith Input Parameters: 1965bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 1966bef8e0ddSBarry Smith - indices - the column indices 1967bef8e0ddSBarry Smith 196815091d37SBarry Smith Level: advanced 196915091d37SBarry Smith 1970bef8e0ddSBarry Smith Notes: 1971bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 1972bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 1973bef8e0ddSBarry Smith of the MatSetValues() operation. 1974bef8e0ddSBarry Smith 1975bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 1976bef8e0ddSBarry Smith MatCreateSeqAIJ(). 1977bef8e0ddSBarry Smith 1978bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 1979bef8e0ddSBarry Smith 1980bef8e0ddSBarry Smith @*/ 1981bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 1982bef8e0ddSBarry Smith { 1983bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 1984bef8e0ddSBarry Smith 1985bef8e0ddSBarry Smith PetscFunctionBegin; 1986bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 1987549d3d68SSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void **)&f);CHKERRQ(ierr); 1988bef8e0ddSBarry Smith if (f) { 1989bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 1990bef8e0ddSBarry Smith } else { 1991bef8e0ddSBarry Smith SETERRQ(1,1,"Wrong type of matrix to set column indices"); 1992bef8e0ddSBarry Smith } 1993bef8e0ddSBarry Smith PetscFunctionReturn(0); 1994bef8e0ddSBarry Smith } 1995bef8e0ddSBarry Smith 1996be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 1997be6bf707SBarry Smith 1998fb2e594dSBarry Smith EXTERN_C_BEGIN 1999be6bf707SBarry Smith #undef __FUNC__ 2000be6bf707SBarry Smith #define __FUNC__ "MatStoreValues_SeqAIJ" 2001be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2002be6bf707SBarry Smith { 2003be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2004549d3d68SSatish Balay int nz = aij->i[aij->m]+aij->indexshift,ierr; 2005be6bf707SBarry Smith 2006be6bf707SBarry Smith PetscFunctionBegin; 2007be6bf707SBarry Smith if (aij->nonew != 1) { 2008be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2009be6bf707SBarry Smith } 2010be6bf707SBarry Smith 2011be6bf707SBarry Smith /* allocate space for values if not already there */ 2012be6bf707SBarry Smith if (!aij->saved_values) { 2013be6bf707SBarry Smith aij->saved_values = (Scalar *) PetscMalloc(nz*sizeof(Scalar));CHKPTRQ(aij->saved_values); 2014be6bf707SBarry Smith } 2015be6bf707SBarry Smith 2016be6bf707SBarry Smith /* copy values over */ 2017549d3d68SSatish Balay ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(Scalar));CHKERRQ(ierr); 2018be6bf707SBarry Smith PetscFunctionReturn(0); 2019be6bf707SBarry Smith } 2020fb2e594dSBarry Smith EXTERN_C_END 2021be6bf707SBarry Smith 2022be6bf707SBarry Smith #undef __FUNC__ 2023be6bf707SBarry Smith #define __FUNC__ "MatStoreValues" 2024be6bf707SBarry Smith /*@ 2025be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2026be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2027be6bf707SBarry Smith nonlinear portion. 2028be6bf707SBarry Smith 2029be6bf707SBarry Smith Collect on Mat 2030be6bf707SBarry Smith 2031be6bf707SBarry Smith Input Parameters: 2032be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2033be6bf707SBarry Smith 203415091d37SBarry Smith Level: advanced 203515091d37SBarry Smith 2036be6bf707SBarry Smith Common Usage, with SNESSolve(): 2037be6bf707SBarry Smith $ Create Jacobian matrix 2038be6bf707SBarry Smith $ Set linear terms into matrix 2039be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2040be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2041be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2042be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2043be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2044be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2045be6bf707SBarry Smith $ In your Jacobian routine 2046be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2047be6bf707SBarry Smith $ Set nonlinear terms in matrix 2048be6bf707SBarry Smith 2049be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2050be6bf707SBarry Smith $ // build linear portion of Jacobian 2051be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2052be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2053be6bf707SBarry Smith $ loop over nonlinear iterations 2054be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2055be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2056be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2057be6bf707SBarry Smith $ Solve linear system with Jacobian 2058be6bf707SBarry Smith $ endloop 2059be6bf707SBarry Smith 2060be6bf707SBarry Smith Notes: 2061be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2062be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2063be6bf707SBarry Smith calling this routine. 2064be6bf707SBarry Smith 2065be6bf707SBarry Smith .seealso: MatRetrieveValues() 2066be6bf707SBarry Smith 2067be6bf707SBarry Smith @*/ 2068be6bf707SBarry Smith int MatStoreValues(Mat mat) 2069be6bf707SBarry Smith { 2070be6bf707SBarry Smith int ierr,(*f)(Mat); 2071be6bf707SBarry Smith 2072be6bf707SBarry Smith PetscFunctionBegin; 2073be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2074be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2075be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2076be6bf707SBarry Smith 2077c5d6004cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void **)&f);CHKERRQ(ierr); 2078be6bf707SBarry Smith if (f) { 2079be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2080be6bf707SBarry Smith } else { 2081be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to store values"); 2082be6bf707SBarry Smith } 2083be6bf707SBarry Smith PetscFunctionReturn(0); 2084be6bf707SBarry Smith } 2085be6bf707SBarry Smith 2086fb2e594dSBarry Smith EXTERN_C_BEGIN 2087be6bf707SBarry Smith #undef __FUNC__ 2088be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues_SeqAIJ" 2089be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2090be6bf707SBarry Smith { 2091be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2092549d3d68SSatish Balay int nz = aij->i[aij->m]+aij->indexshift,ierr; 2093be6bf707SBarry Smith 2094be6bf707SBarry Smith PetscFunctionBegin; 2095be6bf707SBarry Smith if (aij->nonew != 1) { 2096be6bf707SBarry Smith SETERRQ(1,1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2097be6bf707SBarry Smith } 2098be6bf707SBarry Smith if (!aij->saved_values) { 2099be6bf707SBarry Smith SETERRQ(1,1,"Must call MatStoreValues(A);first"); 2100be6bf707SBarry Smith } 2101be6bf707SBarry Smith 2102be6bf707SBarry Smith /* copy values over */ 2103549d3d68SSatish Balay ierr = PetscMemcpy(aij->a, aij->saved_values,nz*sizeof(Scalar));CHKERRQ(ierr); 2104be6bf707SBarry Smith PetscFunctionReturn(0); 2105be6bf707SBarry Smith } 2106fb2e594dSBarry Smith EXTERN_C_END 2107be6bf707SBarry Smith 2108be6bf707SBarry Smith #undef __FUNC__ 2109be6bf707SBarry Smith #define __FUNC__ "MatRetrieveValues" 2110be6bf707SBarry Smith /*@ 2111be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2112be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2113be6bf707SBarry Smith nonlinear portion. 2114be6bf707SBarry Smith 2115be6bf707SBarry Smith Collect on Mat 2116be6bf707SBarry Smith 2117be6bf707SBarry Smith Input Parameters: 2118be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2119be6bf707SBarry Smith 212015091d37SBarry Smith Level: advanced 212115091d37SBarry Smith 2122be6bf707SBarry Smith .seealso: MatStoreValues() 2123be6bf707SBarry Smith 2124be6bf707SBarry Smith @*/ 2125be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2126be6bf707SBarry Smith { 2127be6bf707SBarry Smith int ierr,(*f)(Mat); 2128be6bf707SBarry Smith 2129be6bf707SBarry Smith PetscFunctionBegin; 2130be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2131be6bf707SBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for unassembled matrix"); 2132be6bf707SBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,0,"Not for factored matrix"); 2133be6bf707SBarry Smith 2134c5d6004cSBarry Smith ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void **)&f);CHKERRQ(ierr); 2135be6bf707SBarry Smith if (f) { 2136be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2137be6bf707SBarry Smith } else { 2138be6bf707SBarry Smith SETERRQ(1,1,"Wrong type of matrix to retrieve values"); 2139be6bf707SBarry Smith } 2140be6bf707SBarry Smith PetscFunctionReturn(0); 2141be6bf707SBarry Smith } 2142be6bf707SBarry Smith 2143be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 2144cb5b572fSBarry Smith 2145bef8e0ddSBarry Smith #undef __FUNC__ 21465615d1e5SSatish Balay #define __FUNC__ "MatCreateSeqAIJ" 214717ab2063SBarry Smith /*@C 2148682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 21490d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 21506e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 215151c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 21522bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 215317ab2063SBarry Smith 2154db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2155db81eaa0SLois Curfman McInnes 215617ab2063SBarry Smith Input Parameters: 2157db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 215817ab2063SBarry Smith . m - number of rows 215917ab2063SBarry Smith . n - number of columns 216017ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 216151c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 21622bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 216317ab2063SBarry Smith 216417ab2063SBarry Smith Output Parameter: 2165416022c9SBarry Smith . A - the matrix 216617ab2063SBarry Smith 2167b259b22eSLois Curfman McInnes Notes: 216817ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 216917ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 21700002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 217144cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 217217ab2063SBarry Smith 217317ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2174a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 21753d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 21766da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 217717ab2063SBarry Smith 2178682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 21794fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2180682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 21816c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 21826c7ebb05SLois Curfman McInnes 21836c7ebb05SLois Curfman McInnes Options Database Keys: 2184db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2185db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2186db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2187db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2188db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 218917ab2063SBarry Smith 2190027ccd11SLois Curfman McInnes Level: intermediate 2191027ccd11SLois Curfman McInnes 2192bef8e0ddSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices() 219317ab2063SBarry Smith @*/ 2194416022c9SBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,int *nnz, Mat *A) 219517ab2063SBarry Smith { 2196416022c9SBarry Smith Mat B; 2197416022c9SBarry Smith Mat_SeqAIJ *b; 21986945ee14SBarry Smith int i, len, ierr, flg,size; 21996945ee14SBarry Smith 22003a40ed3dSBarry Smith PetscFunctionBegin; 2201d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2202a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,0,"Comm must be of size 1"); 2203d5d45c9bSBarry Smith 2204b73539f3SBarry Smith if (nz < -2) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,0,"nz cannot be less than -2: value %d",nz); 2205b73539f3SBarry Smith if (nnz) { 2206b73539f3SBarry Smith for (i=0; i<m; i++) { 2207b73539f3SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,0,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 2208b73539f3SBarry Smith } 2209b73539f3SBarry Smith } 2210b73539f3SBarry Smith 2211416022c9SBarry Smith *A = 0; 22123f1db9ecSBarry Smith PetscHeaderCreate(B,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",comm,MatDestroy,MatView); 2213416022c9SBarry Smith PLogObjectCreate(B); 22140452661fSBarry Smith B->data = (void *) (b = PetscNew(Mat_SeqAIJ));CHKPTRQ(b); 2215549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2216549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2217e1311b90SBarry Smith B->ops->destroy = MatDestroy_SeqAIJ; 2218e1311b90SBarry Smith B->ops->view = MatView_SeqAIJ; 2219416022c9SBarry Smith B->factor = 0; 2220416022c9SBarry Smith B->lupivotthreshold = 1.0; 222190f02eecSBarry Smith B->mapping = 0; 2222e1311b90SBarry Smith ierr = OptionsGetDouble(PETSC_NULL,"-mat_lu_pivotthreshold",&B->lupivotthreshold,&flg);CHKERRQ(ierr); 22237a743949SBarry Smith b->ilu_preserve_row_sums = PETSC_FALSE; 2224e1311b90SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-pc_ilu_preserve_row_sums",(int*)&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2225416022c9SBarry Smith b->row = 0; 2226416022c9SBarry Smith b->col = 0; 222782bf6240SBarry Smith b->icol = 0; 2228416022c9SBarry Smith b->indexshift = 0; 2229b810aeb4SBarry Smith b->reallocs = 0; 223069957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_oneindex", &flg);CHKERRQ(ierr); 223169957df2SSatish Balay if (flg) b->indexshift = -1; 223217ab2063SBarry Smith 223344cd7ae7SLois Curfman McInnes b->m = m; B->m = m; B->M = m; 223444cd7ae7SLois Curfman McInnes b->n = n; B->n = n; B->N = n; 2235a5ae1ecdSBarry Smith 22364d197716SBarry Smith ierr = MapCreateMPI(comm,m,m,&B->rmap);CHKERRQ(ierr); 22374d197716SBarry Smith ierr = MapCreateMPI(comm,n,n,&B->cmap);CHKERRQ(ierr); 2238a5ae1ecdSBarry Smith 22390452661fSBarry Smith b->imax = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(b->imax); 2240b4fd4287SBarry Smith if (nnz == PETSC_NULL) { 22417b8455f0SLois Curfman McInnes if (nz == PETSC_DEFAULT) nz = 10; 22427b8455f0SLois Curfman McInnes else if (nz <= 0) nz = 1; 2243416022c9SBarry Smith for ( i=0; i<m; i++ ) b->imax[i] = nz; 224417ab2063SBarry Smith nz = nz*m; 22453a40ed3dSBarry Smith } else { 224617ab2063SBarry Smith nz = 0; 2247416022c9SBarry Smith for ( i=0; i<m; i++ ) {b->imax[i] = nnz[i]; nz += nnz[i];} 224817ab2063SBarry Smith } 224917ab2063SBarry Smith 225017ab2063SBarry Smith /* allocate the matrix space */ 2251416022c9SBarry Smith len = nz*(sizeof(int) + sizeof(Scalar)) + (b->m+1)*sizeof(int); 22520452661fSBarry Smith b->a = (Scalar *) PetscMalloc( len );CHKPTRQ(b->a); 2253416022c9SBarry Smith b->j = (int *) (b->a + nz); 2254549d3d68SSatish Balay ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2255416022c9SBarry Smith b->i = b->j + nz; 2256416022c9SBarry Smith b->singlemalloc = 1; 225717ab2063SBarry Smith 2258416022c9SBarry Smith b->i[0] = -b->indexshift; 225917ab2063SBarry Smith for (i=1; i<m+1; i++) { 2260416022c9SBarry Smith b->i[i] = b->i[i-1] + b->imax[i-1]; 226117ab2063SBarry Smith } 226217ab2063SBarry Smith 2263416022c9SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 22640452661fSBarry Smith b->ilen = (int *) PetscMalloc((m+1)*sizeof(int)); 2265f09e8eb9SSatish Balay PLogObjectMemory(B,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2266416022c9SBarry Smith for ( i=0; i<b->m; i++ ) { b->ilen[i] = 0;} 226717ab2063SBarry Smith 2268416022c9SBarry Smith b->nz = 0; 2269416022c9SBarry Smith b->maxnz = nz; 2270416022c9SBarry Smith b->sorted = 0; 2271416022c9SBarry Smith b->roworiented = 1; 2272416022c9SBarry Smith b->nonew = 0; 2273416022c9SBarry Smith b->diag = 0; 2274416022c9SBarry Smith b->solve_work = 0; 227571bd300dSLois Curfman McInnes b->spptr = 0; 2276754ec7b1SSatish Balay b->inode.node_count = 0; 2277754ec7b1SSatish Balay b->inode.size = 0; 22786c7ebb05SLois Curfman McInnes b->inode.limit = 5; 22796c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2280be6bf707SBarry Smith b->saved_values = 0; 22814e220ebcSLois Curfman McInnes B->info.nz_unneeded = (double)b->maxnz; 2282d7f994e1SBarry Smith b->idiag = 0; 2283d7f994e1SBarry Smith b->ssor = 0; 228417ab2063SBarry Smith 2285416022c9SBarry Smith *A = B; 22864e220ebcSLois Curfman McInnes 22874b14c69eSBarry Smith /* SuperLU is not currently supported through PETSc */ 2288aa482453SBarry Smith #if defined(PETSC_HAVE_SUPERLU) 228969957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_superlu", &flg);CHKERRQ(ierr); 229069957df2SSatish Balay if (flg) { ierr = MatUseSuperLU_SeqAIJ(B);CHKERRQ(ierr); } 22914b14c69eSBarry Smith #endif 229269957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_essl", &flg);CHKERRQ(ierr); 229369957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 229469957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-mat_aij_dxml", &flg);CHKERRQ(ierr); 229569957df2SSatish Balay if (flg) { 2296a8c6a408SBarry Smith if (!b->indexshift) SETERRQ( PETSC_ERR_LIB,0,"need -mat_aij_oneindex with -mat_aij_dxml"); 2297416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 229817ab2063SBarry Smith } 229969957df2SSatish Balay ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr); 230069957df2SSatish Balay if (flg) {ierr = MatPrintHelp(B);CHKERRQ(ierr); } 2301bef8e0ddSBarry Smith 2302bef8e0ddSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2303bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2304bef8e0ddSBarry Smith (void*)MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2305be6bf707SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C", 2306be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2307be6bf707SBarry Smith (void*)MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2308be6bf707SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C", 2309be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2310be6bf707SBarry Smith (void*)MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 23113a40ed3dSBarry Smith PetscFunctionReturn(0); 231217ab2063SBarry Smith } 231317ab2063SBarry Smith 23145615d1e5SSatish Balay #undef __FUNC__ 2315be6bf707SBarry Smith #define __FUNC__ "MatDuplicate_SeqAIJ" 2316be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 231717ab2063SBarry Smith { 2318416022c9SBarry Smith Mat C; 2319416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ *) A->data; 2320bef8e0ddSBarry Smith int i,len, m = a->m,shift = a->indexshift,ierr; 232117ab2063SBarry Smith 23223a40ed3dSBarry Smith PetscFunctionBegin; 23234043dd9cSLois Curfman McInnes *B = 0; 23243f1db9ecSBarry Smith PetscHeaderCreate(C,_p_Mat,struct _MatOps,MAT_COOKIE,MATSEQAIJ,"Mat",A->comm,MatDestroy,MatView); 2325416022c9SBarry Smith PLogObjectCreate(C); 23260452661fSBarry Smith C->data = (void *) (c = PetscNew(Mat_SeqAIJ));CHKPTRQ(c); 2327549d3d68SSatish Balay ierr = PetscMemcpy(C->ops,A->ops,sizeof(struct _MatOps));CHKERRQ(ierr); 2328e1311b90SBarry Smith C->ops->destroy = MatDestroy_SeqAIJ; 2329e1311b90SBarry Smith C->ops->view = MatView_SeqAIJ; 2330416022c9SBarry Smith C->factor = A->factor; 2331416022c9SBarry Smith c->row = 0; 2332416022c9SBarry Smith c->col = 0; 233382bf6240SBarry Smith c->icol = 0; 2334416022c9SBarry Smith c->indexshift = shift; 2335c456f294SBarry Smith C->assembled = PETSC_TRUE; 233617ab2063SBarry Smith 233744cd7ae7SLois Curfman McInnes c->m = C->m = a->m; 233844cd7ae7SLois Curfman McInnes c->n = C->n = a->n; 233944cd7ae7SLois Curfman McInnes C->M = a->m; 234044cd7ae7SLois Curfman McInnes C->N = a->n; 234117ab2063SBarry Smith 23420452661fSBarry Smith c->imax = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->imax); 23430452661fSBarry Smith c->ilen = (int *) PetscMalloc((m+1)*sizeof(int));CHKPTRQ(c->ilen); 234417ab2063SBarry Smith for ( i=0; i<m; i++ ) { 2345416022c9SBarry Smith c->imax[i] = a->imax[i]; 2346416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 234717ab2063SBarry Smith } 234817ab2063SBarry Smith 234917ab2063SBarry Smith /* allocate the matrix space */ 2350416022c9SBarry Smith c->singlemalloc = 1; 2351416022c9SBarry Smith len = (m+1)*sizeof(int)+(a->i[m])*(sizeof(Scalar)+sizeof(int)); 23520452661fSBarry Smith c->a = (Scalar *) PetscMalloc( len );CHKPTRQ(c->a); 2353416022c9SBarry Smith c->j = (int *) (c->a + a->i[m] + shift); 2354416022c9SBarry Smith c->i = c->j + a->i[m] + shift; 2355549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 235617ab2063SBarry Smith if (m > 0) { 2357549d3d68SSatish Balay ierr = PetscMemcpy(c->j,a->j,(a->i[m]+shift)*sizeof(int));CHKERRQ(ierr); 2358be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2359549d3d68SSatish Balay ierr = PetscMemcpy(c->a,a->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 2360be6bf707SBarry Smith } else { 2361549d3d68SSatish Balay ierr = PetscMemzero(c->a,(a->i[m]+shift)*sizeof(Scalar));CHKERRQ(ierr); 236217ab2063SBarry Smith } 236308480c60SBarry Smith } 236417ab2063SBarry Smith 2365f09e8eb9SSatish Balay PLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2366416022c9SBarry Smith c->sorted = a->sorted; 2367416022c9SBarry Smith c->roworiented = a->roworiented; 2368416022c9SBarry Smith c->nonew = a->nonew; 23697a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2370be6bf707SBarry Smith c->saved_values = 0; 2371d7f994e1SBarry Smith c->idiag = 0; 2372d7f994e1SBarry Smith c->ssor = 0; 237317ab2063SBarry Smith 2374416022c9SBarry Smith if (a->diag) { 23750452661fSBarry Smith c->diag = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->diag); 2376416022c9SBarry Smith PLogObjectMemory(C,(m+1)*sizeof(int)); 237717ab2063SBarry Smith for ( i=0; i<m; i++ ) { 2378416022c9SBarry Smith c->diag[i] = a->diag[i]; 237917ab2063SBarry Smith } 23803a40ed3dSBarry Smith } else c->diag = 0; 23816c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 23826c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2383754ec7b1SSatish Balay if (a->inode.size){ 2384daed632aSSatish Balay c->inode.size = (int *) PetscMalloc( (m+1)*sizeof(int) );CHKPTRQ(c->inode.size); 2385754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2386549d3d68SSatish Balay ierr = PetscMemcpy( c->inode.size, a->inode.size, (m+1)*sizeof(int));CHKERRQ(ierr); 2387754ec7b1SSatish Balay } else { 2388754ec7b1SSatish Balay c->inode.size = 0; 2389754ec7b1SSatish Balay c->inode.node_count = 0; 2390754ec7b1SSatish Balay } 2391416022c9SBarry Smith c->nz = a->nz; 2392416022c9SBarry Smith c->maxnz = a->maxnz; 2393416022c9SBarry Smith c->solve_work = 0; 239476dd722bSSatish Balay c->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2395754ec7b1SSatish Balay 2396416022c9SBarry Smith *B = C; 23977b2a1423SBarry Smith ierr = FListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 23983a40ed3dSBarry Smith PetscFunctionReturn(0); 239917ab2063SBarry Smith } 240017ab2063SBarry Smith 24015615d1e5SSatish Balay #undef __FUNC__ 24025615d1e5SSatish Balay #define __FUNC__ "MatLoad_SeqAIJ" 240319bcc07fSBarry Smith int MatLoad_SeqAIJ(Viewer viewer,MatType type,Mat *A) 240417ab2063SBarry Smith { 2405416022c9SBarry Smith Mat_SeqAIJ *a; 2406416022c9SBarry Smith Mat B; 240717699dbbSLois Curfman McInnes int i, nz, ierr, fd, header[4],size,*rowlengths = 0,M,N,shift; 2408bcd2baecSBarry Smith MPI_Comm comm; 240917ab2063SBarry Smith 24103a40ed3dSBarry Smith PetscFunctionBegin; 2411e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject) viewer,&comm);CHKERRQ(ierr); 2412d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 2413a8c6a408SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,0,"view must have one processor"); 241490ace30eSBarry Smith ierr = ViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 24150752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2416a8c6a408SBarry Smith if (header[0] != MAT_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,0,"not matrix object in file"); 241717ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 241817ab2063SBarry Smith 2419d64ed03dSBarry Smith if (nz < 0) { 2420a8c6a408SBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,1,"Matrix stored in special format on disk, cannot load as SeqAIJ"); 2421d64ed03dSBarry Smith } 2422d64ed03dSBarry Smith 242317ab2063SBarry Smith /* read in row lengths */ 24240452661fSBarry Smith rowlengths = (int*) PetscMalloc( M*sizeof(int) );CHKPTRQ(rowlengths); 24250752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 242617ab2063SBarry Smith 242717ab2063SBarry Smith /* create our matrix */ 2428416022c9SBarry Smith ierr = MatCreateSeqAIJ(comm,M,N,0,rowlengths,A);CHKERRQ(ierr); 2429416022c9SBarry Smith B = *A; 2430416022c9SBarry Smith a = (Mat_SeqAIJ *) B->data; 2431416022c9SBarry Smith shift = a->indexshift; 243217ab2063SBarry Smith 243317ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 24340752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 243517ab2063SBarry Smith if (shift) { 243617ab2063SBarry Smith for ( i=0; i<nz; i++ ) { 2437416022c9SBarry Smith a->j[i] += 1; 243817ab2063SBarry Smith } 243917ab2063SBarry Smith } 244017ab2063SBarry Smith 244117ab2063SBarry Smith /* read in nonzero values */ 24420752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 244317ab2063SBarry Smith 244417ab2063SBarry Smith /* set matrix "i" values */ 2445416022c9SBarry Smith a->i[0] = -shift; 244617ab2063SBarry Smith for ( i=1; i<= M; i++ ) { 2447416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2448416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 244917ab2063SBarry Smith } 2450606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 245117ab2063SBarry Smith 24526d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24536d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24543a40ed3dSBarry Smith PetscFunctionReturn(0); 245517ab2063SBarry Smith } 245617ab2063SBarry Smith 24575615d1e5SSatish Balay #undef __FUNC__ 24585615d1e5SSatish Balay #define __FUNC__ "MatEqual_SeqAIJ" 24598f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B, PetscTruth* flg) 24607264ac53SSatish Balay { 24617264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data, *b = (Mat_SeqAIJ *)B->data; 24620f5bd95cSBarry Smith int ierr; 24637264ac53SSatish Balay 24643a40ed3dSBarry Smith PetscFunctionBegin; 2465a8c6a408SBarry Smith if (B->type !=MATSEQAIJ)SETERRQ(PETSC_ERR_ARG_INCOMP,0,"Matrices must be same type"); 24667264ac53SSatish Balay 24677264ac53SSatish Balay /* If the matrix dimensions are not equal, or no of nonzeros or shift */ 24687264ac53SSatish Balay if ((a->m != b->m ) || (a->n !=b->n) ||( a->nz != b->nz)|| 2469bcd2baecSBarry Smith (a->indexshift != b->indexshift)) { 24703a40ed3dSBarry Smith *flg = PETSC_FALSE; PetscFunctionReturn(0); 2471bcd2baecSBarry Smith } 24727264ac53SSatish Balay 24737264ac53SSatish Balay /* if the a->i are the same */ 24740f5bd95cSBarry Smith ierr = PetscMemcmp(a->i,b->i,(a->m+1)*sizeof(int),flg);CHKERRQ(ierr); 24750f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 24767264ac53SSatish Balay 24777264ac53SSatish Balay /* if a->j are the same */ 24780f5bd95cSBarry Smith ierr = PetscMemcmp(a->j, b->j, (a->nz)*sizeof(int),flg);CHKERRQ(ierr); 24790f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2480bcd2baecSBarry Smith 2481bcd2baecSBarry Smith /* if a->a are the same */ 24820f5bd95cSBarry Smith ierr = PetscMemcmp(a->a, b->a, (a->nz)*sizeof(Scalar),flg);CHKERRQ(ierr); 24830f5bd95cSBarry Smith 24843a40ed3dSBarry Smith PetscFunctionReturn(0); 24857264ac53SSatish Balay 24867264ac53SSatish Balay } 2487