173f4d377SMatthew Knepley /*$Id: aij.c,v 1.385 2001/09/07 20:09:22 bsmith Exp $*/ 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 79e070d67SMatthew Knepley #include "src/mat/impls/aij/seq/aij.h" /*I "petscmat.h" I*/ 8f5eb4b81SSatish Balay #include "src/vec/vecimpl.h" 9f5eb4b81SSatish Balay #include "src/inline/spops.h" 108d195f9aSBarry Smith #include "src/inline/dot.h" 110a835dfdSSatish Balay #include "petscbt.h" 1217ab2063SBarry Smith 13a2ce50c7SBarry Smith 14ca44d042SBarry Smith EXTERN int MatToSymmetricIJ_SeqAIJ(int,int*,int*,int,int,int**,int**); 1517ab2063SBarry Smith 164a2ae208SSatish Balay #undef __FUNCT__ 174a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 184e7234bfSBarry Smith int MatGetRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *m,int *ia[],int *ja[],PetscTruth *done) 1917ab2063SBarry Smith { 20416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 216945ee14SBarry Smith int ierr,i,ishift; 2217ab2063SBarry Smith 233a40ed3dSBarry Smith PetscFunctionBegin; 2431625ec5SSatish Balay *m = A->m; 253a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 26bfeeae90SHong Zhang ishift = 0; 2753e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 28273d9f13SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 29bfeeae90SHong Zhang } else if (oshift == 1) { 30435da068SBarry Smith int nz = a->i[A->m]; 313b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 321bc30dd5SBarry Smith ierr = PetscMalloc((A->m+1)*sizeof(int),ia);CHKERRQ(ierr); 33b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),ja);CHKERRQ(ierr); 343b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 35273d9f13SBarry Smith for (i=0; i<A->m+1; i++) (*ia)[i] = a->i[i] + 1; 366945ee14SBarry Smith } else { 376945ee14SBarry Smith *ia = a->i; *ja = a->j; 38a2ce50c7SBarry Smith } 393a40ed3dSBarry Smith PetscFunctionReturn(0); 40a2744918SBarry Smith } 41a2744918SBarry Smith 424a2ae208SSatish Balay #undef __FUNCT__ 434a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 444e7234bfSBarry Smith int MatRestoreRowIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done) 456945ee14SBarry Smith { 46bfeeae90SHong Zhang int ierr; 476945ee14SBarry Smith 483a40ed3dSBarry Smith PetscFunctionBegin; 493a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 50bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 51606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 52606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 53bcd2baecSBarry Smith } 543a40ed3dSBarry Smith PetscFunctionReturn(0); 5517ab2063SBarry Smith } 5617ab2063SBarry Smith 574a2ae208SSatish Balay #undef __FUNCT__ 584a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 594e7234bfSBarry Smith int MatGetColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *nn,int *ia[],int *ja[],PetscTruth *done) 603b2fbd54SBarry Smith { 613b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 62bfeeae90SHong Zhang int ierr,i,*collengths,*cia,*cja,n = A->n,m = A->m; 63bfeeae90SHong Zhang int nz = a->i[m],row,*jj,mr,col; 643b2fbd54SBarry Smith 653a40ed3dSBarry Smith PetscFunctionBegin; 663b2fbd54SBarry Smith *nn = A->n; 673a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 683b2fbd54SBarry Smith if (symmetric) { 69bfeeae90SHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->m,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 703b2fbd54SBarry Smith } else { 71b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&collengths);CHKERRQ(ierr); 72549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 73b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&cia);CHKERRQ(ierr); 74b0a32e0cSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(int),&cja);CHKERRQ(ierr); 753b2fbd54SBarry Smith jj = a->j; 763b2fbd54SBarry Smith for (i=0; i<nz; i++) { 77bfeeae90SHong Zhang collengths[jj[i]]++; 783b2fbd54SBarry Smith } 793b2fbd54SBarry Smith cia[0] = oshift; 803b2fbd54SBarry Smith for (i=0; i<n; i++) { 813b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 823b2fbd54SBarry Smith } 83549d3d68SSatish Balay ierr = PetscMemzero(collengths,n*sizeof(int));CHKERRQ(ierr); 843b2fbd54SBarry Smith jj = a->j; 85a93ec695SBarry Smith for (row=0; row<m; row++) { 86a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 87a93ec695SBarry Smith for (i=0; i<mr; i++) { 88bfeeae90SHong Zhang col = *jj++; 893b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 903b2fbd54SBarry Smith } 913b2fbd54SBarry Smith } 92606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 933b2fbd54SBarry Smith *ia = cia; *ja = cja; 943b2fbd54SBarry Smith } 953a40ed3dSBarry Smith PetscFunctionReturn(0); 963b2fbd54SBarry Smith } 973b2fbd54SBarry Smith 984a2ae208SSatish Balay #undef __FUNCT__ 994a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 1004e7234bfSBarry Smith int MatRestoreColumnIJ_SeqAIJ(Mat A,int oshift,PetscTruth symmetric,int *n,int *ia[],int *ja[],PetscTruth *done) 1013b2fbd54SBarry Smith { 102606d414cSSatish Balay int ierr; 103606d414cSSatish Balay 1043a40ed3dSBarry Smith PetscFunctionBegin; 1053a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 1063b2fbd54SBarry Smith 107606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 108606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 1093b2fbd54SBarry Smith 1103a40ed3dSBarry Smith PetscFunctionReturn(0); 1113b2fbd54SBarry Smith } 1123b2fbd54SBarry Smith 113227d817aSBarry Smith #define CHUNKSIZE 15 11417ab2063SBarry Smith 1154a2ae208SSatish Balay #undef __FUNCT__ 1164a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 117f15d580aSBarry Smith int MatSetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],const PetscScalar v[],InsertMode is) 11817ab2063SBarry Smith { 119416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 120416022c9SBarry Smith int *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N,sorted = a->sorted; 121273d9f13SBarry Smith int *imax = a->imax,*ai = a->i,*ailen = a->ilen; 122bfeeae90SHong Zhang int *aj = a->j,nonew = a->nonew,ierr; 12387828ca2SBarry Smith PetscScalar *ap,value,*aa = a->a; 12436db0b34SBarry Smith PetscTruth ignorezeroentries = ((a->ignorezeroentries && is == ADD_VALUES) ? PETSC_TRUE:PETSC_FALSE); 125273d9f13SBarry Smith PetscTruth roworiented = a->roworiented; 12617ab2063SBarry Smith 1273a40ed3dSBarry Smith PetscFunctionBegin; 12817ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 129416022c9SBarry Smith row = im[k]; 1305ef9f2a5SBarry Smith if (row < 0) continue; 131aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 132590ac198SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1); 1333b2fbd54SBarry Smith #endif 134bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 13517ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 136416022c9SBarry Smith low = 0; 13717ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 1385ef9f2a5SBarry Smith if (in[l] < 0) continue; 139aa482453SBarry Smith #if defined(PETSC_USE_BOPT_g) 140590ac198SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1); 1413b2fbd54SBarry Smith #endif 142bfeeae90SHong Zhang col = in[l]; 1434b0e389bSBarry Smith if (roworiented) { 1445ef9f2a5SBarry Smith value = v[l + k*n]; 145bef8e0ddSBarry Smith } else { 1464b0e389bSBarry Smith value = v[k + l*m]; 1474b0e389bSBarry Smith } 14836db0b34SBarry Smith if (value == 0.0 && ignorezeroentries) continue; 14936db0b34SBarry Smith 150416022c9SBarry Smith if (!sorted) low = 0; high = nrow; 151416022c9SBarry Smith while (high-low > 5) { 152416022c9SBarry Smith t = (low+high)/2; 153416022c9SBarry Smith if (rp[t] > col) high = t; 154416022c9SBarry Smith else low = t; 15517ab2063SBarry Smith } 156416022c9SBarry Smith for (i=low; i<high; i++) { 15717ab2063SBarry Smith if (rp[i] > col) break; 15817ab2063SBarry Smith if (rp[i] == col) { 159416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 16017ab2063SBarry Smith else ap[i] = value; 16117ab2063SBarry Smith goto noinsert; 16217ab2063SBarry Smith } 16317ab2063SBarry Smith } 164c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 16529bbc08cSBarry Smith else if (nonew == -1) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix",row,col); 16617ab2063SBarry Smith if (nrow >= rmax) { 16717ab2063SBarry Smith /* there is no extra room in row, therefore enlarge */ 168a7ed9263SMatthew Knepley int new_nz = ai[A->m] + CHUNKSIZE,*new_i,*new_j; 169a7ed9263SMatthew Knepley size_t len; 17087828ca2SBarry Smith PetscScalar *new_a; 17117ab2063SBarry Smith 17229bbc08cSBarry Smith if (nonew == -2) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%d,%d) in the matrix requiring new malloc()",row,col); 17396854ed6SLois Curfman McInnes 17417ab2063SBarry Smith /* malloc new storage space */ 175a7ed9263SMatthew Knepley len = ((size_t) new_nz)*(sizeof(int)+sizeof(PetscScalar))+(A->m+1)*sizeof(int); 176b0a32e0cSBarry Smith ierr = PetscMalloc(len,&new_a);CHKERRQ(ierr); 17717ab2063SBarry Smith new_j = (int*)(new_a + new_nz); 17817ab2063SBarry Smith new_i = new_j + new_nz; 17917ab2063SBarry Smith 18017ab2063SBarry Smith /* copy over old data into new slots */ 18117ab2063SBarry Smith for (ii=0; ii<row+1; ii++) {new_i[ii] = ai[ii];} 182273d9f13SBarry Smith for (ii=row+1; ii<A->m+1; ii++) {new_i[ii] = ai[ii]+CHUNKSIZE;} 183bfeeae90SHong Zhang ierr = PetscMemcpy(new_j,aj,(ai[row]+nrow)*sizeof(int));CHKERRQ(ierr); 184bfeeae90SHong Zhang len = (((size_t) new_nz) - CHUNKSIZE - ai[row] - nrow ); 185bfeeae90SHong Zhang ierr = PetscMemcpy(new_j+ai[row]+nrow+CHUNKSIZE,aj+ai[row]+nrow,len*sizeof(int));CHKERRQ(ierr); 186bfeeae90SHong Zhang ierr = PetscMemcpy(new_a,aa,(((size_t) ai[row])+nrow)*sizeof(PetscScalar));CHKERRQ(ierr); 187bfeeae90SHong Zhang ierr = PetscMemcpy(new_a+ai[row]+nrow+CHUNKSIZE,aa+ai[row]+nrow,len*sizeof(PetscScalar));CHKERRQ(ierr); 18817ab2063SBarry Smith /* free up old matrix storage */ 189606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 190606d414cSSatish Balay if (!a->singlemalloc) { 191606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 192606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 193606d414cSSatish Balay } 194416022c9SBarry Smith aa = a->a = new_a; ai = a->i = new_i; aj = a->j = new_j; 195f1e2ffcdSBarry Smith a->singlemalloc = PETSC_TRUE; 19617ab2063SBarry Smith 197bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row] ; 198416022c9SBarry Smith rmax = imax[row] = imax[row] + CHUNKSIZE; 19987828ca2SBarry Smith PetscLogObjectMemory(A,CHUNKSIZE*(sizeof(int) + sizeof(PetscScalar))); 200416022c9SBarry Smith a->maxnz += CHUNKSIZE; 201b810aeb4SBarry Smith a->reallocs++; 20217ab2063SBarry Smith } 203416022c9SBarry Smith N = nrow++ - 1; a->nz++; 204416022c9SBarry Smith /* shift up all the later entries in this row */ 205416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 20617ab2063SBarry Smith rp[ii+1] = rp[ii]; 20717ab2063SBarry Smith ap[ii+1] = ap[ii]; 20817ab2063SBarry Smith } 20917ab2063SBarry Smith rp[i] = col; 21017ab2063SBarry Smith ap[i] = value; 21117ab2063SBarry Smith noinsert:; 212416022c9SBarry Smith low = i + 1; 21317ab2063SBarry Smith } 21417ab2063SBarry Smith ailen[row] = nrow; 21517ab2063SBarry Smith } 2163a40ed3dSBarry Smith PetscFunctionReturn(0); 21717ab2063SBarry Smith } 21817ab2063SBarry Smith 2194a2ae208SSatish Balay #undef __FUNCT__ 2204a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 221f15d580aSBarry Smith int MatGetValues_SeqAIJ(Mat A,int m,const int im[],int n,const int in[],PetscScalar v[]) 2227eb43aa7SLois Curfman McInnes { 2237eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 224b49de8d1SLois Curfman McInnes int *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 225bfeeae90SHong Zhang int *ai = a->i,*ailen = a->ilen; 22687828ca2SBarry Smith PetscScalar *ap,*aa = a->a,zero = 0.0; 2277eb43aa7SLois Curfman McInnes 2283a40ed3dSBarry Smith PetscFunctionBegin; 2297eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 2307eb43aa7SLois Curfman McInnes row = im[k]; 23129bbc08cSBarry Smith if (row < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %d",row); 232590ac198SBarry Smith if (row >= A->m) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %d max %d",row,A->m-1); 233bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 2347eb43aa7SLois Curfman McInnes nrow = ailen[row]; 2357eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 23629bbc08cSBarry Smith if (in[l] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %d",in[l]); 237590ac198SBarry Smith if (in[l] >= A->n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %d max %d",in[l],A->n-1); 238bfeeae90SHong Zhang col = in[l] ; 2397eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 2407eb43aa7SLois Curfman McInnes while (high-low > 5) { 2417eb43aa7SLois Curfman McInnes t = (low+high)/2; 2427eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 2437eb43aa7SLois Curfman McInnes else low = t; 2447eb43aa7SLois Curfman McInnes } 2457eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 2467eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 2477eb43aa7SLois Curfman McInnes if (rp[i] == col) { 248b49de8d1SLois Curfman McInnes *v++ = ap[i]; 2497eb43aa7SLois Curfman McInnes goto finished; 2507eb43aa7SLois Curfman McInnes } 2517eb43aa7SLois Curfman McInnes } 252b49de8d1SLois Curfman McInnes *v++ = zero; 2537eb43aa7SLois Curfman McInnes finished:; 2547eb43aa7SLois Curfman McInnes } 2557eb43aa7SLois Curfman McInnes } 2563a40ed3dSBarry Smith PetscFunctionReturn(0); 2577eb43aa7SLois Curfman McInnes } 2587eb43aa7SLois Curfman McInnes 25917ab2063SBarry Smith 2604a2ae208SSatish Balay #undef __FUNCT__ 2614a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 262b0a32e0cSBarry Smith int MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 26317ab2063SBarry Smith { 264416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 265416022c9SBarry Smith int i,fd,*col_lens,ierr; 26617ab2063SBarry Smith 2673a40ed3dSBarry Smith PetscFunctionBegin; 268b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 269b0a32e0cSBarry Smith ierr = PetscMalloc((4+A->m)*sizeof(int),&col_lens);CHKERRQ(ierr); 270552e946dSBarry Smith col_lens[0] = MAT_FILE_COOKIE; 271273d9f13SBarry Smith col_lens[1] = A->m; 272273d9f13SBarry Smith col_lens[2] = A->n; 273416022c9SBarry Smith col_lens[3] = a->nz; 274416022c9SBarry Smith 275416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 276273d9f13SBarry Smith for (i=0; i<A->m; i++) { 277416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 27817ab2063SBarry Smith } 279273d9f13SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->m,PETSC_INT,1);CHKERRQ(ierr); 280606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 281416022c9SBarry Smith 282416022c9SBarry Smith /* store column indices (zero start index) */ 2830752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,0);CHKERRQ(ierr); 284416022c9SBarry Smith 285416022c9SBarry Smith /* store nonzero values */ 2860752156aSBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,0);CHKERRQ(ierr); 2873a40ed3dSBarry Smith PetscFunctionReturn(0); 28817ab2063SBarry Smith } 289416022c9SBarry Smith 2904ffef66eSHong Zhang extern int MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 2911dfdf1d9SHong Zhang extern int MatFactorInfo_MUMPS(Mat,PetscViewer); 292cd155464SBarry Smith 2934a2ae208SSatish Balay #undef __FUNCT__ 2944a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 295b0a32e0cSBarry Smith int MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 296416022c9SBarry Smith { 297416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 298bfeeae90SHong Zhang int ierr,i,j,m = A->m,shift=0; 299fb9695e5SSatish Balay char *name; 300f3ef73ceSBarry Smith PetscViewerFormat format; 30117ab2063SBarry Smith 3023a40ed3dSBarry Smith PetscFunctionBegin; 303435da068SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 304b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 305456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO_DETAIL || format == PETSC_VIEWER_ASCII_INFO) { 3066831982aSBarry Smith if (a->inode.size) { 307b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"using I-node routines: found %d nodes, limit used is %d\n",a->inode.node_count,a->inode.limit);CHKERRQ(ierr); 3086831982aSBarry Smith } else { 309b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"not using I-node routines\n");CHKERRQ(ierr); 3106831982aSBarry Smith } 311fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_MATLAB) { 312d00d2cf4SBarry Smith int nofinalvalue = 0; 313273d9f13SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->n-!shift)) { 314d00d2cf4SBarry Smith nofinalvalue = 1; 315d00d2cf4SBarry Smith } 316b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 317b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %d %d \n",m,A->n);CHKERRQ(ierr); 318b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %d \n",a->nz);CHKERRQ(ierr); 319b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%d,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 320b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 32117ab2063SBarry Smith 32217ab2063SBarry Smith for (i=0; i<m; i++) { 323416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 324aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 325b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e + %18.16ei \n",i+1,a->j[j]+!shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 32617ab2063SBarry Smith #else 327b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 32817ab2063SBarry Smith #endif 32917ab2063SBarry Smith } 33017ab2063SBarry Smith } 331d00d2cf4SBarry Smith if (nofinalvalue) { 332b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%d %d %18.16e\n",m,A->n,0.0);CHKERRQ(ierr); 333d00d2cf4SBarry Smith } 334fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 335b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 336cd155464SBarry Smith } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO) { 3374ffef66eSHong Zhang #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_SINGLE) && !defined(PETSC_USE_COMPLEX) 3384ffef66eSHong Zhang ierr = MatSeqAIJFactorInfo_Matlab(A,viewer);CHKERRQ(ierr); 3394ffef66eSHong Zhang #endif 3401dfdf1d9SHong Zhang #if defined(PETSC_HAVE_MUMPS) && !defined(PETSC_USE_SINGLE) 3411dfdf1d9SHong Zhang ierr = MatFactorInfo_MUMPS(A,viewer);CHKERRQ(ierr); 3421dfdf1d9SHong Zhang #endif 343cd155464SBarry Smith PetscFunctionReturn(0); 344fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 345b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 34644cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 347b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 34844cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 349aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 35036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 35162b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35236db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 35362b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 35436db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 35562b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 3566831982aSBarry Smith } 35744cd7ae7SLois Curfman McInnes #else 35862b941d6SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 35944cd7ae7SLois Curfman McInnes #endif 36044cd7ae7SLois Curfman McInnes } 361b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 36244cd7ae7SLois Curfman McInnes } 363b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 364fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 365496be53dSLois Curfman McInnes int nzd=0,fshift=1,*sptr; 366b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 367b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&sptr);CHKERRQ(ierr); 368496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 369496be53dSLois Curfman McInnes sptr[i] = nzd+1; 370496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 371496be53dSLois Curfman McInnes if (a->j[j] >= i) { 372aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 37336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 374496be53dSLois Curfman McInnes #else 375496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 376496be53dSLois Curfman McInnes #endif 377496be53dSLois Curfman McInnes } 378496be53dSLois Curfman McInnes } 379496be53dSLois Curfman McInnes } 3802e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 381b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %d %d\n\n",m,nzd);CHKERRQ(ierr); 3822e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 383b0a32e0cSBarry Smith if (i+4<m) {ierr = PetscViewerASCIIPrintf(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);} 384b0a32e0cSBarry Smith else if (i+3<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3],sptr[i+4]);CHKERRQ(ierr);} 385b0a32e0cSBarry Smith else if (i+2<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr);} 386b0a32e0cSBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d %d\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 387b0a32e0cSBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %d %d\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 388b0a32e0cSBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %d\n",sptr[i]);CHKERRQ(ierr);} 389496be53dSLois Curfman McInnes } 390b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 391606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 392496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 393496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 394b0a32e0cSBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %d ",a->j[j]+fshift);CHKERRQ(ierr);} 395496be53dSLois Curfman McInnes } 396b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 397496be53dSLois Curfman McInnes } 398b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 399496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 400496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 401496be53dSLois Curfman McInnes if (a->j[j] >= i) { 402aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 40336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 404b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4056831982aSBarry Smith } 406496be53dSLois Curfman McInnes #else 407b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 408496be53dSLois Curfman McInnes #endif 409496be53dSLois Curfman McInnes } 410496be53dSLois Curfman McInnes } 411b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 412496be53dSLois Curfman McInnes } 413b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 414fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 41502594712SBarry Smith int cnt = 0,jcnt; 41687828ca2SBarry Smith PetscScalar value; 41702594712SBarry Smith 418b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 41902594712SBarry Smith for (i=0; i<m; i++) { 42002594712SBarry Smith jcnt = 0; 421273d9f13SBarry Smith for (j=0; j<A->n; j++) { 422e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 42302594712SBarry Smith value = a->a[cnt++]; 424e24b481bSBarry Smith jcnt++; 42502594712SBarry Smith } else { 42602594712SBarry Smith value = 0.0; 42702594712SBarry Smith } 428aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 429b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 43002594712SBarry Smith #else 431b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 43202594712SBarry Smith #endif 43302594712SBarry Smith } 434b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 43502594712SBarry Smith } 436b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 4373a40ed3dSBarry Smith } else { 438b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_NO);CHKERRQ(ierr); 43917ab2063SBarry Smith for (i=0; i<m; i++) { 440b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %d:",i);CHKERRQ(ierr); 441416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 442aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 44336db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 44462b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g + %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 44536db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 44662b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g - %g i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 4473a40ed3dSBarry Smith } else { 44862b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 44917ab2063SBarry Smith } 45017ab2063SBarry Smith #else 45162b941d6SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%d, %g) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 45217ab2063SBarry Smith #endif 45317ab2063SBarry Smith } 454b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 45517ab2063SBarry Smith } 456b0a32e0cSBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_YES);CHKERRQ(ierr); 45717ab2063SBarry Smith } 458b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 4593a40ed3dSBarry Smith PetscFunctionReturn(0); 460416022c9SBarry Smith } 461416022c9SBarry Smith 4624a2ae208SSatish Balay #undef __FUNCT__ 4634a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 464b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 465416022c9SBarry Smith { 466480ef9eaSBarry Smith Mat A = (Mat) Aa; 467416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 468bfeeae90SHong Zhang int ierr,i,j,m = A->m,color; 46936db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 470b0a32e0cSBarry Smith PetscViewer viewer; 471f3ef73ceSBarry Smith PetscViewerFormat format; 472cddf8d76SBarry Smith 4733a40ed3dSBarry Smith PetscFunctionBegin; 474480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 475b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 47619bcc07fSBarry Smith 477b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 478416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 4790513a670SBarry Smith 480fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 4810513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 482b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 483416022c9SBarry Smith for (i=0; i<m; i++) { 484cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 485bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 486bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 487aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 48836db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 489cddf8d76SBarry Smith #else 490cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 491cddf8d76SBarry Smith #endif 492b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 493cddf8d76SBarry Smith } 494cddf8d76SBarry Smith } 495b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 496cddf8d76SBarry Smith for (i=0; i<m; i++) { 497cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 498bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 499bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 500cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 501b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 502cddf8d76SBarry Smith } 503cddf8d76SBarry Smith } 504b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 505cddf8d76SBarry Smith for (i=0; i<m; i++) { 506cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 507bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 508bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 509aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 51036db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 511cddf8d76SBarry Smith #else 512cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 513cddf8d76SBarry Smith #endif 514b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 515416022c9SBarry Smith } 516416022c9SBarry Smith } 5170513a670SBarry Smith } else { 5180513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 5190513a670SBarry Smith /* first determine max of all nonzero values */ 5200513a670SBarry Smith int nz = a->nz,count; 521b0a32e0cSBarry Smith PetscDraw popup; 52236db0b34SBarry Smith PetscReal scale; 5230513a670SBarry Smith 5240513a670SBarry Smith for (i=0; i<nz; i++) { 5250513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 5260513a670SBarry Smith } 527b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 528b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 529b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 5300513a670SBarry Smith count = 0; 5310513a670SBarry Smith for (i=0; i<m; i++) { 5320513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 533bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 534bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 535b0a32e0cSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (int)(scale*PetscAbsScalar(a->a[count])); 536b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 5370513a670SBarry Smith count++; 5380513a670SBarry Smith } 5390513a670SBarry Smith } 5400513a670SBarry Smith } 541480ef9eaSBarry Smith PetscFunctionReturn(0); 542480ef9eaSBarry Smith } 543cddf8d76SBarry Smith 5444a2ae208SSatish Balay #undef __FUNCT__ 5454a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 546b0a32e0cSBarry Smith int MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 547480ef9eaSBarry Smith { 548480ef9eaSBarry Smith int ierr; 549b0a32e0cSBarry Smith PetscDraw draw; 55036db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 551480ef9eaSBarry Smith PetscTruth isnull; 552480ef9eaSBarry Smith 553480ef9eaSBarry Smith PetscFunctionBegin; 554b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 555b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 556480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 557480ef9eaSBarry Smith 558480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 559273d9f13SBarry Smith xr = A->n; yr = A->m; h = yr/10.0; w = xr/10.0; 560480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 561b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 562b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 563480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 5643a40ed3dSBarry Smith PetscFunctionReturn(0); 565416022c9SBarry Smith } 566416022c9SBarry Smith 5674a2ae208SSatish Balay #undef __FUNCT__ 5684a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 569b0a32e0cSBarry Smith int MatView_SeqAIJ(Mat A,PetscViewer viewer) 570416022c9SBarry Smith { 571416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 572bcd2baecSBarry Smith int ierr; 5736831982aSBarry Smith PetscTruth issocket,isascii,isbinary,isdraw; 574416022c9SBarry Smith 5753a40ed3dSBarry Smith PetscFunctionBegin; 576b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);CHKERRQ(ierr); 577b0a32e0cSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 578fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr); 579fb9695e5SSatish Balay ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);CHKERRQ(ierr); 5800f5bd95cSBarry Smith if (issocket) { 581b0a32e0cSBarry Smith ierr = PetscViewerSocketPutSparse_Private(viewer,A->m,A->n,a->nz,a->a,a->i,a->j);CHKERRQ(ierr); 5820f5bd95cSBarry Smith } else if (isascii) { 5833a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 5840f5bd95cSBarry Smith } else if (isbinary) { 5853a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 5860f5bd95cSBarry Smith } else if (isdraw) { 5873a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 5885cd90555SBarry Smith } else { 58929bbc08cSBarry Smith SETERRQ1(1,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 59017ab2063SBarry Smith } 5913a40ed3dSBarry Smith PetscFunctionReturn(0); 59217ab2063SBarry Smith } 59319bcc07fSBarry Smith 5943a7fca6bSBarry Smith EXTERN int Mat_AIJ_CheckInode(Mat,PetscTruth); 5954a2ae208SSatish Balay #undef __FUNCT__ 5964a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 5978f6be9afSLois Curfman McInnes int MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 59817ab2063SBarry Smith { 599416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 60041c01911SSatish Balay int fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax,ierr; 601bfeeae90SHong Zhang int m = A->m,*ip,N,*ailen = a->ilen,rmax = 0; 60287828ca2SBarry Smith PetscScalar *aa = a->a,*ap; 6031677d0b8SKris Buschelman #if defined(PETSC_HAVE_MUMPS) 6049b9367d5SHong Zhang PetscTruth flag; 6059e070d67SMatthew Knepley #endif 60617ab2063SBarry Smith 6073a40ed3dSBarry Smith PetscFunctionBegin; 6083a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 60917ab2063SBarry Smith 61043ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 61117ab2063SBarry Smith for (i=1; i<m; i++) { 612416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 61317ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 61494a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 61517ab2063SBarry Smith if (fshift) { 616bfeeae90SHong Zhang ip = aj + ai[i] ; 617bfeeae90SHong Zhang ap = aa + ai[i] ; 61817ab2063SBarry Smith N = ailen[i]; 61917ab2063SBarry Smith for (j=0; j<N; j++) { 62017ab2063SBarry Smith ip[j-fshift] = ip[j]; 62117ab2063SBarry Smith ap[j-fshift] = ap[j]; 62217ab2063SBarry Smith } 62317ab2063SBarry Smith } 62417ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 62517ab2063SBarry Smith } 62617ab2063SBarry Smith if (m) { 62717ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 62817ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 62917ab2063SBarry Smith } 63017ab2063SBarry Smith /* reset ilen and imax for each row */ 63117ab2063SBarry Smith for (i=0; i<m; i++) { 63217ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 63317ab2063SBarry Smith } 634bfeeae90SHong Zhang a->nz = ai[m]; 63517ab2063SBarry Smith 63617ab2063SBarry Smith /* diagonals may have moved, so kill the diagonal pointers */ 637416022c9SBarry Smith if (fshift && a->diag) { 638606d414cSSatish Balay ierr = PetscFree(a->diag);CHKERRQ(ierr); 639b0a32e0cSBarry Smith PetscLogObjectMemory(A,-(m+1)*sizeof(int)); 640416022c9SBarry Smith a->diag = 0; 64117ab2063SBarry Smith } 642b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Matrix size: %d X %d; storage space: %d unneeded,%d used\n",m,A->n,fshift,a->nz); 643b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Number of mallocs during MatSetValues() is %d\n",a->reallocs); 644b0a32e0cSBarry Smith PetscLogInfo(A,"MatAssemblyEnd_SeqAIJ:Most nonzeros in any row is %d\n",rmax); 645dd5f02e7SSatish Balay a->reallocs = 0; 6464e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 64736db0b34SBarry Smith a->rmax = rmax; 6484e220ebcSLois Curfman McInnes 64976dd722bSSatish Balay /* check out for identical nodes. If found, use inode functions */ 6503a7fca6bSBarry Smith ierr = Mat_AIJ_CheckInode(A,(PetscTruth)(!fshift));CHKERRQ(ierr); 651cfef3cccSHong Zhang 652eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS) 653eee76cafSHong Zhang ierr = PetscOptionsHasName(A->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr); 654eee76cafSHong Zhang if (flag) { ierr = MatUseMUMPS_MPIAIJ(A);CHKERRQ(ierr); } 655eee76cafSHong Zhang #endif 656eee76cafSHong Zhang 6573a40ed3dSBarry Smith PetscFunctionReturn(0); 65817ab2063SBarry Smith } 65917ab2063SBarry Smith 6604a2ae208SSatish Balay #undef __FUNCT__ 6614a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 6628f6be9afSLois Curfman McInnes int MatZeroEntries_SeqAIJ(Mat A) 66317ab2063SBarry Smith { 664416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 665549d3d68SSatish Balay int ierr; 6663a40ed3dSBarry Smith 6673a40ed3dSBarry Smith PetscFunctionBegin; 668bfeeae90SHong Zhang ierr = PetscMemzero(a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 6693a40ed3dSBarry Smith PetscFunctionReturn(0); 67017ab2063SBarry Smith } 671416022c9SBarry Smith 6724a2ae208SSatish Balay #undef __FUNCT__ 6734a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 674e1311b90SBarry Smith int MatDestroy_SeqAIJ(Mat A) 67517ab2063SBarry Smith { 676416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 67782bf6240SBarry Smith int ierr; 678d5d45c9bSBarry Smith 6793a40ed3dSBarry Smith PetscFunctionBegin; 680aa482453SBarry Smith #if defined(PETSC_USE_LOG) 681b0a32e0cSBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%d, Cols=%d, NZ=%d",A->m,A->n,a->nz); 68217ab2063SBarry Smith #endif 68336db0b34SBarry Smith if (a->freedata) { 684606d414cSSatish Balay ierr = PetscFree(a->a);CHKERRQ(ierr); 685606d414cSSatish Balay if (!a->singlemalloc) { 686606d414cSSatish Balay ierr = PetscFree(a->i);CHKERRQ(ierr); 687606d414cSSatish Balay ierr = PetscFree(a->j);CHKERRQ(ierr); 688606d414cSSatish Balay } 68936db0b34SBarry Smith } 690c38d4ed2SBarry Smith if (a->row) { 691c38d4ed2SBarry Smith ierr = ISDestroy(a->row);CHKERRQ(ierr); 692c38d4ed2SBarry Smith } 693c38d4ed2SBarry Smith if (a->col) { 694c38d4ed2SBarry Smith ierr = ISDestroy(a->col);CHKERRQ(ierr); 695c38d4ed2SBarry Smith } 696606d414cSSatish Balay if (a->diag) {ierr = PetscFree(a->diag);CHKERRQ(ierr);} 697606d414cSSatish Balay if (a->ilen) {ierr = PetscFree(a->ilen);CHKERRQ(ierr);} 698606d414cSSatish Balay if (a->imax) {ierr = PetscFree(a->imax);CHKERRQ(ierr);} 699273d9f13SBarry Smith if (a->idiag) {ierr = PetscFree(a->idiag);CHKERRQ(ierr);} 700606d414cSSatish Balay if (a->solve_work) {ierr = PetscFree(a->solve_work);CHKERRQ(ierr);} 701606d414cSSatish Balay if (a->inode.size) {ierr = PetscFree(a->inode.size);CHKERRQ(ierr);} 70282bf6240SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} 703606d414cSSatish Balay if (a->saved_values) {ierr = PetscFree(a->saved_values);CHKERRQ(ierr);} 704cc8ba8e1SBarry Smith if (a->coloring) {ierr = ISColoringDestroy(a->coloring);CHKERRQ(ierr);} 705a30b2313SHong Zhang if (a->xtoy) {ierr = PetscFree(a->xtoy);CHKERRQ(ierr);} 706a30b2313SHong Zhang 707606d414cSSatish Balay ierr = PetscFree(a);CHKERRQ(ierr); 7083a40ed3dSBarry Smith PetscFunctionReturn(0); 70917ab2063SBarry Smith } 71017ab2063SBarry Smith 7114a2ae208SSatish Balay #undef __FUNCT__ 7124a2ae208SSatish Balay #define __FUNCT__ "MatCompress_SeqAIJ" 7138f6be9afSLois Curfman McInnes int MatCompress_SeqAIJ(Mat A) 71417ab2063SBarry Smith { 7153a40ed3dSBarry Smith PetscFunctionBegin; 7163a40ed3dSBarry Smith PetscFunctionReturn(0); 71717ab2063SBarry Smith } 71817ab2063SBarry Smith 7194a2ae208SSatish Balay #undef __FUNCT__ 7204a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 7218f6be9afSLois Curfman McInnes int MatSetOption_SeqAIJ(Mat A,MatOption op) 72217ab2063SBarry Smith { 723416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7243a40ed3dSBarry Smith 7253a40ed3dSBarry Smith PetscFunctionBegin; 726a65d3064SKris Buschelman switch (op) { 727a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 728a65d3064SKris Buschelman a->roworiented = PETSC_TRUE; 729a65d3064SKris Buschelman break; 730a65d3064SKris Buschelman case MAT_KEEP_ZEROED_ROWS: 731a65d3064SKris Buschelman a->keepzeroedrows = PETSC_TRUE; 732a65d3064SKris Buschelman break; 733a65d3064SKris Buschelman case MAT_COLUMN_ORIENTED: 734a65d3064SKris Buschelman a->roworiented = PETSC_FALSE; 735a65d3064SKris Buschelman break; 736a65d3064SKris Buschelman case MAT_COLUMNS_SORTED: 737a65d3064SKris Buschelman a->sorted = PETSC_TRUE; 738a65d3064SKris Buschelman break; 739a65d3064SKris Buschelman case MAT_COLUMNS_UNSORTED: 740a65d3064SKris Buschelman a->sorted = PETSC_FALSE; 741a65d3064SKris Buschelman break; 742a65d3064SKris Buschelman case MAT_NO_NEW_NONZERO_LOCATIONS: 743a65d3064SKris Buschelman a->nonew = 1; 744a65d3064SKris Buschelman break; 745a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 746a65d3064SKris Buschelman a->nonew = -1; 747a65d3064SKris Buschelman break; 748a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 749a65d3064SKris Buschelman a->nonew = -2; 750a65d3064SKris Buschelman break; 751a65d3064SKris Buschelman case MAT_YES_NEW_NONZERO_LOCATIONS: 752a65d3064SKris Buschelman a->nonew = 0; 753a65d3064SKris Buschelman break; 754a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 755a65d3064SKris Buschelman a->ignorezeroentries = PETSC_TRUE; 756a65d3064SKris Buschelman break; 757a65d3064SKris Buschelman case MAT_USE_INODES: 758a65d3064SKris Buschelman a->inode.use = PETSC_TRUE; 759a65d3064SKris Buschelman break; 760a65d3064SKris Buschelman case MAT_DO_NOT_USE_INODES: 761a65d3064SKris Buschelman a->inode.use = PETSC_FALSE; 762a65d3064SKris Buschelman break; 763a65d3064SKris Buschelman case MAT_ROWS_SORTED: 764a65d3064SKris Buschelman case MAT_ROWS_UNSORTED: 765a65d3064SKris Buschelman case MAT_YES_NEW_DIAGONALS: 766a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 767a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 768b0a32e0cSBarry Smith PetscLogInfo(A,"MatSetOption_SeqAIJ:Option ignored\n"); 769a65d3064SKris Buschelman break; 770a65d3064SKris Buschelman case MAT_NO_NEW_DIAGONALS: 77129bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"MAT_NO_NEW_DIAGONALS"); 772a65d3064SKris Buschelman case MAT_INODE_LIMIT_1: 773a65d3064SKris Buschelman a->inode.limit = 1; 774a65d3064SKris Buschelman break; 775a65d3064SKris Buschelman case MAT_INODE_LIMIT_2: 776a65d3064SKris Buschelman a->inode.limit = 2; 777a65d3064SKris Buschelman break; 778a65d3064SKris Buschelman case MAT_INODE_LIMIT_3: 779a65d3064SKris Buschelman a->inode.limit = 3; 780a65d3064SKris Buschelman break; 781a65d3064SKris Buschelman case MAT_INODE_LIMIT_4: 782a65d3064SKris Buschelman a->inode.limit = 4; 783a65d3064SKris Buschelman break; 784a65d3064SKris Buschelman case MAT_INODE_LIMIT_5: 785a65d3064SKris Buschelman a->inode.limit = 5; 786a65d3064SKris Buschelman break; 787a65d3064SKris Buschelman default: 788a65d3064SKris Buschelman SETERRQ(PETSC_ERR_SUP,"unknown option"); 789a65d3064SKris Buschelman } 7903a40ed3dSBarry Smith PetscFunctionReturn(0); 79117ab2063SBarry Smith } 79217ab2063SBarry Smith 7934a2ae208SSatish Balay #undef __FUNCT__ 7944a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 7958f6be9afSLois Curfman McInnes int MatGetDiagonal_SeqAIJ(Mat A,Vec v) 79617ab2063SBarry Smith { 797416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 798bfeeae90SHong Zhang int i,j,n,ierr; 79987828ca2SBarry Smith PetscScalar *x,zero = 0.0; 80017ab2063SBarry Smith 8013a40ed3dSBarry Smith PetscFunctionBegin; 8023a40ed3dSBarry Smith ierr = VecSet(&zero,v);CHKERRQ(ierr); 803ed480e8bSBarry Smith ierr = VecGetArrayFast(v,&x);CHKERRQ(ierr); 80436db0b34SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 805273d9f13SBarry Smith if (n != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 806273d9f13SBarry Smith for (i=0; i<A->m; i++) { 807bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 808bfeeae90SHong Zhang if (a->j[j] == i) { 809416022c9SBarry Smith x[i] = a->a[j]; 81017ab2063SBarry Smith break; 81117ab2063SBarry Smith } 81217ab2063SBarry Smith } 81317ab2063SBarry Smith } 814ed480e8bSBarry Smith ierr = VecRestoreArrayFast(v,&x);CHKERRQ(ierr); 8153a40ed3dSBarry Smith PetscFunctionReturn(0); 81617ab2063SBarry Smith } 81717ab2063SBarry Smith 818d5d45c9bSBarry Smith 8194a2ae208SSatish Balay #undef __FUNCT__ 8204a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 8217c922b88SBarry Smith int MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 82217ab2063SBarry Smith { 823416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8245c897100SBarry Smith PetscScalar *x,*y; 825bfeeae90SHong Zhang int ierr,m = A->m; 8265c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 8275c897100SBarry Smith PetscScalar *v,alpha; 8285c897100SBarry Smith int n,i,*idx; 8295c897100SBarry Smith #endif 83017ab2063SBarry Smith 8313a40ed3dSBarry Smith PetscFunctionBegin; 8322e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 833ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 834ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 8355c897100SBarry Smith 8365c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 837bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 8385c897100SBarry Smith #else 83917ab2063SBarry Smith for (i=0; i<m; i++) { 840bfeeae90SHong Zhang idx = a->j + a->i[i] ; 841bfeeae90SHong Zhang v = a->a + a->i[i] ; 842416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 84317ab2063SBarry Smith alpha = x[i]; 84417ab2063SBarry Smith while (n-->0) {y[*idx++] += alpha * *v++;} 84517ab2063SBarry Smith } 8465c897100SBarry Smith #endif 847b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 848ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 849ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 8503a40ed3dSBarry Smith PetscFunctionReturn(0); 85117ab2063SBarry Smith } 85217ab2063SBarry Smith 8534a2ae208SSatish Balay #undef __FUNCT__ 8545c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 8555c897100SBarry Smith int MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 8565c897100SBarry Smith { 8578d5b0100SBarry Smith PetscScalar zero = 0.0; 8585c897100SBarry Smith int ierr; 8595c897100SBarry Smith 8605c897100SBarry Smith PetscFunctionBegin; 8615c897100SBarry Smith ierr = VecSet(&zero,yy);CHKERRQ(ierr); 8625c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 8635c897100SBarry Smith PetscFunctionReturn(0); 8645c897100SBarry Smith } 8655c897100SBarry Smith 8665c897100SBarry Smith 8675c897100SBarry Smith #undef __FUNCT__ 8684a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 86944cd7ae7SLois Curfman McInnes int MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 87017ab2063SBarry Smith { 871416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 872362ced78SSatish Balay PetscScalar *x,*y,*v; 873bfeeae90SHong Zhang int ierr,m = A->m,*idx,*ii; 874aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 875e36a17ebSSatish Balay int n,i,jrow,j; 876362ced78SSatish Balay PetscScalar sum; 877e36a17ebSSatish Balay #endif 87817ab2063SBarry Smith 879b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 880fee21e36SBarry Smith #pragma disjoint(*x,*y,*v) 881fee21e36SBarry Smith #endif 882fee21e36SBarry Smith 8833a40ed3dSBarry Smith PetscFunctionBegin; 884ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 885ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 886416022c9SBarry Smith idx = a->j; 887d64ed03dSBarry Smith v = a->a; 888416022c9SBarry Smith ii = a->i; 889aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 890bfeeae90SHong Zhang fortranmultaij_(&m,x,ii,idx,v,y); 8918d195f9aSBarry Smith #else 89217ab2063SBarry Smith for (i=0; i<m; i++) { 8939ea0dfa2SSatish Balay jrow = ii[i]; 8949ea0dfa2SSatish Balay n = ii[i+1] - jrow; 89517ab2063SBarry Smith sum = 0.0; 8969ea0dfa2SSatish Balay for (j=0; j<n; j++) { 8979ea0dfa2SSatish Balay sum += v[jrow]*x[idx[jrow]]; jrow++; 8989ea0dfa2SSatish Balay } 89917ab2063SBarry Smith y[i] = sum; 90017ab2063SBarry Smith } 9018d195f9aSBarry Smith #endif 902b0a32e0cSBarry Smith PetscLogFlops(2*a->nz - m); 903ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 904ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 9053a40ed3dSBarry Smith PetscFunctionReturn(0); 90617ab2063SBarry Smith } 90717ab2063SBarry Smith 9084a2ae208SSatish Balay #undef __FUNCT__ 9094a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 91044cd7ae7SLois Curfman McInnes int MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 91117ab2063SBarry Smith { 912416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 913362ced78SSatish Balay PetscScalar *x,*y,*z,*v; 914bfeeae90SHong Zhang int ierr,m = A->m,*idx,*ii; 915aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 916e36a17ebSSatish Balay int n,i,jrow,j; 917362ced78SSatish Balay PetscScalar sum; 918e36a17ebSSatish Balay #endif 9199ea0dfa2SSatish Balay 9203a40ed3dSBarry Smith PetscFunctionBegin; 921ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 922ed480e8bSBarry Smith ierr = VecGetArrayFast(yy,&y);CHKERRQ(ierr); 9232e8a6d31SBarry Smith if (zz != yy) { 924ed480e8bSBarry Smith ierr = VecGetArrayFast(zz,&z);CHKERRQ(ierr); 9252e8a6d31SBarry Smith } else { 9262e8a6d31SBarry Smith z = y; 9272e8a6d31SBarry Smith } 928bfeeae90SHong Zhang 929cddf8d76SBarry Smith idx = a->j; 930d64ed03dSBarry Smith v = a->a; 931cddf8d76SBarry Smith ii = a->i; 932aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 933bfeeae90SHong Zhang fortranmultaddaij_(&m,x,ii,idx,v,y,z); 93402ab625aSSatish Balay #else 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 945b0a32e0cSBarry Smith PetscLogFlops(2*a->nz); 946ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 947ed480e8bSBarry Smith ierr = VecRestoreArrayFast(yy,&y);CHKERRQ(ierr); 9482e8a6d31SBarry Smith if (zz != yy) { 949ed480e8bSBarry Smith ierr = VecRestoreArrayFast(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 */ 9574a2ae208SSatish Balay #undef __FUNCT__ 9584a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 959f1e2ffcdSBarry Smith int MatMarkDiagonal_SeqAIJ(Mat A) 96017ab2063SBarry Smith { 961416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 962bfeeae90SHong Zhang int i,j,*diag,m = A->m,ierr; 96317ab2063SBarry Smith 9643a40ed3dSBarry Smith PetscFunctionBegin; 965f1e2ffcdSBarry Smith if (a->diag) PetscFunctionReturn(0); 966f1e2ffcdSBarry Smith 967b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&diag);CHKERRQ(ierr); 968b0a32e0cSBarry Smith PetscLogObjectMemory(A,(m+1)*sizeof(int)); 969273d9f13SBarry Smith for (i=0; i<A->m; i++) { 97035b0346bSBarry Smith diag[i] = a->i[i+1]; 971bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 972bfeeae90SHong Zhang if (a->j[j] == i) { 973bfeeae90SHong Zhang diag[i] = j; 97417ab2063SBarry Smith break; 97517ab2063SBarry Smith } 97617ab2063SBarry Smith } 97717ab2063SBarry Smith } 978416022c9SBarry Smith a->diag = diag; 9793a40ed3dSBarry Smith PetscFunctionReturn(0); 98017ab2063SBarry Smith } 98117ab2063SBarry Smith 982be5855fcSBarry Smith /* 983be5855fcSBarry Smith Checks for missing diagonals 984be5855fcSBarry Smith */ 9854a2ae208SSatish Balay #undef __FUNCT__ 9864a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 987f1e2ffcdSBarry Smith int MatMissingDiagonal_SeqAIJ(Mat A) 988be5855fcSBarry Smith { 989be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 990bfeeae90SHong Zhang int *diag,*jj = a->j,i,ierr; 991be5855fcSBarry Smith 992be5855fcSBarry Smith PetscFunctionBegin; 993f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 994f1e2ffcdSBarry Smith diag = a->diag; 995273d9f13SBarry Smith for (i=0; i<A->m; i++) { 996bfeeae90SHong Zhang if (jj[diag[i]] != i) { 99729bbc08cSBarry Smith SETERRQ1(1,"Matrix is missing diagonal number %d",i); 998be5855fcSBarry Smith } 999be5855fcSBarry Smith } 1000be5855fcSBarry Smith PetscFunctionReturn(0); 1001be5855fcSBarry Smith } 1002be5855fcSBarry Smith 10034a2ae208SSatish Balay #undef __FUNCT__ 10044a2ae208SSatish Balay #define __FUNCT__ "MatRelax_SeqAIJ" 1005c14dc6b6SHong Zhang int MatRelax_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,int its,int lits,Vec xx) 100617ab2063SBarry Smith { 1007416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1008beeb8507SBarry Smith PetscScalar *x,d,*xs,sum,*t,scale,*idiag=0,*mdiag; 1009beeb8507SBarry Smith const PetscScalar *v = a->a, *b, *bs,*xb, *ts; 1010beeb8507SBarry Smith int ierr,n = A->n,m = A->m,i; 1011beeb8507SBarry Smith const int *idx,*diag; 101217ab2063SBarry Smith 10133a40ed3dSBarry Smith PetscFunctionBegin; 1014b965ef7fSBarry Smith its = its*lits; 101591723122SBarry Smith if (its <= 0) SETERRQ2(PETSC_ERR_ARG_WRONG,"Relaxation requires global its %d and local its %d both positive",its,lits); 101691723122SBarry Smith 1017ed480e8bSBarry Smith if (!a->diag) {ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr);} 1018ed480e8bSBarry Smith diag = a->diag; 1019ed480e8bSBarry Smith if (!a->idiag) { 1020ed480e8bSBarry Smith ierr = PetscMalloc(3*m*sizeof(PetscScalar),&a->idiag);CHKERRQ(ierr); 1021ed480e8bSBarry Smith a->ssor = a->idiag + m; 1022ed480e8bSBarry Smith mdiag = a->ssor + m; 1023ed480e8bSBarry Smith 1024ed480e8bSBarry Smith v = a->a; 1025ed480e8bSBarry Smith 1026ed480e8bSBarry Smith /* this is wrong when fshift omega changes each iteration */ 1027ed480e8bSBarry Smith if (omega == 1.0 && fshift == 0.0) { 1028ed480e8bSBarry Smith for (i=0; i<m; i++) { 1029ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1030ed480e8bSBarry Smith a->idiag[i] = 1.0/v[diag[i]]; 1031ed480e8bSBarry Smith } 1032beeb8507SBarry Smith PetscLogFlops(m); 1033ed480e8bSBarry Smith } else { 1034ed480e8bSBarry Smith for (i=0; i<m; i++) { 1035ed480e8bSBarry Smith mdiag[i] = v[diag[i]]; 1036beeb8507SBarry Smith a->idiag[i] = omega/(fshift + v[diag[i]]); 1037ed480e8bSBarry Smith } 1038beeb8507SBarry Smith PetscLogFlops(2*m); 1039beeb8507SBarry Smith } 1040ed480e8bSBarry Smith } 1041ed480e8bSBarry Smith t = a->ssor; 1042ed480e8bSBarry Smith idiag = a->idiag; 1043ed480e8bSBarry Smith mdiag = a->idiag + 2*m; 1044ed480e8bSBarry Smith 1045ed480e8bSBarry Smith ierr = VecGetArrayFast(xx,&x);CHKERRQ(ierr); 1046fb2e594dSBarry Smith if (xx != bb) { 1047beeb8507SBarry Smith ierr = VecGetArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr); 1048fb2e594dSBarry Smith } else { 1049fb2e594dSBarry Smith b = x; 1050fb2e594dSBarry Smith } 1051fb2e594dSBarry Smith 1052ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 1053ed480e8bSBarry Smith xs = x; 105417ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 105517ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1056ed480e8bSBarry Smith bs = b; 105717ab2063SBarry Smith for (i=0; i<m; i++) { 1058ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1059416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1060ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1061ed480e8bSBarry Smith v = a->a + diag[i] + 1; 106217ab2063SBarry Smith sum = b[i]*d/omega; 106317ab2063SBarry Smith SPARSEDENSEDOT(sum,bs,v,idx,n); 106417ab2063SBarry Smith x[i] = sum; 106517ab2063SBarry Smith } 1066ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1067beeb8507SBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 1068ed480e8bSBarry Smith PetscLogFlops(a->nz); 10693a40ed3dSBarry Smith PetscFunctionReturn(0); 107017ab2063SBarry Smith } 1071c783ea89SBarry Smith 1072ed480e8bSBarry Smith 1073fc3d8934SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1074fc3d8934SBarry Smith U is upper triangular, E is diagonal; This routine applies 1075fc3d8934SBarry Smith 1076fc3d8934SBarry Smith (L + E)^{-1} A (U + E)^{-1} 1077fc3d8934SBarry Smith 1078fc3d8934SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 1079fc3d8934SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 108048af12d7SBarry Smith is the relaxation factor. 1081fc3d8934SBarry Smith */ 1082fc3d8934SBarry Smith 108348af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 108429bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 10853a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 108617ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 108717ab2063SBarry Smith U is upper triangular, E is diagonal; This routine applies 108817ab2063SBarry Smith 108917ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 109017ab2063SBarry Smith 109117ab2063SBarry Smith to a vector efficiently using Eisenstat's trick. This is for 109217ab2063SBarry Smith the case of SSOR preconditioner, so E is D/omega where omega 109317ab2063SBarry Smith is the relaxation factor. 109417ab2063SBarry Smith */ 109517ab2063SBarry Smith scale = (2.0/omega) - 1.0; 109617ab2063SBarry Smith 109717ab2063SBarry Smith /* x = (E + U)^{-1} b */ 109817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1099416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1100ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1101ed480e8bSBarry Smith v = a->a + diag[i] + 1; 110217ab2063SBarry Smith sum = b[i]; 110317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1104ed480e8bSBarry Smith x[i] = sum*idiag[i]; 110517ab2063SBarry Smith } 110617ab2063SBarry Smith 110717ab2063SBarry Smith /* t = b - (2*E - D)x */ 1108416022c9SBarry Smith v = a->a; 1109ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 111017ab2063SBarry Smith 111117ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1112ed480e8bSBarry Smith ts = t; 1113416022c9SBarry Smith diag = a->diag; 111417ab2063SBarry Smith for (i=0; i<m; i++) { 1115416022c9SBarry Smith n = diag[i] - a->i[i]; 1116ed480e8bSBarry Smith idx = a->j + a->i[i]; 1117ed480e8bSBarry Smith v = a->a + a->i[i]; 111817ab2063SBarry Smith sum = t[i]; 111917ab2063SBarry Smith SPARSEDENSEMDOT(sum,ts,v,idx,n); 1120ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1121733d66baSBarry Smith /* x = x + t */ 1122733d66baSBarry Smith x[i] += t[i]; 112317ab2063SBarry Smith } 112417ab2063SBarry Smith 1125b0a32e0cSBarry Smith PetscLogFlops(6*m-1 + 2*a->nz); 1126ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1127beeb8507SBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 11283a40ed3dSBarry Smith PetscFunctionReturn(0); 112917ab2063SBarry Smith } 113017ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 113117ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 113277d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 1133*0c559628SSatish Balay fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,(int *)diag,idiag,a->a,(void*)b); 113477d8c4bbSBarry Smith #else 113517ab2063SBarry Smith for (i=0; i<m; i++) { 1136416022c9SBarry Smith n = diag[i] - a->i[i]; 1137ed480e8bSBarry Smith idx = a->j + a->i[i]; 1138ed480e8bSBarry Smith v = a->a + a->i[i]; 113917ab2063SBarry Smith sum = b[i]; 114017ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1141ed480e8bSBarry Smith x[i] = sum*idiag[i]; 114217ab2063SBarry Smith } 114377d8c4bbSBarry Smith #endif 114417ab2063SBarry Smith xb = x; 1145ed480e8bSBarry Smith PetscLogFlops(a->nz); 11463a40ed3dSBarry Smith } else xb = b; 114717ab2063SBarry Smith if ((flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) && 114817ab2063SBarry Smith (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP)) { 114917ab2063SBarry Smith for (i=0; i<m; i++) { 1150ed480e8bSBarry Smith x[i] *= mdiag[i]; 115117ab2063SBarry Smith } 1152b0a32e0cSBarry Smith PetscLogFlops(m); 115317ab2063SBarry Smith } 115417ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 115577d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 1156*0c559628SSatish Balay fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,(int*)diag,idiag,a->a,(void*)xb); 115777d8c4bbSBarry Smith #else 115817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1159416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1160ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1161ed480e8bSBarry Smith v = a->a + diag[i] + 1; 116217ab2063SBarry Smith sum = xb[i]; 116317ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1164ed480e8bSBarry Smith x[i] = sum*idiag[i]; 116517ab2063SBarry Smith } 116677d8c4bbSBarry Smith #endif 1167ed480e8bSBarry Smith PetscLogFlops(a->nz); 116817ab2063SBarry Smith } 116917ab2063SBarry Smith its--; 117017ab2063SBarry Smith } 117117ab2063SBarry Smith while (its--) { 117217ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 117377d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 1174*0c559628SSatish Balay fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b); 117577d8c4bbSBarry Smith #else 117617ab2063SBarry Smith for (i=0; i<m; i++) { 1177ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1178416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1179ed480e8bSBarry Smith idx = a->j + a->i[i]; 1180ed480e8bSBarry Smith v = a->a + a->i[i]; 118117ab2063SBarry Smith sum = b[i]; 118217ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1183ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 118417ab2063SBarry Smith } 118577d8c4bbSBarry Smith #endif 1186ed480e8bSBarry Smith PetscLogFlops(a->nz); 118717ab2063SBarry Smith } 118817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 118977d8c4bbSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_RELAXAIJ) 1190*0c559628SSatish Balay fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,(int*)diag,a->a,(void*)b); 119177d8c4bbSBarry Smith #else 119217ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1193ed480e8bSBarry Smith d = fshift + a->a[diag[i]]; 1194416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1195ed480e8bSBarry Smith idx = a->j + a->i[i]; 1196ed480e8bSBarry Smith v = a->a + a->i[i]; 119717ab2063SBarry Smith sum = b[i]; 119817ab2063SBarry Smith SPARSEDENSEMDOT(sum,xs,v,idx,n); 1199ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 120017ab2063SBarry Smith } 120177d8c4bbSBarry Smith #endif 1202ed480e8bSBarry Smith PetscLogFlops(a->nz); 120317ab2063SBarry Smith } 120417ab2063SBarry Smith } 1205ed480e8bSBarry Smith ierr = VecRestoreArrayFast(xx,&x);CHKERRQ(ierr); 1206beeb8507SBarry Smith if (bb != xx) {ierr = VecRestoreArrayFast(bb,(PetscScalar**)&b);CHKERRQ(ierr);} 12073a40ed3dSBarry Smith PetscFunctionReturn(0); 120817ab2063SBarry Smith } 120917ab2063SBarry Smith 12104a2ae208SSatish Balay #undef __FUNCT__ 12114a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 12128f6be9afSLois Curfman McInnes int MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 121317ab2063SBarry Smith { 1214416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12154e220ebcSLois Curfman McInnes 12163a40ed3dSBarry Smith PetscFunctionBegin; 1217273d9f13SBarry Smith info->rows_global = (double)A->m; 1218273d9f13SBarry Smith info->columns_global = (double)A->n; 1219273d9f13SBarry Smith info->rows_local = (double)A->m; 1220273d9f13SBarry Smith info->columns_local = (double)A->n; 12214e220ebcSLois Curfman McInnes info->block_size = 1.0; 12224e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 12234e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 12244e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 12254e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 12264e220ebcSLois Curfman McInnes info->mallocs = (double)a->reallocs; 12274e220ebcSLois Curfman McInnes info->memory = A->mem; 12284e220ebcSLois Curfman McInnes if (A->factor) { 12294e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 12304e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 12314e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 12324e220ebcSLois Curfman McInnes } else { 12334e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 12344e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 12354e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 12364e220ebcSLois Curfman McInnes } 12373a40ed3dSBarry Smith PetscFunctionReturn(0); 123817ab2063SBarry Smith } 123917ab2063SBarry Smith 1240b380c88cSHong Zhang EXTERN int MatLUFactorSymbolic_SeqAIJ(Mat,IS,IS,MatFactorInfo*,Mat*); 1241ca44d042SBarry Smith EXTERN int MatLUFactorNumeric_SeqAIJ(Mat,Mat*); 1242b380c88cSHong Zhang EXTERN int MatLUFactor_SeqAIJ(Mat,IS,IS,MatFactorInfo*); 1243ca44d042SBarry Smith EXTERN int MatSolve_SeqAIJ(Mat,Vec,Vec); 1244ca44d042SBarry Smith EXTERN int MatSolveAdd_SeqAIJ(Mat,Vec,Vec,Vec); 1245ca44d042SBarry Smith EXTERN int MatSolveTranspose_SeqAIJ(Mat,Vec,Vec); 1246ca44d042SBarry Smith EXTERN int MatSolveTransposeAdd_SeqAIJ(Mat,Vec,Vec,Vec); 124717ab2063SBarry Smith 12484a2ae208SSatish Balay #undef __FUNCT__ 12494a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 1250268466fbSBarry Smith int MatZeroRows_SeqAIJ(Mat A,IS is,const PetscScalar *diag) 125117ab2063SBarry Smith { 1252416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1253bfeeae90SHong Zhang int i,ierr,N,*rows,m = A->m - 1; 125417ab2063SBarry Smith 12553a40ed3dSBarry Smith PetscFunctionBegin; 1256b9b97703SBarry Smith ierr = ISGetLocalSize(is,&N);CHKERRQ(ierr); 125717ab2063SBarry Smith ierr = ISGetIndices(is,&rows);CHKERRQ(ierr); 1258f1e2ffcdSBarry Smith if (a->keepzeroedrows) { 1259f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 126029bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 1261bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1262f1e2ffcdSBarry Smith } 1263f1e2ffcdSBarry Smith if (diag) { 1264f1e2ffcdSBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1265f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 1266f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1267f1e2ffcdSBarry Smith a->a[a->diag[rows[i]]] = *diag; 1268f1e2ffcdSBarry Smith } 1269f1e2ffcdSBarry Smith } 1270f1e2ffcdSBarry Smith } else { 127117ab2063SBarry Smith if (diag) { 127217ab2063SBarry Smith for (i=0; i<N; i++) { 127329bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 12747ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1275416022c9SBarry Smith a->ilen[rows[i]] = 1; 1276bfeeae90SHong Zhang a->a[a->i[rows[i]]] = *diag; 1277bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 12787ae801bdSBarry Smith } else { /* in case row was completely empty */ 1279d64ed03dSBarry Smith ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],diag,INSERT_VALUES);CHKERRQ(ierr); 128017ab2063SBarry Smith } 128117ab2063SBarry Smith } 12823a40ed3dSBarry Smith } else { 128317ab2063SBarry Smith for (i=0; i<N; i++) { 128429bbc08cSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"row out of range"); 1285416022c9SBarry Smith a->ilen[rows[i]] = 0; 128617ab2063SBarry Smith } 128717ab2063SBarry Smith } 1288f1e2ffcdSBarry Smith } 12897ae801bdSBarry Smith ierr = ISRestoreIndices(is,&rows);CHKERRQ(ierr); 129043a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12913a40ed3dSBarry Smith PetscFunctionReturn(0); 129217ab2063SBarry Smith } 129317ab2063SBarry Smith 12944a2ae208SSatish Balay #undef __FUNCT__ 12954a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 129687828ca2SBarry Smith int MatGetRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 129717ab2063SBarry Smith { 1298416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1299b3fb0a6cSMatthew Knepley int *itmp; 130017ab2063SBarry Smith 13013a40ed3dSBarry Smith PetscFunctionBegin; 1302273d9f13SBarry Smith if (row < 0 || row >= A->m) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Row %d out of range",row); 130317ab2063SBarry Smith 1304416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1305bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 130617ab2063SBarry Smith if (idx) { 1307bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1308bfeeae90SHong Zhang if (*nz) { 13094e093b46SBarry Smith *idx = itmp; 131017ab2063SBarry Smith } 131117ab2063SBarry Smith else *idx = 0; 131217ab2063SBarry Smith } 13133a40ed3dSBarry Smith PetscFunctionReturn(0); 131417ab2063SBarry Smith } 131517ab2063SBarry Smith 1316bfeeae90SHong Zhang /* remove this function? */ 13174a2ae208SSatish Balay #undef __FUNCT__ 13184a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 131987828ca2SBarry Smith int MatRestoreRow_SeqAIJ(Mat A,int row,int *nz,int **idx,PetscScalar **v) 132017ab2063SBarry Smith { 1321bfeeae90SHong Zhang /* Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1322bfeeae90SHong Zhang int ierr; */ 13233a40ed3dSBarry Smith 13243a40ed3dSBarry Smith PetscFunctionBegin; 1325bfeeae90SHong Zhang /* if (idx) {if (*idx && a->indexshift) {ierr = PetscFree(*idx);CHKERRQ(ierr);}} */ 13263a40ed3dSBarry Smith PetscFunctionReturn(0); 132717ab2063SBarry Smith } 132817ab2063SBarry Smith 13294a2ae208SSatish Balay #undef __FUNCT__ 13304a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1331064f8208SBarry Smith int MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 133217ab2063SBarry Smith { 1333416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 133487828ca2SBarry Smith PetscScalar *v = a->a; 133536db0b34SBarry Smith PetscReal sum = 0.0; 1336bfeeae90SHong Zhang int i,j,ierr; 133717ab2063SBarry Smith 13383a40ed3dSBarry Smith PetscFunctionBegin; 133917ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1340416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1341aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 134236db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 134317ab2063SBarry Smith #else 134417ab2063SBarry Smith sum += (*v)*(*v); v++; 134517ab2063SBarry Smith #endif 134617ab2063SBarry Smith } 1347064f8208SBarry Smith *nrm = sqrt(sum); 13483a40ed3dSBarry Smith } else if (type == NORM_1) { 134936db0b34SBarry Smith PetscReal *tmp; 1350416022c9SBarry Smith int *jj = a->j; 1351b0a32e0cSBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1352273d9f13SBarry Smith ierr = PetscMemzero(tmp,A->n*sizeof(PetscReal));CHKERRQ(ierr); 1353064f8208SBarry Smith *nrm = 0.0; 1354416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1355bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 135617ab2063SBarry Smith } 1357273d9f13SBarry Smith for (j=0; j<A->n; j++) { 1358064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 135917ab2063SBarry Smith } 1360606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 13613a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1362064f8208SBarry Smith *nrm = 0.0; 1363273d9f13SBarry Smith for (j=0; j<A->m; j++) { 1364bfeeae90SHong Zhang v = a->a + a->i[j]; 136517ab2063SBarry Smith sum = 0.0; 1366416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1367cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 136817ab2063SBarry Smith } 1369064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 137017ab2063SBarry Smith } 13713a40ed3dSBarry Smith } else { 137229bbc08cSBarry Smith SETERRQ(PETSC_ERR_SUP,"No support for two norm"); 137317ab2063SBarry Smith } 13743a40ed3dSBarry Smith PetscFunctionReturn(0); 137517ab2063SBarry Smith } 137617ab2063SBarry Smith 13774a2ae208SSatish Balay #undef __FUNCT__ 13784a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 13798f6be9afSLois Curfman McInnes int MatTranspose_SeqAIJ(Mat A,Mat *B) 138017ab2063SBarry Smith { 1381416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1382416022c9SBarry Smith Mat C; 1383273d9f13SBarry Smith int i,ierr,*aj = a->j,*ai = a->i,m = A->m,len,*col; 138487828ca2SBarry Smith PetscScalar *array = a->a; 138517ab2063SBarry Smith 13863a40ed3dSBarry Smith PetscFunctionBegin; 1387273d9f13SBarry Smith if (!B && m != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1388b0a32e0cSBarry Smith ierr = PetscMalloc((1+A->n)*sizeof(int),&col);CHKERRQ(ierr); 1389273d9f13SBarry Smith ierr = PetscMemzero(col,(1+A->n)*sizeof(int));CHKERRQ(ierr); 1390bfeeae90SHong Zhang 1391bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 1392273d9f13SBarry Smith ierr = MatCreateSeqAIJ(A->comm,A->n,m,0,col,&C);CHKERRQ(ierr); 1393606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 139417ab2063SBarry Smith for (i=0; i<m; i++) { 139517ab2063SBarry Smith len = ai[i+1]-ai[i]; 1396416022c9SBarry Smith ierr = MatSetValues(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1397b9b97703SBarry Smith array += len; 1398b9b97703SBarry Smith aj += len; 139917ab2063SBarry Smith } 140017ab2063SBarry Smith 14016d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14026d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 140317ab2063SBarry Smith 1404f1e2ffcdSBarry Smith if (B) { 1405416022c9SBarry Smith *B = C; 140617ab2063SBarry Smith } else { 1407273d9f13SBarry Smith ierr = MatHeaderCopy(A,C);CHKERRQ(ierr); 140817ab2063SBarry Smith } 14093a40ed3dSBarry Smith PetscFunctionReturn(0); 141017ab2063SBarry Smith } 141117ab2063SBarry Smith 1412cd0d46ebSvictorle EXTERN_C_BEGIN 1413cd0d46ebSvictorle #undef __FUNCT__ 1414cd0d46ebSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1415cd0d46ebSvictorle int MatIsSymmetric_SeqAIJ(Mat A,Mat B,PetscTruth *f) 1416cd0d46ebSvictorle { 1417cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 1418cd0d46ebSvictorle int *adx,*bdx,*aii,*bii,*aptr,*bptr; PetscScalar *va,*vb; 1419cd0d46ebSvictorle int ma,na,mb,nb, i,ierr; 1420cd0d46ebSvictorle 1421cd0d46ebSvictorle PetscFunctionBegin; 1422cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1423cd0d46ebSvictorle 1424cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na); CHKERRQ(ierr); 1425cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb); CHKERRQ(ierr); 1426cd0d46ebSvictorle if (ma!=nb || na!=mb) 1427cd0d46ebSvictorle SETERRQ(1,"Incompatible A/B sizes for symmetry test"); 1428cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1429cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1430cd0d46ebSvictorle va = aij->a; vb = bij->a; 1431cd0d46ebSvictorle ierr = PetscMalloc(ma*sizeof(int),&aptr); CHKERRQ(ierr); 1432cd0d46ebSvictorle ierr = PetscMalloc(mb*sizeof(int),&bptr); CHKERRQ(ierr); 1433cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1434cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1435cd0d46ebSvictorle 1436cd0d46ebSvictorle *f = PETSC_TRUE; 1437cd0d46ebSvictorle for (i=0; i<ma; i++) { 1438cd0d46ebSvictorle /*printf("row %d spans %d--%d; we start @ %d\n", 1439cd0d46ebSvictorle i,idx[ii[i]],idx[ii[i+1]-1],idx[aptr[i]]);*/ 1440cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 1441cd0d46ebSvictorle int idc,idr; PetscScalar vc,vr; 1442cd0d46ebSvictorle /* column/row index/value */ 1443cd0d46ebSvictorle idc = adx[aptr[i]]; idr = bdx[bptr[idc]]; 1444cd0d46ebSvictorle vc = va[aptr[i]]; vr = vb[bptr[idc]]; 1445cd0d46ebSvictorle /*printf("comparing %d: (%d,%d)=%e to (%d,%d)=%e\n", 1446cd0d46ebSvictorle aptr[i],i,idc,vc,idc,idr,vr);*/ 1447cd0d46ebSvictorle if (i!=idr || vc!=vr) { 1448cd0d46ebSvictorle *f = PETSC_FALSE; goto done; 1449cd0d46ebSvictorle } else { 14503aeef889SHong Zhang aptr[i]++; if (B || i!=idc) bptr[idc]++; 1451cd0d46ebSvictorle } 1452cd0d46ebSvictorle } 1453cd0d46ebSvictorle } 1454cd0d46ebSvictorle done: 1455cd0d46ebSvictorle ierr = PetscFree(aptr); CHKERRQ(ierr); 14563aeef889SHong Zhang if (B) { 14573aeef889SHong Zhang ierr = PetscFree(bptr); CHKERRQ(ierr); 14583aeef889SHong Zhang } 1459cd0d46ebSvictorle 1460cd0d46ebSvictorle PetscFunctionReturn(0); 1461cd0d46ebSvictorle } 1462cd0d46ebSvictorle EXTERN_C_END 1463cd0d46ebSvictorle 14644a2ae208SSatish Balay #undef __FUNCT__ 14654a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 14668f6be9afSLois Curfman McInnes int MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 146717ab2063SBarry Smith { 1468416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 146987828ca2SBarry Smith PetscScalar *l,*r,x,*v; 1470bfeeae90SHong Zhang int ierr,i,j,m = A->m,n = A->n,M,nz = a->nz,*jj; 147117ab2063SBarry Smith 14723a40ed3dSBarry Smith PetscFunctionBegin; 147317ab2063SBarry Smith if (ll) { 14743ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 14753ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1476e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1477273d9f13SBarry Smith if (m != A->m) SETERRQ(PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 1478ed480e8bSBarry Smith ierr = VecGetArrayFast(ll,&l);CHKERRQ(ierr); 1479416022c9SBarry Smith v = a->a; 148017ab2063SBarry Smith for (i=0; i<m; i++) { 148117ab2063SBarry Smith x = l[i]; 1482416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 148317ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 148417ab2063SBarry Smith } 1485ed480e8bSBarry Smith ierr = VecRestoreArrayFast(ll,&l);CHKERRQ(ierr); 1486b0a32e0cSBarry Smith PetscLogFlops(nz); 148717ab2063SBarry Smith } 148817ab2063SBarry Smith if (rr) { 1489e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1490273d9f13SBarry Smith if (n != A->n) SETERRQ(PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 1491ed480e8bSBarry Smith ierr = VecGetArrayFast(rr,&r);CHKERRQ(ierr); 1492416022c9SBarry Smith v = a->a; jj = a->j; 149317ab2063SBarry Smith for (i=0; i<nz; i++) { 1494bfeeae90SHong Zhang (*v++) *= r[*jj++]; 149517ab2063SBarry Smith } 1496ed480e8bSBarry Smith ierr = VecRestoreArrayFast(rr,&r);CHKERRQ(ierr); 1497b0a32e0cSBarry Smith PetscLogFlops(nz); 149817ab2063SBarry Smith } 14993a40ed3dSBarry Smith PetscFunctionReturn(0); 150017ab2063SBarry Smith } 150117ab2063SBarry Smith 15024a2ae208SSatish Balay #undef __FUNCT__ 15034a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 15047b2a1423SBarry Smith int MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,int csize,MatReuse scall,Mat *B) 150517ab2063SBarry Smith { 1506db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 1507273d9f13SBarry Smith int *smap,i,k,kstart,kend,ierr,oldcols = A->n,*lens; 150836db0b34SBarry Smith int row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 1509bfeeae90SHong Zhang int *irow,*icol,nrows,ncols; 151099141d43SSatish Balay int *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 151187828ca2SBarry Smith PetscScalar *a_new,*mat_a; 1512416022c9SBarry Smith Mat C; 1513fee21e36SBarry Smith PetscTruth stride; 151417ab2063SBarry Smith 15153a40ed3dSBarry Smith PetscFunctionBegin; 1516d64ed03dSBarry Smith ierr = ISSorted(isrow,(PetscTruth*)&i);CHKERRQ(ierr); 151729bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 1518d64ed03dSBarry Smith ierr = ISSorted(iscol,(PetscTruth*)&i);CHKERRQ(ierr); 151929bbc08cSBarry Smith if (!i) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 152099141d43SSatish Balay 152117ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 1522b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1523b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 152417ab2063SBarry Smith 1525fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 1526fee21e36SBarry Smith ierr = ISStride(iscol,&stride);CHKERRQ(ierr); 1527fee21e36SBarry Smith if (stride && step == 1) { 152802834360SBarry Smith /* special case of contiguous rows */ 152931ebf83bSSatish Balay ierr = PetscMalloc((2*nrows+1)*sizeof(int),&lens);CHKERRQ(ierr); 153031ebf83bSSatish Balay starts = lens + nrows; 153102834360SBarry Smith /* loop over new rows determining lens and starting points */ 153202834360SBarry Smith for (i=0; i<nrows; i++) { 1533bfeeae90SHong Zhang kstart = ai[irow[i]]; 1534a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 153502834360SBarry Smith for (k=kstart; k<kend; k++) { 1536bfeeae90SHong Zhang if (aj[k] >= first) { 153702834360SBarry Smith starts[i] = k; 153802834360SBarry Smith break; 153902834360SBarry Smith } 154002834360SBarry Smith } 1541a2744918SBarry Smith sum = 0; 154202834360SBarry Smith while (k < kend) { 1543bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 1544a2744918SBarry Smith sum++; 154502834360SBarry Smith } 1546a2744918SBarry Smith lens[i] = sum; 154702834360SBarry Smith } 154802834360SBarry Smith /* create submatrix */ 1549cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 155008480c60SBarry Smith int n_cols,n_rows; 155108480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 155229bbc08cSBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 1553d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 155408480c60SBarry Smith C = *B; 15553a40ed3dSBarry Smith } else { 155602834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 155708480c60SBarry Smith } 1558db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 1559db02288aSLois Curfman McInnes 156002834360SBarry Smith /* loop over rows inserting into submatrix */ 1561db02288aSLois Curfman McInnes a_new = c->a; 1562db02288aSLois Curfman McInnes j_new = c->j; 1563db02288aSLois Curfman McInnes i_new = c->i; 1564bfeeae90SHong Zhang 156502834360SBarry Smith for (i=0; i<nrows; i++) { 1566a2744918SBarry Smith ii = starts[i]; 1567a2744918SBarry Smith lensi = lens[i]; 1568a2744918SBarry Smith for (k=0; k<lensi; k++) { 1569a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 157002834360SBarry Smith } 157187828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 1572a2744918SBarry Smith a_new += lensi; 1573a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 1574a2744918SBarry Smith c->ilen[i] = lensi; 157502834360SBarry Smith } 1576606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 15773a40ed3dSBarry Smith } else { 157802834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1579b0a32e0cSBarry Smith ierr = PetscMalloc((1+oldcols)*sizeof(int),&smap);CHKERRQ(ierr); 1580bfeeae90SHong Zhang 1581b0a32e0cSBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(int),&lens);CHKERRQ(ierr); 1582549d3d68SSatish Balay ierr = PetscMemzero(smap,oldcols*sizeof(int));CHKERRQ(ierr); 158317ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 158402834360SBarry Smith /* determine lens of each row */ 158502834360SBarry Smith for (i=0; i<nrows; i++) { 1586bfeeae90SHong Zhang kstart = ai[irow[i]]; 158702834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 158802834360SBarry Smith lens[i] = 0; 158902834360SBarry Smith for (k=kstart; k<kend; k++) { 1590bfeeae90SHong Zhang if (smap[aj[k]]) { 159102834360SBarry Smith lens[i]++; 159202834360SBarry Smith } 159302834360SBarry Smith } 159402834360SBarry Smith } 159517ab2063SBarry Smith /* Create and fill new matrix */ 1596a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 15970f5bd95cSBarry Smith PetscTruth equal; 15980f5bd95cSBarry Smith 159999141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 1600273d9f13SBarry Smith if ((*B)->m != nrows || (*B)->n != ncols) SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 1601273d9f13SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->m*sizeof(int),&equal);CHKERRQ(ierr); 16020f5bd95cSBarry Smith if (!equal) { 160329bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 160499141d43SSatish Balay } 1605273d9f13SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->m*sizeof(int));CHKERRQ(ierr); 160608480c60SBarry Smith C = *B; 16073a40ed3dSBarry Smith } else { 160802834360SBarry Smith ierr = MatCreateSeqAIJ(A->comm,nrows,ncols,0,lens,&C);CHKERRQ(ierr); 160908480c60SBarry Smith } 161099141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 161117ab2063SBarry Smith for (i=0; i<nrows; i++) { 161299141d43SSatish Balay row = irow[i]; 1613bfeeae90SHong Zhang kstart = ai[row]; 161499141d43SSatish Balay kend = kstart + a->ilen[row]; 1615bfeeae90SHong Zhang mat_i = c->i[i]; 161699141d43SSatish Balay mat_j = c->j + mat_i; 161799141d43SSatish Balay mat_a = c->a + mat_i; 161899141d43SSatish Balay mat_ilen = c->ilen + i; 161917ab2063SBarry Smith for (k=kstart; k<kend; k++) { 1620bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 1621ed480e8bSBarry Smith *mat_j++ = tcol - 1; 162299141d43SSatish Balay *mat_a++ = a->a[k]; 162399141d43SSatish Balay (*mat_ilen)++; 162499141d43SSatish Balay 162517ab2063SBarry Smith } 162617ab2063SBarry Smith } 162717ab2063SBarry Smith } 162802834360SBarry Smith /* Free work space */ 162902834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1630606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 1631606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 163202834360SBarry Smith } 16336d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16346d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 163517ab2063SBarry Smith 163617ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 1637416022c9SBarry Smith *B = C; 16383a40ed3dSBarry Smith PetscFunctionReturn(0); 163917ab2063SBarry Smith } 164017ab2063SBarry Smith 1641a871dcd8SBarry Smith /* 1642a871dcd8SBarry Smith */ 16434a2ae208SSatish Balay #undef __FUNCT__ 16444a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 1645b380c88cSHong Zhang int MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,MatFactorInfo *info) 1646a871dcd8SBarry Smith { 164763b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 164808480c60SBarry Smith int ierr; 164963b91edcSBarry Smith Mat outA; 1650b8a78c4aSBarry Smith PetscTruth row_identity,col_identity; 165163b91edcSBarry Smith 16523a40ed3dSBarry Smith PetscFunctionBegin; 1653d3d32019SBarry Smith if (info->levels != 0) SETERRQ(PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 1654b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 1655b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 1656b8a78c4aSBarry Smith if (!row_identity || !col_identity) { 165729bbc08cSBarry Smith SETERRQ(1,"Row and column permutations must be identity for in-place ILU"); 1658b8a78c4aSBarry Smith } 1659a871dcd8SBarry Smith 166063b91edcSBarry Smith outA = inA; 166163b91edcSBarry Smith inA->factor = FACTOR_LU; 166263b91edcSBarry Smith a->row = row; 166363b91edcSBarry Smith a->col = col; 1664c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 1665c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 166663b91edcSBarry Smith 166736db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 1668b9b97703SBarry Smith if (a->icol) {ierr = ISDestroy(a->icol);CHKERRQ(ierr);} /* need to remove old one */ 16694c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 1670b0a32e0cSBarry Smith PetscLogObjectParent(inA,a->icol); 1671f0ec6fceSSatish Balay 167294a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 167387828ca2SBarry Smith ierr = PetscMalloc((inA->m+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 167494a9d846SBarry Smith } 167563b91edcSBarry Smith 167608480c60SBarry Smith if (!a->diag) { 1677f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 167863b91edcSBarry Smith } 167963b91edcSBarry Smith ierr = MatLUFactorNumeric_SeqAIJ(inA,&outA);CHKERRQ(ierr); 16803a40ed3dSBarry Smith PetscFunctionReturn(0); 1681a871dcd8SBarry Smith } 1682a871dcd8SBarry Smith 1683d9eff348SSatish Balay #include "petscblaslapack.h" 16844a2ae208SSatish Balay #undef __FUNCT__ 16854a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 1686268466fbSBarry Smith int MatScale_SeqAIJ(const PetscScalar *alpha,Mat inA) 1687f0b747eeSBarry Smith { 1688f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 1689f0b747eeSBarry Smith int one = 1; 16903a40ed3dSBarry Smith 16913a40ed3dSBarry Smith PetscFunctionBegin; 1692268466fbSBarry Smith BLscal_(&a->nz,(PetscScalar*)alpha,a->a,&one); 1693b0a32e0cSBarry Smith PetscLogFlops(a->nz); 16943a40ed3dSBarry Smith PetscFunctionReturn(0); 1695f0b747eeSBarry Smith } 1696f0b747eeSBarry Smith 16974a2ae208SSatish Balay #undef __FUNCT__ 16984a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 1699268466fbSBarry Smith int MatGetSubMatrices_SeqAIJ(Mat A,int n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1700cddf8d76SBarry Smith { 1701cddf8d76SBarry Smith int ierr,i; 1702cddf8d76SBarry Smith 17033a40ed3dSBarry Smith PetscFunctionBegin; 1704cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1705b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 1706cddf8d76SBarry Smith } 1707cddf8d76SBarry Smith 1708cddf8d76SBarry Smith for (i=0; i<n; i++) { 17096a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1710cddf8d76SBarry Smith } 17113a40ed3dSBarry Smith PetscFunctionReturn(0); 1712cddf8d76SBarry Smith } 1713cddf8d76SBarry Smith 17144a2ae208SSatish Balay #undef __FUNCT__ 17154a2ae208SSatish Balay #define __FUNCT__ "MatGetBlockSize_SeqAIJ" 17168f6be9afSLois Curfman McInnes int MatGetBlockSize_SeqAIJ(Mat A,int *bs) 17175a838052SSatish Balay { 1718f830108cSBarry Smith PetscFunctionBegin; 17195a838052SSatish Balay *bs = 1; 17203a40ed3dSBarry Smith PetscFunctionReturn(0); 17215a838052SSatish Balay } 17225a838052SSatish Balay 17234a2ae208SSatish Balay #undef __FUNCT__ 17244a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 1725268466fbSBarry Smith int MatIncreaseOverlap_SeqAIJ(Mat A,int is_max,IS is[],int ov) 17264dcbc457SBarry Smith { 1727e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1728efb16452SHong Zhang int row,i,j,k,l,m,n,*idx,ierr,*nidx,isz,val; 17298a047759SSatish Balay int start,end,*ai,*aj; 1730f1af5d2fSBarry Smith PetscBT table; 1731bbd702dbSSatish Balay 17323a40ed3dSBarry Smith PetscFunctionBegin; 1733273d9f13SBarry Smith m = A->m; 1734e4d965acSSatish Balay ai = a->i; 1735bfeeae90SHong Zhang aj = a->j; 17368a047759SSatish Balay 173729bbc08cSBarry Smith if (ov < 0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"illegal overlap value used"); 173806763907SSatish Balay 1739b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&nidx);CHKERRQ(ierr); 17406831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 174106763907SSatish Balay 1742e4d965acSSatish Balay for (i=0; i<is_max; i++) { 1743b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 1744e4d965acSSatish Balay isz = 0; 17456831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 1746e4d965acSSatish Balay 1747e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 17484dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 1749b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 1750e4d965acSSatish Balay 1751dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 1752e4d965acSSatish Balay for (j=0; j<n ; ++j){ 1753f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 17544dcbc457SBarry Smith } 175506763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 175606763907SSatish Balay ierr = ISDestroy(is[i]);CHKERRQ(ierr); 1757e4d965acSSatish Balay 175804a348a9SBarry Smith k = 0; 175904a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 176004a348a9SBarry Smith n = isz; 176106763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 1762e4d965acSSatish Balay row = nidx[k]; 1763e4d965acSSatish Balay start = ai[row]; 1764e4d965acSSatish Balay end = ai[row+1]; 176504a348a9SBarry Smith for (l = start; l<end ; l++){ 1766efb16452SHong Zhang val = aj[l] ; 1767f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 1768e4d965acSSatish Balay } 1769e4d965acSSatish Balay } 1770e4d965acSSatish Balay } 1771029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,(is+i));CHKERRQ(ierr); 1772e4d965acSSatish Balay } 17736831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 1774606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 17753a40ed3dSBarry Smith PetscFunctionReturn(0); 17764dcbc457SBarry Smith } 177717ab2063SBarry Smith 17780513a670SBarry Smith /* -------------------------------------------------------------- */ 17794a2ae208SSatish Balay #undef __FUNCT__ 17804a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 17810513a670SBarry Smith int MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 17820513a670SBarry Smith { 17830513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 178487828ca2SBarry Smith PetscScalar *vwork; 1785273d9f13SBarry Smith int i,ierr,nz,m = A->m,n = A->n,*cwork; 17860513a670SBarry Smith int *row,*col,*cnew,j,*lens; 178756cd22aeSBarry Smith IS icolp,irowp; 17880513a670SBarry Smith 17893a40ed3dSBarry Smith PetscFunctionBegin; 17904c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 179156cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 17924c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 179356cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 17940513a670SBarry Smith 17950513a670SBarry Smith /* determine lengths of permuted rows */ 1796b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&lens);CHKERRQ(ierr); 17970513a670SBarry Smith for (i=0; i<m; i++) { 17980513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 17990513a670SBarry Smith } 18000513a670SBarry Smith ierr = MatCreateSeqAIJ(A->comm,m,n,0,lens,B);CHKERRQ(ierr); 1801606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 18020513a670SBarry Smith 1803b0a32e0cSBarry Smith ierr = PetscMalloc(n*sizeof(int),&cnew);CHKERRQ(ierr); 18040513a670SBarry Smith for (i=0; i<m; i++) { 18050513a670SBarry Smith ierr = MatGetRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18060513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 18070513a670SBarry Smith ierr = MatSetValues(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 18080513a670SBarry Smith ierr = MatRestoreRow(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 18090513a670SBarry Smith } 1810606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 18110513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18120513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 181356cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 181456cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 181556cd22aeSBarry Smith ierr = ISDestroy(irowp);CHKERRQ(ierr); 181656cd22aeSBarry Smith ierr = ISDestroy(icolp);CHKERRQ(ierr); 18173a40ed3dSBarry Smith PetscFunctionReturn(0); 18180513a670SBarry Smith } 18190513a670SBarry Smith 18204a2ae208SSatish Balay #undef __FUNCT__ 18214a2ae208SSatish Balay #define __FUNCT__ "MatPrintHelp_SeqAIJ" 1822682d7d0cSBarry Smith int MatPrintHelp_SeqAIJ(Mat A) 1823682d7d0cSBarry Smith { 1824c38d4ed2SBarry Smith static PetscTruth called = PETSC_FALSE; 1825682d7d0cSBarry Smith MPI_Comm comm = A->comm; 1826d132466eSBarry Smith int ierr; 1827682d7d0cSBarry Smith 18283a40ed3dSBarry Smith PetscFunctionBegin; 1829c38d4ed2SBarry Smith if (called) {PetscFunctionReturn(0);} else called = PETSC_TRUE; 1830d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," Options for MATSEQAIJ and MATMPIAIJ matrix formats (the defaults):\n");CHKERRQ(ierr); 1831d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_lu_pivotthreshold <threshold>: Set pivoting threshold\n");CHKERRQ(ierr); 1832d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_oneindex: internal indices begin at 1 instead of the default 0.\n");CHKERRQ(ierr); 1833d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_no_inode: Do not use inodes\n");CHKERRQ(ierr); 1834d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_inode_limit <limit>: Set inode limit (max limit=5)\n");CHKERRQ(ierr); 183587828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 1836ca44d042SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr); 1837ca44d042SBarry Smith #endif 18383a40ed3dSBarry Smith PetscFunctionReturn(0); 1839682d7d0cSBarry Smith } 1840ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg); 1841ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1842b380c88cSHong Zhang EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatFactorInfo*,IS,IS,Mat*); 18434a2ae208SSatish Balay #undef __FUNCT__ 18444a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1845cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1846cb5b572fSBarry Smith { 1847be6bf707SBarry Smith int ierr; 1848cb5b572fSBarry Smith 1849cb5b572fSBarry Smith PetscFunctionBegin; 185033f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 185133f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1852be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1853be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1854be6bf707SBarry Smith 1855bfeeae90SHong Zhang if (a->i[A->m] != b->i[B->m]) { 185629bbc08cSBarry Smith SETERRQ(1,"Number of nonzeros in two matrices are different"); 1857cb5b572fSBarry Smith } 1858bfeeae90SHong Zhang ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 1859cb5b572fSBarry Smith } else { 1860cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1861cb5b572fSBarry Smith } 1862cb5b572fSBarry Smith PetscFunctionReturn(0); 1863cb5b572fSBarry Smith } 1864cb5b572fSBarry Smith 18654a2ae208SSatish Balay #undef __FUNCT__ 18664a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1867273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A) 1868273d9f13SBarry Smith { 1869273d9f13SBarry Smith int ierr; 1870273d9f13SBarry Smith 1871273d9f13SBarry Smith PetscFunctionBegin; 1872273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1873273d9f13SBarry Smith PetscFunctionReturn(0); 1874273d9f13SBarry Smith } 1875273d9f13SBarry Smith 18764a2ae208SSatish Balay #undef __FUNCT__ 18774a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 18784e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 18796c0721eeSBarry Smith { 18806c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18816c0721eeSBarry Smith PetscFunctionBegin; 18826c0721eeSBarry Smith *array = a->a; 18836c0721eeSBarry Smith PetscFunctionReturn(0); 18846c0721eeSBarry Smith } 18856c0721eeSBarry Smith 18864a2ae208SSatish Balay #undef __FUNCT__ 18874a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 18884e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 18896c0721eeSBarry Smith { 18906c0721eeSBarry Smith PetscFunctionBegin; 18916c0721eeSBarry Smith PetscFunctionReturn(0); 18926c0721eeSBarry Smith } 1893273d9f13SBarry Smith 1894ee4f033dSBarry Smith #undef __FUNCT__ 1895ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1896ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1897ee4f033dSBarry Smith { 1898ee4f033dSBarry Smith int (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f; 1899ee4f033dSBarry Smith int k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 190087828ca2SBarry Smith PetscScalar dx,mone = -1.0,*y,*xx,*w3_array; 190187828ca2SBarry Smith PetscScalar *vscale_array; 1902ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1903ee4f033dSBarry Smith Vec w1,w2,w3; 1904ee4f033dSBarry Smith void *fctx = coloring->fctx; 1905ee4f033dSBarry Smith PetscTruth flg; 1906ee4f033dSBarry Smith 1907ee4f033dSBarry Smith PetscFunctionBegin; 1908ee4f033dSBarry Smith if (!coloring->w1) { 1909ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 1910ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w1); 1911ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 1912ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w2); 1913ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 1914ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w3); 1915ee4f033dSBarry Smith } 1916ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1917ee4f033dSBarry Smith 1918ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1919e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1920ee4f033dSBarry Smith if (flg) { 1921ee4f033dSBarry Smith PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"); 1922ee4f033dSBarry Smith } else { 1923ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1924ee4f033dSBarry Smith } 1925ee4f033dSBarry Smith 1926ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1927ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 1928ee4f033dSBarry Smith 1929ee4f033dSBarry Smith /* 1930ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 1931ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 1932ee4f033dSBarry Smith */ 1933ee4f033dSBarry Smith if (coloring->F) { 1934ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 1935ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 1936ee4f033dSBarry Smith if (m1 != m2) { 1937ee4f033dSBarry Smith coloring->F = 0; 1938ee4f033dSBarry Smith } 1939ee4f033dSBarry Smith } 1940ee4f033dSBarry Smith 1941ee4f033dSBarry Smith if (coloring->F) { 1942ee4f033dSBarry Smith w1 = coloring->F; 1943ee4f033dSBarry Smith coloring->F = 0; 1944ee4f033dSBarry Smith } else { 194566f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1946ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 194766f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1948ee4f033dSBarry Smith } 1949ee4f033dSBarry Smith 1950ee4f033dSBarry Smith /* 1951ee4f033dSBarry Smith Compute all the scale factors and share with other processors 1952ee4f033dSBarry Smith */ 1953ed480e8bSBarry Smith ierr = VecGetArrayFast(x1,&xx);CHKERRQ(ierr);xx = xx - start; 1954ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 1955ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 1956ee4f033dSBarry Smith /* 1957ee4f033dSBarry Smith Loop over each column associated with color adding the 1958ee4f033dSBarry Smith perturbation to the vector w3. 1959ee4f033dSBarry Smith */ 1960ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1961ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1962ee4f033dSBarry Smith dx = xx[col]; 1963ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 1964ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 1965ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 1966ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 1967ee4f033dSBarry Smith #else 1968ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 1969ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 1970ee4f033dSBarry Smith #endif 1971ee4f033dSBarry Smith dx *= epsilon; 1972ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 1973ee4f033dSBarry Smith } 1974ee4f033dSBarry Smith } 1975ed480e8bSBarry Smith vscale_array = vscale_array + start;ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1976ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1977ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1978ee4f033dSBarry Smith 1979ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 1980ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 1981ee4f033dSBarry Smith 1982ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 1983ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 1984ee4f033dSBarry Smith 1985ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1986ee4f033dSBarry Smith /* 1987ee4f033dSBarry Smith Loop over each color 1988ee4f033dSBarry Smith */ 1989ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 199049b058dcSBarry Smith coloring->currentcolor = k; 1991ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 1992ed480e8bSBarry Smith ierr = VecGetArrayFast(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 1993ee4f033dSBarry Smith /* 1994ee4f033dSBarry Smith Loop over each column associated with color adding the 1995ee4f033dSBarry Smith perturbation to the vector w3. 1996ee4f033dSBarry Smith */ 1997ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1998ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1999ee4f033dSBarry Smith dx = xx[col]; 2000ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2001ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2002ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2003ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2004ee4f033dSBarry Smith #else 2005ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2006ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2007ee4f033dSBarry Smith #endif 2008ee4f033dSBarry Smith dx *= epsilon; 2009ee4f033dSBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter"); 2010ee4f033dSBarry Smith w3_array[col] += dx; 2011ee4f033dSBarry Smith } 2012ed480e8bSBarry Smith w3_array = w3_array + start; ierr = VecRestoreArrayFast(w3,&w3_array);CHKERRQ(ierr); 2013ee4f033dSBarry Smith 2014ee4f033dSBarry Smith /* 2015ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2016ee4f033dSBarry Smith */ 2017ee4f033dSBarry Smith 201866f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2019ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 202066f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2021ee4f033dSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 2022ee4f033dSBarry Smith 2023ee4f033dSBarry Smith /* 2024ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2025ee4f033dSBarry Smith */ 2026ed480e8bSBarry Smith ierr = VecGetArrayFast(w2,&y);CHKERRQ(ierr); 2027ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2028ee4f033dSBarry Smith row = coloring->rows[k][l]; 2029ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2030ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2031ee4f033dSBarry Smith srow = row + start; 2032ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2033ee4f033dSBarry Smith } 2034ed480e8bSBarry Smith ierr = VecRestoreArrayFast(w2,&y);CHKERRQ(ierr); 2035ee4f033dSBarry Smith } 203649b058dcSBarry Smith coloring->currentcolor = k; 2037ed480e8bSBarry Smith ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2038ed480e8bSBarry Smith xx = xx + start; ierr = VecRestoreArrayFast(x1,&xx);CHKERRQ(ierr); 2039ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2040ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2041ee4f033dSBarry Smith PetscFunctionReturn(0); 2042ee4f033dSBarry Smith } 2043ee4f033dSBarry Smith 2044ac90fabeSBarry Smith #include "petscblaslapack.h" 2045ac90fabeSBarry Smith #undef __FUNCT__ 2046ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2047268466fbSBarry Smith int MatAXPY_SeqAIJ(const PetscScalar *a,Mat X,Mat Y,MatStructure str) 2048ac90fabeSBarry Smith { 2049c537a176SHong Zhang int ierr,one=1,i; 2050ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 2051ac90fabeSBarry Smith 2052ac90fabeSBarry Smith PetscFunctionBegin; 2053ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2054268466fbSBarry Smith BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one); 2055c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2056a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2057a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2058a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2059a30b2313SHong Zhang } 2060a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 206124f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2062a30b2313SHong Zhang y->XtoY = X; 2063c537a176SHong Zhang } 2064a30b2313SHong Zhang for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]); 2065e2dd4fc4Svictorle PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz); 2066ac90fabeSBarry Smith } else { 2067ac90fabeSBarry Smith ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr); 2068ac90fabeSBarry Smith } 2069ac90fabeSBarry Smith PetscFunctionReturn(0); 2070ac90fabeSBarry Smith } 2071ac90fabeSBarry Smith 2072682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 20730a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2074cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2075cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2076cb5b572fSBarry Smith MatMult_SeqAIJ, 2077cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 20787c922b88SBarry Smith MatMultTranspose_SeqAIJ, 20797c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2080cb5b572fSBarry Smith MatSolve_SeqAIJ, 2081cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 20827c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 20837c922b88SBarry Smith MatSolveTransposeAdd_SeqAIJ, 2084cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2085cb5b572fSBarry Smith 0, 208617ab2063SBarry Smith MatRelax_SeqAIJ, 208717ab2063SBarry Smith MatTranspose_SeqAIJ, 2088cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 2089cb5b572fSBarry Smith MatEqual_SeqAIJ, 2090cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2091cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2092cb5b572fSBarry Smith MatNorm_SeqAIJ, 2093cb5b572fSBarry Smith 0, 2094cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 209517ab2063SBarry Smith MatCompress_SeqAIJ, 2096cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2097cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2098cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 2099cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2100cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2101f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2102a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 2103273d9f13SBarry Smith MatSetUpPreallocation_SeqAIJ, 2104cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2105861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 21066c0721eeSBarry Smith MatGetArray_SeqAIJ, 21076c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2108be6bf707SBarry Smith MatDuplicate_SeqAIJ, 2109cb5b572fSBarry Smith 0, 2110cb5b572fSBarry Smith 0, 2111cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2112cb5b572fSBarry Smith 0, 2113ac90fabeSBarry Smith MatAXPY_SeqAIJ, 2114cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2115cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2116cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2117cb5b572fSBarry Smith MatCopy_SeqAIJ, 2118f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 2119cb5b572fSBarry Smith MatScale_SeqAIJ, 2120cb5b572fSBarry Smith 0, 2121cb5b572fSBarry Smith 0, 21226945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 21236945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 21243b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 21253b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 21263b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2127a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 2128a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 2129b9617806SBarry Smith 0, 21300513a670SBarry Smith 0, 2131cda55fadSBarry Smith MatPermute_SeqAIJ, 2132cda55fadSBarry Smith 0, 2133cda55fadSBarry Smith 0, 2134b9b97703SBarry Smith MatDestroy_SeqAIJ, 2135b9b97703SBarry Smith MatView_SeqAIJ, 21368a124369SBarry Smith MatGetPetscMaps_Petsc, 2137ee4f033dSBarry Smith 0, 2138ee4f033dSBarry Smith 0, 2139ee4f033dSBarry Smith 0, 2140ee4f033dSBarry Smith 0, 2141ee4f033dSBarry Smith 0, 2142ee4f033dSBarry Smith 0, 2143ee4f033dSBarry Smith 0, 2144ee4f033dSBarry Smith 0, 2145ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2146ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2147ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 2148ee4f033dSBarry Smith MatFDColoringApply_SeqAIJ}; 214917ab2063SBarry Smith 2150fb2e594dSBarry Smith EXTERN_C_BEGIN 21514a2ae208SSatish Balay #undef __FUNCT__ 21524a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 215315091d37SBarry Smith 2154bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 2155bef8e0ddSBarry Smith { 2156bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2157bef8e0ddSBarry Smith int i,nz,n; 2158bef8e0ddSBarry Smith 2159bef8e0ddSBarry Smith PetscFunctionBegin; 2160bef8e0ddSBarry Smith 2161bef8e0ddSBarry Smith nz = aij->maxnz; 2162273d9f13SBarry Smith n = mat->n; 2163bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2164bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2165bef8e0ddSBarry Smith } 2166bef8e0ddSBarry Smith aij->nz = nz; 2167bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2168bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2169bef8e0ddSBarry Smith } 2170bef8e0ddSBarry Smith 2171bef8e0ddSBarry Smith PetscFunctionReturn(0); 2172bef8e0ddSBarry Smith } 2173fb2e594dSBarry Smith EXTERN_C_END 2174bef8e0ddSBarry Smith 21754a2ae208SSatish Balay #undef __FUNCT__ 21764a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2177bef8e0ddSBarry Smith /*@ 2178bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2179bef8e0ddSBarry Smith in the matrix. 2180bef8e0ddSBarry Smith 2181bef8e0ddSBarry Smith Input Parameters: 2182bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2183bef8e0ddSBarry Smith - indices - the column indices 2184bef8e0ddSBarry Smith 218515091d37SBarry Smith Level: advanced 218615091d37SBarry Smith 2187bef8e0ddSBarry Smith Notes: 2188bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2189bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2190bef8e0ddSBarry Smith of the MatSetValues() operation. 2191bef8e0ddSBarry Smith 2192bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2193bef8e0ddSBarry Smith MatCreateSeqAIJ(). 2194bef8e0ddSBarry Smith 2195bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2196bef8e0ddSBarry Smith 2197b9617806SBarry Smith The indices should start with zero, not one. 2198b9617806SBarry Smith 2199bef8e0ddSBarry Smith @*/ 2200bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 2201bef8e0ddSBarry Smith { 2202bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 2203bef8e0ddSBarry Smith 2204bef8e0ddSBarry Smith PetscFunctionBegin; 2205bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2206c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2207bef8e0ddSBarry Smith if (f) { 2208bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2209bef8e0ddSBarry Smith } else { 221029bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 2211bef8e0ddSBarry Smith } 2212bef8e0ddSBarry Smith PetscFunctionReturn(0); 2213bef8e0ddSBarry Smith } 2214bef8e0ddSBarry Smith 2215be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2216be6bf707SBarry Smith 2217fb2e594dSBarry Smith EXTERN_C_BEGIN 22184a2ae208SSatish Balay #undef __FUNCT__ 22194a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2220be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2221be6bf707SBarry Smith { 2222be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2223bfeeae90SHong Zhang size_t nz = aij->i[mat->m],ierr; 2224be6bf707SBarry Smith 2225be6bf707SBarry Smith PetscFunctionBegin; 2226be6bf707SBarry Smith if (aij->nonew != 1) { 222729bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2228be6bf707SBarry Smith } 2229be6bf707SBarry Smith 2230be6bf707SBarry Smith /* allocate space for values if not already there */ 2231be6bf707SBarry Smith if (!aij->saved_values) { 223287828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2233be6bf707SBarry Smith } 2234be6bf707SBarry Smith 2235be6bf707SBarry Smith /* copy values over */ 223687828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2237be6bf707SBarry Smith PetscFunctionReturn(0); 2238be6bf707SBarry Smith } 2239fb2e594dSBarry Smith EXTERN_C_END 2240be6bf707SBarry Smith 22414a2ae208SSatish Balay #undef __FUNCT__ 2242b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2243be6bf707SBarry Smith /*@ 2244be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2245be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2246be6bf707SBarry Smith nonlinear portion. 2247be6bf707SBarry Smith 2248be6bf707SBarry Smith Collect on Mat 2249be6bf707SBarry Smith 2250be6bf707SBarry Smith Input Parameters: 2251be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2252be6bf707SBarry Smith 225315091d37SBarry Smith Level: advanced 225415091d37SBarry Smith 2255be6bf707SBarry Smith Common Usage, with SNESSolve(): 2256be6bf707SBarry Smith $ Create Jacobian matrix 2257be6bf707SBarry Smith $ Set linear terms into matrix 2258be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2259be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2260be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2261be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2262be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2263be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2264be6bf707SBarry Smith $ In your Jacobian routine 2265be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2266be6bf707SBarry Smith $ Set nonlinear terms in matrix 2267be6bf707SBarry Smith 2268be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2269be6bf707SBarry Smith $ // build linear portion of Jacobian 2270be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2271be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2272be6bf707SBarry Smith $ loop over nonlinear iterations 2273be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2274be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2275be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2276be6bf707SBarry Smith $ Solve linear system with Jacobian 2277be6bf707SBarry Smith $ endloop 2278be6bf707SBarry Smith 2279be6bf707SBarry Smith Notes: 2280be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2281be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2282be6bf707SBarry Smith calling this routine. 2283be6bf707SBarry Smith 2284be6bf707SBarry Smith .seealso: MatRetrieveValues() 2285be6bf707SBarry Smith 2286be6bf707SBarry Smith @*/ 2287be6bf707SBarry Smith int MatStoreValues(Mat mat) 2288be6bf707SBarry Smith { 2289be6bf707SBarry Smith int ierr,(*f)(Mat); 2290be6bf707SBarry Smith 2291be6bf707SBarry Smith PetscFunctionBegin; 2292be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 229329bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 229429bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2295be6bf707SBarry Smith 2296c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2297be6bf707SBarry Smith if (f) { 2298be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2299be6bf707SBarry Smith } else { 230029bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to store values"); 2301be6bf707SBarry Smith } 2302be6bf707SBarry Smith PetscFunctionReturn(0); 2303be6bf707SBarry Smith } 2304be6bf707SBarry Smith 2305fb2e594dSBarry Smith EXTERN_C_BEGIN 23064a2ae208SSatish Balay #undef __FUNCT__ 23074a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2308be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2309be6bf707SBarry Smith { 2310be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2311bfeeae90SHong Zhang int nz = aij->i[mat->m],ierr; 2312be6bf707SBarry Smith 2313be6bf707SBarry Smith PetscFunctionBegin; 2314be6bf707SBarry Smith if (aij->nonew != 1) { 231529bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2316be6bf707SBarry Smith } 2317be6bf707SBarry Smith if (!aij->saved_values) { 231829bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 2319be6bf707SBarry Smith } 2320be6bf707SBarry Smith 2321be6bf707SBarry Smith /* copy values over */ 232287828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2323be6bf707SBarry Smith PetscFunctionReturn(0); 2324be6bf707SBarry Smith } 2325fb2e594dSBarry Smith EXTERN_C_END 2326be6bf707SBarry Smith 23274a2ae208SSatish Balay #undef __FUNCT__ 23284a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2329be6bf707SBarry Smith /*@ 2330be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2331be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2332be6bf707SBarry Smith nonlinear portion. 2333be6bf707SBarry Smith 2334be6bf707SBarry Smith Collect on Mat 2335be6bf707SBarry Smith 2336be6bf707SBarry Smith Input Parameters: 2337be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2338be6bf707SBarry Smith 233915091d37SBarry Smith Level: advanced 234015091d37SBarry Smith 2341be6bf707SBarry Smith .seealso: MatStoreValues() 2342be6bf707SBarry Smith 2343be6bf707SBarry Smith @*/ 2344be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2345be6bf707SBarry Smith { 2346be6bf707SBarry Smith int ierr,(*f)(Mat); 2347be6bf707SBarry Smith 2348be6bf707SBarry Smith PetscFunctionBegin; 2349be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 235029bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 235129bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2352be6bf707SBarry Smith 2353c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2354be6bf707SBarry Smith if (f) { 2355be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2356be6bf707SBarry Smith } else { 235729bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to retrieve values"); 2358be6bf707SBarry Smith } 2359be6bf707SBarry Smith PetscFunctionReturn(0); 2360be6bf707SBarry Smith } 2361be6bf707SBarry Smith 2362f83d6046SBarry Smith /* 2363f83d6046SBarry Smith This allows SeqAIJ matrices to be passed to the matlab engine 2364f83d6046SBarry Smith */ 236587828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2366f83d6046SBarry Smith #include "engine.h" /* Matlab include file */ 2367f83d6046SBarry Smith #include "mex.h" /* Matlab include file */ 2368f83d6046SBarry Smith EXTERN_C_BEGIN 23694a2ae208SSatish Balay #undef __FUNCT__ 23704a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ" 237162aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 2372f83d6046SBarry Smith { 23734a4478b9SSatish Balay int ierr,i,*ai,*aj; 2374f83d6046SBarry Smith Mat B = (Mat)obj; 2375f83d6046SBarry Smith mxArray *mat; 2376d79a51d8SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 2377d79a51d8SBarry Smith 2378f83d6046SBarry Smith PetscFunctionBegin; 237901820c62SBarry Smith mat = mxCreateSparse(B->n,B->m,aij->nz,mxREAL); 238087828ca2SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 2381d79a51d8SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 238266826eb6SBarry Smith ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 238366826eb6SBarry Smith ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr); 2384f83d6046SBarry Smith 238501820c62SBarry Smith /* Matlab indices start at 0 for sparse (what a surprise) */ 2386bfeeae90SHong Zhang 2387ca44d042SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 2388f83d6046SBarry Smith mxSetName(mat,obj->name); 238962aa7f4eSBarry Smith engPutArray((Engine *)mengine,mat); 2390f83d6046SBarry Smith PetscFunctionReturn(0); 2391f83d6046SBarry Smith } 2392f83d6046SBarry Smith EXTERN_C_END 239366826eb6SBarry Smith 239466826eb6SBarry Smith EXTERN_C_BEGIN 23954a2ae208SSatish Balay #undef __FUNCT__ 23964a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ" 239762aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 239866826eb6SBarry Smith { 239966826eb6SBarry Smith int ierr,ii; 240066826eb6SBarry Smith Mat mat = (Mat)obj; 240166826eb6SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 240266826eb6SBarry Smith mxArray *mmat; 240366826eb6SBarry Smith 24046c0721eeSBarry Smith PetscFunctionBegin; 240566826eb6SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 240666826eb6SBarry Smith 240762aa7f4eSBarry Smith mmat = engGetArray((Engine *)mengine,obj->name); 240866826eb6SBarry Smith 2409a65776f3SBarry Smith aij->nz = (mxGetJc(mmat))[mat->m]; 2410a7ed9263SMatthew Knepley ierr = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr); 241166826eb6SBarry Smith aij->j = (int*)(aij->a + aij->nz); 241266826eb6SBarry Smith aij->i = aij->j + aij->nz; 241366826eb6SBarry Smith aij->singlemalloc = PETSC_TRUE; 241466826eb6SBarry Smith aij->freedata = PETSC_TRUE; 241566826eb6SBarry Smith 241687828ca2SBarry Smith ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 241766826eb6SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 241866826eb6SBarry Smith ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 241966826eb6SBarry Smith ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr); 242066826eb6SBarry Smith 242166826eb6SBarry Smith for (ii=0; ii<mat->m; ii++) { 242266826eb6SBarry Smith aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 242366826eb6SBarry Smith } 242466826eb6SBarry Smith 242566826eb6SBarry Smith ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 242666826eb6SBarry Smith ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 242766826eb6SBarry Smith 242866826eb6SBarry Smith PetscFunctionReturn(0); 242966826eb6SBarry Smith } 243066826eb6SBarry Smith EXTERN_C_END 2431f83d6046SBarry Smith #endif 2432f83d6046SBarry Smith 2433be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 24344a2ae208SSatish Balay #undef __FUNCT__ 24354a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 243617ab2063SBarry Smith /*@C 2437682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 24380d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 24396e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 244051c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 24412bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 244217ab2063SBarry Smith 2443db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2444db81eaa0SLois Curfman McInnes 244517ab2063SBarry Smith Input Parameters: 2446db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 244717ab2063SBarry Smith . m - number of rows 244817ab2063SBarry Smith . n - number of columns 244917ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 245051c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 24512bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 245217ab2063SBarry Smith 245317ab2063SBarry Smith Output Parameter: 2454416022c9SBarry Smith . A - the matrix 245517ab2063SBarry Smith 2456b259b22eSLois Curfman McInnes Notes: 245717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 245817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 24590002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 246044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 246117ab2063SBarry Smith 246217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2463a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 24643d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 24656da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 246617ab2063SBarry Smith 2467682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 24684fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2469682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 24706c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 24716c7ebb05SLois Curfman McInnes 24726c7ebb05SLois Curfman McInnes Options Database Keys: 2473db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2474db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2475db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2476db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2477db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 247817ab2063SBarry Smith 2479027ccd11SLois Curfman McInnes Level: intermediate 2480027ccd11SLois Curfman McInnes 248136db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 248236db0b34SBarry Smith 248317ab2063SBarry Smith @*/ 2484ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A) 248517ab2063SBarry Smith { 2486273d9f13SBarry Smith int ierr; 24876945ee14SBarry Smith 24883a40ed3dSBarry Smith PetscFunctionBegin; 2489273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 2490273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2491273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr); 2492273d9f13SBarry Smith PetscFunctionReturn(0); 2493273d9f13SBarry Smith } 2494273d9f13SBarry Smith 24955da197adSKris Buschelman #define SKIP_ALLOCATION -4 24965da197adSKris Buschelman 24974a2ae208SSatish Balay #undef __FUNCT__ 24984a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2499273d9f13SBarry Smith /*@C 2500273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2501273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2502273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2503273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2504273d9f13SBarry Smith 2505273d9f13SBarry Smith Collective on MPI_Comm 2506273d9f13SBarry Smith 2507273d9f13SBarry Smith Input Parameters: 2508273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2509273d9f13SBarry Smith . m - number of rows 2510273d9f13SBarry Smith . n - number of columns 2511273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2512273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2513273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2514273d9f13SBarry Smith 2515273d9f13SBarry Smith Output Parameter: 2516273d9f13SBarry Smith . A - the matrix 2517273d9f13SBarry Smith 2518273d9f13SBarry Smith Notes: 2519273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2520273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2521273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2522273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2523273d9f13SBarry Smith 2524273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2525273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2526273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2527273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2528273d9f13SBarry Smith 2529273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2530273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2531273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2532273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2533273d9f13SBarry Smith 2534273d9f13SBarry Smith Options Database Keys: 2535273d9f13SBarry Smith + -mat_aij_no_inode - Do not use inodes 2536273d9f13SBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2537273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2538273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2539273d9f13SBarry Smith the user still MUST index entries starting at 0! 2540273d9f13SBarry Smith 2541273d9f13SBarry Smith Level: intermediate 2542273d9f13SBarry Smith 2543273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2544273d9f13SBarry Smith 2545273d9f13SBarry Smith @*/ 2546ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[]) 2547273d9f13SBarry Smith { 2548ca01db9bSBarry Smith int ierr,(*f)(Mat,int,const int[]); 2549a23d5eceSKris Buschelman 2550a23d5eceSKris Buschelman PetscFunctionBegin; 2551a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2552a23d5eceSKris Buschelman if (f) { 2553a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2554a23d5eceSKris Buschelman } 2555a23d5eceSKris Buschelman PetscFunctionReturn(0); 2556a23d5eceSKris Buschelman } 2557a23d5eceSKris Buschelman 2558a23d5eceSKris Buschelman EXTERN_C_BEGIN 2559a23d5eceSKris Buschelman #undef __FUNCT__ 2560a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 2561a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz) 2562a23d5eceSKris Buschelman { 2563273d9f13SBarry Smith Mat_SeqAIJ *b; 2564a7ed9263SMatthew Knepley size_t len = 0; 2565a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 2566a7ed9263SMatthew Knepley int i,ierr; 2567273d9f13SBarry Smith 2568273d9f13SBarry Smith PetscFunctionBegin; 2569d5d45c9bSBarry Smith 2570c461c341SBarry Smith if (nz == SKIP_ALLOCATION) { 2571c461c341SBarry Smith skipallocation = PETSC_TRUE; 2572c461c341SBarry Smith nz = 0; 2573c461c341SBarry Smith } 2574c461c341SBarry Smith 2575435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2576435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2577b73539f3SBarry Smith if (nnz) { 2578273d9f13SBarry Smith for (i=0; i<B->m; i++) { 257929bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 25803a7fca6bSBarry Smith if (nnz[i] > B->n) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->n); 2581b73539f3SBarry Smith } 2582b73539f3SBarry Smith } 2583b73539f3SBarry Smith 2584273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2585273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2586273d9f13SBarry Smith 2587b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 2588273d9f13SBarry Smith if (!nnz) { 2589435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2590273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2591273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2592273d9f13SBarry Smith nz = nz*B->m; 2593273d9f13SBarry Smith } else { 2594273d9f13SBarry Smith nz = 0; 2595273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2596273d9f13SBarry Smith } 2597273d9f13SBarry Smith 2598c461c341SBarry Smith if (!skipallocation) { 2599273d9f13SBarry Smith /* allocate the matrix space */ 2600a7ed9263SMatthew Knepley len = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int); 2601b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 2602273d9f13SBarry Smith b->j = (int*)(b->a + nz); 2603273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2604273d9f13SBarry Smith b->i = b->j + nz; 2605bfeeae90SHong Zhang b->i[0] = 0; 26065da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 26075da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 26085da197adSKris Buschelman } 2609273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2610273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2611c461c341SBarry Smith } else { 2612c461c341SBarry Smith b->freedata = PETSC_FALSE; 2613c461c341SBarry Smith } 2614273d9f13SBarry Smith 2615273d9f13SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2616b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2617b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2618273d9f13SBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2619273d9f13SBarry Smith 2620273d9f13SBarry Smith b->nz = 0; 2621273d9f13SBarry Smith b->maxnz = nz; 2622273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2623273d9f13SBarry Smith PetscFunctionReturn(0); 2624273d9f13SBarry Smith } 2625a23d5eceSKris Buschelman EXTERN_C_END 2626273d9f13SBarry Smith 2627eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat); 2628eb9c0419SKris Buschelman 2629273d9f13SBarry Smith EXTERN_C_BEGIN 263005b94e36SKris Buschelman EXTERN int MatConvert_SeqAIJ_SeqSBAIJ(Mat,MatType,Mat*); 263105b94e36SKris Buschelman EXTERN int MatConvert_SeqAIJ_SeqBAIJ(Mat,MatType,Mat*); 263205b94e36SKris Buschelman EXTERN int MatReorderForNonzeroDiagonal_SeqAIJ(Mat,PetscReal,IS,IS); 26330a99d0a2SKris Buschelman EXTERN int MatAdjustForInodes_SeqAIJ(Mat,IS*,IS*); 2634d758967fSKris Buschelman EXTERN int MatSeqAIJGetInodeSizes_SeqAIJ(Mat,int*,int*[],int*); 2635a6175056SHong Zhang EXTERN_C_END 2636a6175056SHong Zhang 2637a6175056SHong Zhang EXTERN_C_BEGIN 26384a2ae208SSatish Balay #undef __FUNCT__ 26394a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2640273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B) 2641273d9f13SBarry Smith { 2642273d9f13SBarry Smith Mat_SeqAIJ *b; 2643273d9f13SBarry Smith int ierr,size; 2644273d9f13SBarry Smith PetscTruth flg; 2645273d9f13SBarry Smith 2646273d9f13SBarry Smith PetscFunctionBegin; 2647273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2648273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2649273d9f13SBarry Smith 2650273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2651273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2652273d9f13SBarry Smith 2653b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2654b0a32e0cSBarry Smith B->data = (void*)b; 2655549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2656549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2657416022c9SBarry Smith B->factor = 0; 2658416022c9SBarry Smith B->lupivotthreshold = 1.0; 265990f02eecSBarry Smith B->mapping = 0; 2660e82a3eeeSBarry Smith ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2661e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2662416022c9SBarry Smith b->row = 0; 2663416022c9SBarry Smith b->col = 0; 266482bf6240SBarry Smith b->icol = 0; 2665b810aeb4SBarry Smith b->reallocs = 0; 266617ab2063SBarry Smith 26678a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 26688a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2669a5ae1ecdSBarry Smith 2670f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 267136db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2672f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2673416022c9SBarry Smith b->nonew = 0; 2674416022c9SBarry Smith b->diag = 0; 2675416022c9SBarry Smith b->solve_work = 0; 26762a1b7f2aSHong Zhang B->spptr = 0; 2677b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2678754ec7b1SSatish Balay b->inode.node_count = 0; 2679754ec7b1SSatish Balay b->inode.size = 0; 26806c7ebb05SLois Curfman McInnes b->inode.limit = 5; 26816c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2682be6bf707SBarry Smith b->saved_values = 0; 2683d7f994e1SBarry Smith b->idiag = 0; 2684d7f994e1SBarry Smith b->ssor = 0; 2685f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2686a30b2313SHong Zhang b->xtoy = 0; 2687a30b2313SHong Zhang b->XtoY = 0; 268817ab2063SBarry Smith 268935d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 269035d8aa7fSBarry Smith 2691e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr); 2692ca44d042SBarry Smith if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);} 2693f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2694bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2695bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2696f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2697be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2698bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2699f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2700be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2701bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2702a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2703a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2704a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 270585fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 270685fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 270785fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 2708cd0d46ebSvictorle ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsSymmetric_C", 2709cd0d46ebSvictorle "MatIsSymmetric_SeqAIJ", 2710cd0d46ebSvictorle MatIsSymmetric_SeqAIJ);CHKERRQ(ierr); 2711a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 2712a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 2713a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 271405b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 271505b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 271605b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 27170a99d0a2SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C", 27180a99d0a2SKris Buschelman "MatAdjustForInodes_SeqAIJ", 27190a99d0a2SKris Buschelman MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr); 2720d758967fSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C", 2721d758967fSKris Buschelman "MatSeqAIJGetInodeSizes_SeqAIJ", 2722d758967fSKris Buschelman MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr); 272387828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2724f83d6046SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 272566826eb6SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 2726f83d6046SBarry Smith #endif 2727eb9c0419SKris Buschelman ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr); 27283a40ed3dSBarry Smith PetscFunctionReturn(0); 272917ab2063SBarry Smith } 2730273d9f13SBarry Smith EXTERN_C_END 273117ab2063SBarry Smith 27324a2ae208SSatish Balay #undef __FUNCT__ 27334a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2734be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 273517ab2063SBarry Smith { 2736416022c9SBarry Smith Mat C; 2737416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2738bfeeae90SHong Zhang int i,m = A->m,ierr; 2739a7ed9263SMatthew Knepley size_t len; 274017ab2063SBarry Smith 27413a40ed3dSBarry Smith PetscFunctionBegin; 27424043dd9cSLois Curfman McInnes *B = 0; 2743273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 2744273d9f13SBarry Smith ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr); 2745273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2746273d9f13SBarry Smith 2747416022c9SBarry Smith C->factor = A->factor; 2748416022c9SBarry Smith c->row = 0; 2749416022c9SBarry Smith c->col = 0; 275082bf6240SBarry Smith c->icol = 0; 2751f1e2ffcdSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2752c456f294SBarry Smith C->assembled = PETSC_TRUE; 275317ab2063SBarry Smith 2754273d9f13SBarry Smith C->M = A->m; 2755273d9f13SBarry Smith C->N = A->n; 275617ab2063SBarry Smith 2757b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 2758b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 275917ab2063SBarry Smith for (i=0; i<m; i++) { 2760416022c9SBarry Smith c->imax[i] = a->imax[i]; 2761416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 276217ab2063SBarry Smith } 276317ab2063SBarry Smith 276417ab2063SBarry Smith /* allocate the matrix space */ 2765f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 2766a7ed9263SMatthew Knepley len = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int)); 2767b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 2768bfeeae90SHong Zhang c->j = (int*)(c->a + a->i[m] ); 2769bfeeae90SHong Zhang c->i = c->j + a->i[m]; 2770549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 277117ab2063SBarry Smith if (m > 0) { 2772bfeeae90SHong Zhang ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr); 2773be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2774bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 2775be6bf707SBarry Smith } else { 2776bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 277717ab2063SBarry Smith } 277808480c60SBarry Smith } 277917ab2063SBarry Smith 2780b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2781416022c9SBarry Smith c->sorted = a->sorted; 2782416022c9SBarry Smith c->roworiented = a->roworiented; 2783416022c9SBarry Smith c->nonew = a->nonew; 27847a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2785be6bf707SBarry Smith c->saved_values = 0; 2786d7f994e1SBarry Smith c->idiag = 0; 2787d7f994e1SBarry Smith c->ssor = 0; 278836db0b34SBarry Smith c->ignorezeroentries = a->ignorezeroentries; 278936db0b34SBarry Smith c->freedata = PETSC_TRUE; 279017ab2063SBarry Smith 2791416022c9SBarry Smith if (a->diag) { 2792b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 2793b0a32e0cSBarry Smith PetscLogObjectMemory(C,(m+1)*sizeof(int)); 279417ab2063SBarry Smith for (i=0; i<m; i++) { 2795416022c9SBarry Smith c->diag[i] = a->diag[i]; 279617ab2063SBarry Smith } 27973a40ed3dSBarry Smith } else c->diag = 0; 2798b65db4caSBarry Smith c->inode.use = a->inode.use; 27996c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 28006c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2801754ec7b1SSatish Balay if (a->inode.size){ 2802b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr); 2803754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2804549d3d68SSatish Balay ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2805754ec7b1SSatish Balay } else { 2806754ec7b1SSatish Balay c->inode.size = 0; 2807754ec7b1SSatish Balay c->inode.node_count = 0; 2808754ec7b1SSatish Balay } 2809416022c9SBarry Smith c->nz = a->nz; 2810416022c9SBarry Smith c->maxnz = a->maxnz; 2811416022c9SBarry Smith c->solve_work = 0; 28122a1b7f2aSHong Zhang C->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2813273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2814754ec7b1SSatish Balay 2815416022c9SBarry Smith *B = C; 2816b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 28173a40ed3dSBarry Smith PetscFunctionReturn(0); 281817ab2063SBarry Smith } 281917ab2063SBarry Smith 2820273d9f13SBarry Smith EXTERN_C_BEGIN 28214a2ae208SSatish Balay #undef __FUNCT__ 28224a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2823b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A) 282417ab2063SBarry Smith { 2825416022c9SBarry Smith Mat_SeqAIJ *a; 2826416022c9SBarry Smith Mat B; 2827efb16452SHong Zhang int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N; 2828bcd2baecSBarry Smith MPI_Comm comm; 28291677d0b8SKris Buschelman #if defined(PETSC_HAVE_MUMPS) 283027fa2452SHong Zhang PetscTruth flag; 283127fa2452SHong Zhang #endif 283217ab2063SBarry Smith 28333a40ed3dSBarry Smith PetscFunctionBegin; 2834e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2835d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 283629bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2837b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 28380752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2839552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 284017ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 284117ab2063SBarry Smith 2842d64ed03dSBarry Smith if (nz < 0) { 284329bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2844d64ed03dSBarry Smith } 2845d64ed03dSBarry Smith 284617ab2063SBarry Smith /* read in row lengths */ 2847b0a32e0cSBarry Smith ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr); 28480752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 284917ab2063SBarry Smith 285017ab2063SBarry Smith /* create our matrix */ 2851b3a1e11cSKris Buschelman ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr); 2852b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 2853b3a1e11cSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr); 2854416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 285517ab2063SBarry Smith 285617ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 28570752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 285817ab2063SBarry Smith 285917ab2063SBarry Smith /* read in nonzero values */ 28600752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 286117ab2063SBarry Smith 286217ab2063SBarry Smith /* set matrix "i" values */ 2863efb16452SHong Zhang a->i[0] = 0; 286417ab2063SBarry Smith for (i=1; i<= M; i++) { 2865416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2866416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 286717ab2063SBarry Smith } 2868606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 286917ab2063SBarry Smith 28706d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28716d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2872eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS) 2873eee76cafSHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr); 2874eee76cafSHong Zhang if (flag) { ierr = MatUseMUMPS_MPIAIJ(B);CHKERRQ(ierr); } 2875eee76cafSHong Zhang #endif 2876b3a1e11cSKris Buschelman *A = B; 28773a40ed3dSBarry Smith PetscFunctionReturn(0); 287817ab2063SBarry Smith } 2879273d9f13SBarry Smith EXTERN_C_END 288017ab2063SBarry Smith 28814a2ae208SSatish Balay #undef __FUNCT__ 2882b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 28838f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 28847264ac53SSatish Balay { 28857264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 28860f5bd95cSBarry Smith int ierr; 28877264ac53SSatish Balay 28883a40ed3dSBarry Smith PetscFunctionBegin; 2889bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 2890bfeeae90SHong Zhang if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) { 2891ca44d042SBarry Smith *flg = PETSC_FALSE; 2892ca44d042SBarry Smith PetscFunctionReturn(0); 2893bcd2baecSBarry Smith } 28947264ac53SSatish Balay 28957264ac53SSatish Balay /* if the a->i are the same */ 2896273d9f13SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr); 28970f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 28987264ac53SSatish Balay 28997264ac53SSatish Balay /* if a->j are the same */ 29000f5bd95cSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 29010f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2902bcd2baecSBarry Smith 2903bcd2baecSBarry Smith /* if a->a are the same */ 290487828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 29050f5bd95cSBarry Smith 29063a40ed3dSBarry Smith PetscFunctionReturn(0); 29077264ac53SSatish Balay 29087264ac53SSatish Balay } 290936db0b34SBarry Smith 29104a2ae208SSatish Balay #undef __FUNCT__ 29114a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 291236db0b34SBarry Smith /*@C 291336db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 291436db0b34SBarry Smith provided by the user. 291536db0b34SBarry Smith 291636db0b34SBarry Smith Coolective on MPI_Comm 291736db0b34SBarry Smith 291836db0b34SBarry Smith Input Parameters: 291936db0b34SBarry Smith + comm - must be an MPI communicator of size 1 292036db0b34SBarry Smith . m - number of rows 292136db0b34SBarry Smith . n - number of columns 292236db0b34SBarry Smith . i - row indices 292336db0b34SBarry Smith . j - column indices 292436db0b34SBarry Smith - a - matrix values 292536db0b34SBarry Smith 292636db0b34SBarry Smith Output Parameter: 292736db0b34SBarry Smith . mat - the matrix 292836db0b34SBarry Smith 292936db0b34SBarry Smith Level: intermediate 293036db0b34SBarry Smith 293136db0b34SBarry Smith Notes: 29320551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 293336db0b34SBarry Smith once the matrix is destroyed 293436db0b34SBarry Smith 293536db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 293636db0b34SBarry Smith 2937bfeeae90SHong Zhang The i and j indices are 0 based 293836db0b34SBarry Smith 293936db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 294036db0b34SBarry Smith 294136db0b34SBarry Smith @*/ 294287828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat) 294336db0b34SBarry Smith { 294436db0b34SBarry Smith int ierr,ii; 294536db0b34SBarry Smith Mat_SeqAIJ *aij; 294636db0b34SBarry Smith 294736db0b34SBarry Smith PetscFunctionBegin; 2948c461c341SBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr); 294936db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 295036db0b34SBarry Smith 2951bfeeae90SHong Zhang if (i[0] != 0) { 2952bfeeae90SHong Zhang SETERRQ(1,"i (row indices) must start with 0"); 295336db0b34SBarry Smith } 295436db0b34SBarry Smith aij->i = i; 295536db0b34SBarry Smith aij->j = j; 295636db0b34SBarry Smith aij->a = a; 295736db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 295836db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 295936db0b34SBarry Smith aij->freedata = PETSC_FALSE; 296036db0b34SBarry Smith 296136db0b34SBarry Smith for (ii=0; ii<m; ii++) { 296236db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 29639860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 296429bbc08cSBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(1,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 296536db0b34SBarry Smith #endif 296636db0b34SBarry Smith } 29679860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 296836db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 2969bfeeae90SHong Zhang if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]); 2970bfeeae90SHong Zhang if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]); 297136db0b34SBarry Smith } 297236db0b34SBarry Smith #endif 297336db0b34SBarry Smith 2974b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2975b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 297636db0b34SBarry Smith PetscFunctionReturn(0); 297736db0b34SBarry Smith } 297836db0b34SBarry Smith 2979cc8ba8e1SBarry Smith #undef __FUNCT__ 2980ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 2981ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 2982cc8ba8e1SBarry Smith { 2983cc8ba8e1SBarry Smith int ierr; 2984cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 298536db0b34SBarry Smith 2986cc8ba8e1SBarry Smith PetscFunctionBegin; 298712c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 2988cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 2989cc8ba8e1SBarry Smith a->coloring = coloring; 299012c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 299108b6dcc0SBarry Smith int i,*larray; 299212c595b3SBarry Smith ISColoring ocoloring; 299308b6dcc0SBarry Smith ISColoringValue *colors; 299412c595b3SBarry Smith 299512c595b3SBarry Smith /* set coloring for diagonal portion */ 299612c595b3SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr); 299712c595b3SBarry Smith for (i=0; i<A->n; i++) { 299812c595b3SBarry Smith larray[i] = i; 299912c595b3SBarry Smith } 300012c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 300108b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 300212c595b3SBarry Smith for (i=0; i<A->n; i++) { 300312c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 300412c595b3SBarry Smith } 300512c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 300612c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 300712c595b3SBarry Smith a->coloring = ocoloring; 300812c595b3SBarry Smith } 3009cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3010cc8ba8e1SBarry Smith } 3011cc8ba8e1SBarry Smith 301287828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 3013ee4f033dSBarry Smith EXTERN_C_BEGIN 301429c1e371SBarry Smith #include "adic/ad_utils.h" 3015ee4f033dSBarry Smith EXTERN_C_END 3016cc8ba8e1SBarry Smith 3017cc8ba8e1SBarry Smith #undef __FUNCT__ 3018ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3019ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3020cc8ba8e1SBarry Smith { 3021cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 302208b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 30234440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 302408b6dcc0SBarry Smith ISColoringValue *color; 3025cc8ba8e1SBarry Smith 3026cc8ba8e1SBarry Smith PetscFunctionBegin; 3027cc8ba8e1SBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 30284440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3029cc8ba8e1SBarry Smith color = a->coloring->colors; 3030cc8ba8e1SBarry Smith /* loop over rows */ 3031cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3032cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3033cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3034cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3035cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3036cc8ba8e1SBarry Smith } 30374440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3038ee4f033dSBarry Smith } 3039ee4f033dSBarry Smith PetscFunctionReturn(0); 3040ee4f033dSBarry Smith } 3041ee4f033dSBarry Smith 3042ee4f033dSBarry Smith #else 3043ee4f033dSBarry Smith 3044ee4f033dSBarry Smith #undef __FUNCT__ 3045ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3046ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3047ee4f033dSBarry Smith { 3048ee4f033dSBarry Smith PetscFunctionBegin; 3049ee4f033dSBarry Smith SETERRQ(1,"PETSc installed without ADIC"); 3050ee4f033dSBarry Smith } 3051ee4f033dSBarry Smith 3052ee4f033dSBarry Smith #endif 3053ee4f033dSBarry Smith 3054ee4f033dSBarry Smith #undef __FUNCT__ 3055ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 3056ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues) 3057ee4f033dSBarry Smith { 3058ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 305908b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 306087828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 306108b6dcc0SBarry Smith ISColoringValue *color; 3062ee4f033dSBarry Smith 3063ee4f033dSBarry Smith PetscFunctionBegin; 3064ee4f033dSBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 3065ee4f033dSBarry Smith color = a->coloring->colors; 3066ee4f033dSBarry Smith /* loop over rows */ 3067ee4f033dSBarry Smith for (i=0; i<m; i++) { 3068ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3069ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3070ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3071ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3072ee4f033dSBarry Smith } 3073ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3074cc8ba8e1SBarry Smith } 3075cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3076cc8ba8e1SBarry Smith } 307736db0b34SBarry Smith 3078