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; 603*1677d0b8SKris 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) 1133beeb8507SBarry Smith fortranrelaxaijforwardzero_(&m,&omega,x,a->i,a->j,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) 1156beeb8507SBarry Smith fortranrelaxaijbackwardzero_(&m,&omega,x,a->i,a->j,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) 1174beeb8507SBarry Smith fortranrelaxaijforward_(&m,&omega,x,a->i,a->j,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) 1190beeb8507SBarry Smith fortranrelaxaijbackward_(&m,&omega,x,a->i,a->j,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); 1835aa482453SBarry Smith #if defined(PETSC_HAVE_ESSL) 1836d132466eSBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_essl: Use IBM sparse LU factorization and solve.\n");CHKERRQ(ierr); 1837682d7d0cSBarry Smith #endif 1838cd5578b5SBarry Smith #if defined(PETSC_HAVE_LUSOL) 1839cd5578b5SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_lusol: Use the Stanford LUSOL sparse factorization and solve.\n");CHKERRQ(ierr); 1840cd5578b5SBarry Smith #endif 184187828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 1842ca44d042SBarry Smith ierr = (*PetscHelpPrintf)(comm," -mat_aij_matlab: Use Matlab engine sparse LU factorization and solve.\n");CHKERRQ(ierr); 1843ca44d042SBarry Smith #endif 18443a40ed3dSBarry Smith PetscFunctionReturn(0); 1845682d7d0cSBarry Smith } 1846ca44d042SBarry Smith EXTERN int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg); 1847ca44d042SBarry Smith EXTERN int MatFDColoringCreate_SeqAIJ(Mat,ISColoring,MatFDColoring); 1848b380c88cSHong Zhang EXTERN int MatILUDTFactor_SeqAIJ(Mat,MatFactorInfo*,IS,IS,Mat*); 18494a2ae208SSatish Balay #undef __FUNCT__ 18504a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 1851cb5b572fSBarry Smith int MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 1852cb5b572fSBarry Smith { 1853be6bf707SBarry Smith int ierr; 1854cb5b572fSBarry Smith 1855cb5b572fSBarry Smith PetscFunctionBegin; 185633f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 185733f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 1858be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1859be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 1860be6bf707SBarry Smith 1861bfeeae90SHong Zhang if (a->i[A->m] != b->i[B->m]) { 186229bbc08cSBarry Smith SETERRQ(1,"Number of nonzeros in two matrices are different"); 1863cb5b572fSBarry Smith } 1864bfeeae90SHong Zhang ierr = PetscMemcpy(b->a,a->a,(a->i[A->m])*sizeof(PetscScalar));CHKERRQ(ierr); 1865cb5b572fSBarry Smith } else { 1866cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 1867cb5b572fSBarry Smith } 1868cb5b572fSBarry Smith PetscFunctionReturn(0); 1869cb5b572fSBarry Smith } 1870cb5b572fSBarry Smith 18714a2ae208SSatish Balay #undef __FUNCT__ 18724a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 1873273d9f13SBarry Smith int MatSetUpPreallocation_SeqAIJ(Mat A) 1874273d9f13SBarry Smith { 1875273d9f13SBarry Smith int ierr; 1876273d9f13SBarry Smith 1877273d9f13SBarry Smith PetscFunctionBegin; 1878273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 1879273d9f13SBarry Smith PetscFunctionReturn(0); 1880273d9f13SBarry Smith } 1881273d9f13SBarry Smith 18824a2ae208SSatish Balay #undef __FUNCT__ 18834a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 18844e7234bfSBarry Smith int MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 18856c0721eeSBarry Smith { 18866c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18876c0721eeSBarry Smith PetscFunctionBegin; 18886c0721eeSBarry Smith *array = a->a; 18896c0721eeSBarry Smith PetscFunctionReturn(0); 18906c0721eeSBarry Smith } 18916c0721eeSBarry Smith 18924a2ae208SSatish Balay #undef __FUNCT__ 18934a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 18944e7234bfSBarry Smith int MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 18956c0721eeSBarry Smith { 18966c0721eeSBarry Smith PetscFunctionBegin; 18976c0721eeSBarry Smith PetscFunctionReturn(0); 18986c0721eeSBarry Smith } 1899273d9f13SBarry Smith 1900ee4f033dSBarry Smith #undef __FUNCT__ 1901ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 1902ee4f033dSBarry Smith int MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 1903ee4f033dSBarry Smith { 1904ee4f033dSBarry Smith int (*f)(void *,Vec,Vec,void*) = (int (*)(void *,Vec,Vec,void *))coloring->f; 1905ee4f033dSBarry Smith int k,ierr,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 190687828ca2SBarry Smith PetscScalar dx,mone = -1.0,*y,*xx,*w3_array; 190787828ca2SBarry Smith PetscScalar *vscale_array; 1908ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 1909ee4f033dSBarry Smith Vec w1,w2,w3; 1910ee4f033dSBarry Smith void *fctx = coloring->fctx; 1911ee4f033dSBarry Smith PetscTruth flg; 1912ee4f033dSBarry Smith 1913ee4f033dSBarry Smith PetscFunctionBegin; 1914ee4f033dSBarry Smith if (!coloring->w1) { 1915ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 1916ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w1); 1917ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 1918ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w2); 1919ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 1920ee4f033dSBarry Smith PetscLogObjectParent(coloring,coloring->w3); 1921ee4f033dSBarry Smith } 1922ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 1923ee4f033dSBarry Smith 1924ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 1925e82a3eeeSBarry Smith ierr = PetscOptionsHasName(coloring->prefix,"-mat_fd_coloring_dont_rezero",&flg);CHKERRQ(ierr); 1926ee4f033dSBarry Smith if (flg) { 1927ee4f033dSBarry Smith PetscLogInfo(coloring,"MatFDColoringApply_SeqAIJ: Not calling MatZeroEntries()\n"); 1928ee4f033dSBarry Smith } else { 1929ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 1930ee4f033dSBarry Smith } 1931ee4f033dSBarry Smith 1932ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 1933ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 1934ee4f033dSBarry Smith 1935ee4f033dSBarry Smith /* 1936ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 1937ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 1938ee4f033dSBarry Smith */ 1939ee4f033dSBarry Smith if (coloring->F) { 1940ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 1941ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 1942ee4f033dSBarry Smith if (m1 != m2) { 1943ee4f033dSBarry Smith coloring->F = 0; 1944ee4f033dSBarry Smith } 1945ee4f033dSBarry Smith } 1946ee4f033dSBarry Smith 1947ee4f033dSBarry Smith if (coloring->F) { 1948ee4f033dSBarry Smith w1 = coloring->F; 1949ee4f033dSBarry Smith coloring->F = 0; 1950ee4f033dSBarry Smith } else { 195166f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1952ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 195366f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 1954ee4f033dSBarry Smith } 1955ee4f033dSBarry Smith 1956ee4f033dSBarry Smith /* 1957ee4f033dSBarry Smith Compute all the scale factors and share with other processors 1958ee4f033dSBarry Smith */ 1959ed480e8bSBarry Smith ierr = VecGetArrayFast(x1,&xx);CHKERRQ(ierr);xx = xx - start; 1960ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 1961ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 1962ee4f033dSBarry Smith /* 1963ee4f033dSBarry Smith Loop over each column associated with color adding the 1964ee4f033dSBarry Smith perturbation to the vector w3. 1965ee4f033dSBarry Smith */ 1966ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 1967ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 1968ee4f033dSBarry Smith dx = xx[col]; 1969ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 1970ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 1971ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 1972ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 1973ee4f033dSBarry Smith #else 1974ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 1975ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 1976ee4f033dSBarry Smith #endif 1977ee4f033dSBarry Smith dx *= epsilon; 1978ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 1979ee4f033dSBarry Smith } 1980ee4f033dSBarry Smith } 1981ed480e8bSBarry Smith vscale_array = vscale_array + start;ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1982ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1983ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1984ee4f033dSBarry Smith 1985ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 1986ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 1987ee4f033dSBarry Smith 1988ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 1989ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 1990ee4f033dSBarry Smith 1991ed480e8bSBarry Smith ierr = VecGetArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 1992ee4f033dSBarry Smith /* 1993ee4f033dSBarry Smith Loop over each color 1994ee4f033dSBarry Smith */ 1995ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 199649b058dcSBarry Smith coloring->currentcolor = k; 1997ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 1998ed480e8bSBarry Smith ierr = VecGetArrayFast(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 1999ee4f033dSBarry Smith /* 2000ee4f033dSBarry Smith Loop over each column associated with color adding the 2001ee4f033dSBarry Smith perturbation to the vector w3. 2002ee4f033dSBarry Smith */ 2003ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2004ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2005ee4f033dSBarry Smith dx = xx[col]; 2006ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2007ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2008ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2009ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2010ee4f033dSBarry Smith #else 2011ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2012ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2013ee4f033dSBarry Smith #endif 2014ee4f033dSBarry Smith dx *= epsilon; 2015ee4f033dSBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(1,"Computed 0 differencing parameter"); 2016ee4f033dSBarry Smith w3_array[col] += dx; 2017ee4f033dSBarry Smith } 2018ed480e8bSBarry Smith w3_array = w3_array + start; ierr = VecRestoreArrayFast(w3,&w3_array);CHKERRQ(ierr); 2019ee4f033dSBarry Smith 2020ee4f033dSBarry Smith /* 2021ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2022ee4f033dSBarry Smith */ 2023ee4f033dSBarry Smith 202466f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2025ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 202666f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2027ee4f033dSBarry Smith ierr = VecAXPY(&mone,w1,w2);CHKERRQ(ierr); 2028ee4f033dSBarry Smith 2029ee4f033dSBarry Smith /* 2030ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2031ee4f033dSBarry Smith */ 2032ed480e8bSBarry Smith ierr = VecGetArrayFast(w2,&y);CHKERRQ(ierr); 2033ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2034ee4f033dSBarry Smith row = coloring->rows[k][l]; 2035ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2036ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2037ee4f033dSBarry Smith srow = row + start; 2038ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2039ee4f033dSBarry Smith } 2040ed480e8bSBarry Smith ierr = VecRestoreArrayFast(w2,&y);CHKERRQ(ierr); 2041ee4f033dSBarry Smith } 204249b058dcSBarry Smith coloring->currentcolor = k; 2043ed480e8bSBarry Smith ierr = VecRestoreArrayFast(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2044ed480e8bSBarry Smith xx = xx + start; ierr = VecRestoreArrayFast(x1,&xx);CHKERRQ(ierr); 2045ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2046ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2047ee4f033dSBarry Smith PetscFunctionReturn(0); 2048ee4f033dSBarry Smith } 2049ee4f033dSBarry Smith 2050ac90fabeSBarry Smith #include "petscblaslapack.h" 2051ac90fabeSBarry Smith #undef __FUNCT__ 2052ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2053268466fbSBarry Smith int MatAXPY_SeqAIJ(const PetscScalar *a,Mat X,Mat Y,MatStructure str) 2054ac90fabeSBarry Smith { 2055c537a176SHong Zhang int ierr,one=1,i; 2056ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 2057ac90fabeSBarry Smith 2058ac90fabeSBarry Smith PetscFunctionBegin; 2059ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2060268466fbSBarry Smith BLaxpy_(&x->nz,(PetscScalar*)a,x->a,&one,y->a,&one); 2061c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2062a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2063a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 2064a30b2313SHong Zhang ierr = MatDestroy(y->XtoY);CHKERRQ(ierr); 2065a30b2313SHong Zhang } 2066a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 206724f910e3SHong Zhang ierr = MatAXPYGetxtoy_Private(X->m,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2068a30b2313SHong Zhang y->XtoY = X; 2069c537a176SHong Zhang } 2070a30b2313SHong Zhang for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += (*a)*(x->a[i]); 2071e2dd4fc4Svictorle PetscLogInfo(0,"MatAXPY_SeqAIJ: ratio of nnz(X)/nnz(Y): %d/%d = %g\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz); 2072ac90fabeSBarry Smith } else { 2073ac90fabeSBarry Smith ierr = MatAXPY_Basic(a,X,Y,str);CHKERRQ(ierr); 2074ac90fabeSBarry Smith } 2075ac90fabeSBarry Smith PetscFunctionReturn(0); 2076ac90fabeSBarry Smith } 2077ac90fabeSBarry Smith 2078682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 20790a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2080cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2081cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2082cb5b572fSBarry Smith MatMult_SeqAIJ, 2083cb5b572fSBarry Smith MatMultAdd_SeqAIJ, 20847c922b88SBarry Smith MatMultTranspose_SeqAIJ, 20857c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2086cb5b572fSBarry Smith MatSolve_SeqAIJ, 2087cb5b572fSBarry Smith MatSolveAdd_SeqAIJ, 20887c922b88SBarry Smith MatSolveTranspose_SeqAIJ, 20897c922b88SBarry Smith MatSolveTransposeAdd_SeqAIJ, 2090cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2091cb5b572fSBarry Smith 0, 209217ab2063SBarry Smith MatRelax_SeqAIJ, 209317ab2063SBarry Smith MatTranspose_SeqAIJ, 2094cb5b572fSBarry Smith MatGetInfo_SeqAIJ, 2095cb5b572fSBarry Smith MatEqual_SeqAIJ, 2096cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2097cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2098cb5b572fSBarry Smith MatNorm_SeqAIJ, 2099cb5b572fSBarry Smith 0, 2100cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 210117ab2063SBarry Smith MatCompress_SeqAIJ, 2102cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2103cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2104cb5b572fSBarry Smith MatZeroRows_SeqAIJ, 2105cb5b572fSBarry Smith MatLUFactorSymbolic_SeqAIJ, 2106cb5b572fSBarry Smith MatLUFactorNumeric_SeqAIJ, 2107f76d2b81SHong Zhang MatCholeskyFactorSymbolic_SeqAIJ, 2108a6175056SHong Zhang MatCholeskyFactorNumeric_SeqAIJ, 2109273d9f13SBarry Smith MatSetUpPreallocation_SeqAIJ, 2110cb5b572fSBarry Smith MatILUFactorSymbolic_SeqAIJ, 2111861ba921SHong Zhang MatICCFactorSymbolic_SeqAIJ, 21126c0721eeSBarry Smith MatGetArray_SeqAIJ, 21136c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2114be6bf707SBarry Smith MatDuplicate_SeqAIJ, 2115cb5b572fSBarry Smith 0, 2116cb5b572fSBarry Smith 0, 2117cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2118cb5b572fSBarry Smith 0, 2119ac90fabeSBarry Smith MatAXPY_SeqAIJ, 2120cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2121cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2122cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2123cb5b572fSBarry Smith MatCopy_SeqAIJ, 2124f0b747eeSBarry Smith MatPrintHelp_SeqAIJ, 2125cb5b572fSBarry Smith MatScale_SeqAIJ, 2126cb5b572fSBarry Smith 0, 2127cb5b572fSBarry Smith 0, 21286945ee14SBarry Smith MatILUDTFactor_SeqAIJ, 21296945ee14SBarry Smith MatGetBlockSize_SeqAIJ, 21303b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 21313b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 21323b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2133a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 2134a93ec695SBarry Smith MatFDColoringCreate_SeqAIJ, 2135b9617806SBarry Smith 0, 21360513a670SBarry Smith 0, 2137cda55fadSBarry Smith MatPermute_SeqAIJ, 2138cda55fadSBarry Smith 0, 2139cda55fadSBarry Smith 0, 2140b9b97703SBarry Smith MatDestroy_SeqAIJ, 2141b9b97703SBarry Smith MatView_SeqAIJ, 21428a124369SBarry Smith MatGetPetscMaps_Petsc, 2143ee4f033dSBarry Smith 0, 2144ee4f033dSBarry Smith 0, 2145ee4f033dSBarry Smith 0, 2146ee4f033dSBarry Smith 0, 2147ee4f033dSBarry Smith 0, 2148ee4f033dSBarry Smith 0, 2149ee4f033dSBarry Smith 0, 2150ee4f033dSBarry Smith 0, 2151ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2152ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2153ee4f033dSBarry Smith MatSetValuesAdifor_SeqAIJ, 2154ee4f033dSBarry Smith MatFDColoringApply_SeqAIJ}; 215517ab2063SBarry Smith 2156fb2e594dSBarry Smith EXTERN_C_BEGIN 21574a2ae208SSatish Balay #undef __FUNCT__ 21584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 215915091d37SBarry Smith 2160bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,int *indices) 2161bef8e0ddSBarry Smith { 2162bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2163bef8e0ddSBarry Smith int i,nz,n; 2164bef8e0ddSBarry Smith 2165bef8e0ddSBarry Smith PetscFunctionBegin; 2166bef8e0ddSBarry Smith 2167bef8e0ddSBarry Smith nz = aij->maxnz; 2168273d9f13SBarry Smith n = mat->n; 2169bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 2170bef8e0ddSBarry Smith aij->j[i] = indices[i]; 2171bef8e0ddSBarry Smith } 2172bef8e0ddSBarry Smith aij->nz = nz; 2173bef8e0ddSBarry Smith for (i=0; i<n; i++) { 2174bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 2175bef8e0ddSBarry Smith } 2176bef8e0ddSBarry Smith 2177bef8e0ddSBarry Smith PetscFunctionReturn(0); 2178bef8e0ddSBarry Smith } 2179fb2e594dSBarry Smith EXTERN_C_END 2180bef8e0ddSBarry Smith 21814a2ae208SSatish Balay #undef __FUNCT__ 21824a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 2183bef8e0ddSBarry Smith /*@ 2184bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 2185bef8e0ddSBarry Smith in the matrix. 2186bef8e0ddSBarry Smith 2187bef8e0ddSBarry Smith Input Parameters: 2188bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 2189bef8e0ddSBarry Smith - indices - the column indices 2190bef8e0ddSBarry Smith 219115091d37SBarry Smith Level: advanced 219215091d37SBarry Smith 2193bef8e0ddSBarry Smith Notes: 2194bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 2195bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 2196bef8e0ddSBarry Smith of the MatSetValues() operation. 2197bef8e0ddSBarry Smith 2198bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 2199bef8e0ddSBarry Smith MatCreateSeqAIJ(). 2200bef8e0ddSBarry Smith 2201bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 2202bef8e0ddSBarry Smith 2203b9617806SBarry Smith The indices should start with zero, not one. 2204b9617806SBarry Smith 2205bef8e0ddSBarry Smith @*/ 2206bef8e0ddSBarry Smith int MatSeqAIJSetColumnIndices(Mat mat,int *indices) 2207bef8e0ddSBarry Smith { 2208bef8e0ddSBarry Smith int ierr,(*f)(Mat,int *); 2209bef8e0ddSBarry Smith 2210bef8e0ddSBarry Smith PetscFunctionBegin; 2211bef8e0ddSBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 2212c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatSeqAIJSetColumnIndices_C",(void (**)(void))&f);CHKERRQ(ierr); 2213bef8e0ddSBarry Smith if (f) { 2214bef8e0ddSBarry Smith ierr = (*f)(mat,indices);CHKERRQ(ierr); 2215bef8e0ddSBarry Smith } else { 221629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to set column indices"); 2217bef8e0ddSBarry Smith } 2218bef8e0ddSBarry Smith PetscFunctionReturn(0); 2219bef8e0ddSBarry Smith } 2220bef8e0ddSBarry Smith 2221be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 2222be6bf707SBarry Smith 2223fb2e594dSBarry Smith EXTERN_C_BEGIN 22244a2ae208SSatish Balay #undef __FUNCT__ 22254a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 2226be6bf707SBarry Smith int MatStoreValues_SeqAIJ(Mat mat) 2227be6bf707SBarry Smith { 2228be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2229bfeeae90SHong Zhang size_t nz = aij->i[mat->m],ierr; 2230be6bf707SBarry Smith 2231be6bf707SBarry Smith PetscFunctionBegin; 2232be6bf707SBarry Smith if (aij->nonew != 1) { 223329bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2234be6bf707SBarry Smith } 2235be6bf707SBarry Smith 2236be6bf707SBarry Smith /* allocate space for values if not already there */ 2237be6bf707SBarry Smith if (!aij->saved_values) { 223887828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 2239be6bf707SBarry Smith } 2240be6bf707SBarry Smith 2241be6bf707SBarry Smith /* copy values over */ 224287828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2243be6bf707SBarry Smith PetscFunctionReturn(0); 2244be6bf707SBarry Smith } 2245fb2e594dSBarry Smith EXTERN_C_END 2246be6bf707SBarry Smith 22474a2ae208SSatish Balay #undef __FUNCT__ 2248b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 2249be6bf707SBarry Smith /*@ 2250be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 2251be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2252be6bf707SBarry Smith nonlinear portion. 2253be6bf707SBarry Smith 2254be6bf707SBarry Smith Collect on Mat 2255be6bf707SBarry Smith 2256be6bf707SBarry Smith Input Parameters: 2257be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2258be6bf707SBarry Smith 225915091d37SBarry Smith Level: advanced 226015091d37SBarry Smith 2261be6bf707SBarry Smith Common Usage, with SNESSolve(): 2262be6bf707SBarry Smith $ Create Jacobian matrix 2263be6bf707SBarry Smith $ Set linear terms into matrix 2264be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 2265be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 2266be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 2267be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2268be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2269be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 2270be6bf707SBarry Smith $ In your Jacobian routine 2271be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2272be6bf707SBarry Smith $ Set nonlinear terms in matrix 2273be6bf707SBarry Smith 2274be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 2275be6bf707SBarry Smith $ // build linear portion of Jacobian 2276be6bf707SBarry Smith $ ierr = MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); 2277be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 2278be6bf707SBarry Smith $ loop over nonlinear iterations 2279be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 2280be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 2281be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 2282be6bf707SBarry Smith $ Solve linear system with Jacobian 2283be6bf707SBarry Smith $ endloop 2284be6bf707SBarry Smith 2285be6bf707SBarry Smith Notes: 2286be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 2287be6bf707SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NO_NEW_NONZERO_LOCATIONS); before 2288be6bf707SBarry Smith calling this routine. 2289be6bf707SBarry Smith 2290be6bf707SBarry Smith .seealso: MatRetrieveValues() 2291be6bf707SBarry Smith 2292be6bf707SBarry Smith @*/ 2293be6bf707SBarry Smith int MatStoreValues(Mat mat) 2294be6bf707SBarry Smith { 2295be6bf707SBarry Smith int ierr,(*f)(Mat); 2296be6bf707SBarry Smith 2297be6bf707SBarry Smith PetscFunctionBegin; 2298be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 229929bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 230029bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2301be6bf707SBarry Smith 2302c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatStoreValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2303be6bf707SBarry Smith if (f) { 2304be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2305be6bf707SBarry Smith } else { 230629bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to store values"); 2307be6bf707SBarry Smith } 2308be6bf707SBarry Smith PetscFunctionReturn(0); 2309be6bf707SBarry Smith } 2310be6bf707SBarry Smith 2311fb2e594dSBarry Smith EXTERN_C_BEGIN 23124a2ae208SSatish Balay #undef __FUNCT__ 23134a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 2314be6bf707SBarry Smith int MatRetrieveValues_SeqAIJ(Mat mat) 2315be6bf707SBarry Smith { 2316be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2317bfeeae90SHong Zhang int nz = aij->i[mat->m],ierr; 2318be6bf707SBarry Smith 2319be6bf707SBarry Smith PetscFunctionBegin; 2320be6bf707SBarry Smith if (aij->nonew != 1) { 232129bbc08cSBarry Smith SETERRQ(1,"Must call MatSetOption(A,MAT_NO_NEW_NONZERO_LOCATIONS);first"); 2322be6bf707SBarry Smith } 2323be6bf707SBarry Smith if (!aij->saved_values) { 232429bbc08cSBarry Smith SETERRQ(1,"Must call MatStoreValues(A);first"); 2325be6bf707SBarry Smith } 2326be6bf707SBarry Smith 2327be6bf707SBarry Smith /* copy values over */ 232887828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 2329be6bf707SBarry Smith PetscFunctionReturn(0); 2330be6bf707SBarry Smith } 2331fb2e594dSBarry Smith EXTERN_C_END 2332be6bf707SBarry Smith 23334a2ae208SSatish Balay #undef __FUNCT__ 23344a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 2335be6bf707SBarry Smith /*@ 2336be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 2337be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 2338be6bf707SBarry Smith nonlinear portion. 2339be6bf707SBarry Smith 2340be6bf707SBarry Smith Collect on Mat 2341be6bf707SBarry Smith 2342be6bf707SBarry Smith Input Parameters: 2343be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 2344be6bf707SBarry Smith 234515091d37SBarry Smith Level: advanced 234615091d37SBarry Smith 2347be6bf707SBarry Smith .seealso: MatStoreValues() 2348be6bf707SBarry Smith 2349be6bf707SBarry Smith @*/ 2350be6bf707SBarry Smith int MatRetrieveValues(Mat mat) 2351be6bf707SBarry Smith { 2352be6bf707SBarry Smith int ierr,(*f)(Mat); 2353be6bf707SBarry Smith 2354be6bf707SBarry Smith PetscFunctionBegin; 2355be6bf707SBarry Smith PetscValidHeaderSpecific(mat,MAT_COOKIE); 235629bbc08cSBarry Smith if (!mat->assembled) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 235729bbc08cSBarry Smith if (mat->factor) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2358be6bf707SBarry Smith 2359c134de8dSSatish Balay ierr = PetscObjectQueryFunction((PetscObject)mat,"MatRetrieveValues_C",(void (**)(void))&f);CHKERRQ(ierr); 2360be6bf707SBarry Smith if (f) { 2361be6bf707SBarry Smith ierr = (*f)(mat);CHKERRQ(ierr); 2362be6bf707SBarry Smith } else { 236329bbc08cSBarry Smith SETERRQ(1,"Wrong type of matrix to retrieve values"); 2364be6bf707SBarry Smith } 2365be6bf707SBarry Smith PetscFunctionReturn(0); 2366be6bf707SBarry Smith } 2367be6bf707SBarry Smith 2368f83d6046SBarry Smith /* 2369f83d6046SBarry Smith This allows SeqAIJ matrices to be passed to the matlab engine 2370f83d6046SBarry Smith */ 237187828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2372f83d6046SBarry Smith #include "engine.h" /* Matlab include file */ 2373f83d6046SBarry Smith #include "mex.h" /* Matlab include file */ 2374f83d6046SBarry Smith EXTERN_C_BEGIN 23754a2ae208SSatish Balay #undef __FUNCT__ 23764a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEnginePut_SeqAIJ" 237762aa7f4eSBarry Smith int MatMatlabEnginePut_SeqAIJ(PetscObject obj,void *mengine) 2378f83d6046SBarry Smith { 23794a4478b9SSatish Balay int ierr,i,*ai,*aj; 2380f83d6046SBarry Smith Mat B = (Mat)obj; 2381f83d6046SBarry Smith mxArray *mat; 2382d79a51d8SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)B->data; 2383d79a51d8SBarry Smith 2384f83d6046SBarry Smith PetscFunctionBegin; 238501820c62SBarry Smith mat = mxCreateSparse(B->n,B->m,aij->nz,mxREAL); 238687828ca2SBarry Smith ierr = PetscMemcpy(mxGetPr(mat),aij->a,aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 2387d79a51d8SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 238866826eb6SBarry Smith ierr = PetscMemcpy(mxGetIr(mat),aij->j,aij->nz*sizeof(int));CHKERRQ(ierr); 238966826eb6SBarry Smith ierr = PetscMemcpy(mxGetJc(mat),aij->i,(B->m+1)*sizeof(int));CHKERRQ(ierr); 2390f83d6046SBarry Smith 239101820c62SBarry Smith /* Matlab indices start at 0 for sparse (what a surprise) */ 2392bfeeae90SHong Zhang 2393ca44d042SBarry Smith ierr = PetscObjectName(obj);CHKERRQ(ierr); 2394f83d6046SBarry Smith mxSetName(mat,obj->name); 239562aa7f4eSBarry Smith engPutArray((Engine *)mengine,mat); 2396f83d6046SBarry Smith PetscFunctionReturn(0); 2397f83d6046SBarry Smith } 2398f83d6046SBarry Smith EXTERN_C_END 239966826eb6SBarry Smith 240066826eb6SBarry Smith EXTERN_C_BEGIN 24014a2ae208SSatish Balay #undef __FUNCT__ 24024a2ae208SSatish Balay #define __FUNCT__ "MatMatlabEngineGet_SeqAIJ" 240362aa7f4eSBarry Smith int MatMatlabEngineGet_SeqAIJ(PetscObject obj,void *mengine) 240466826eb6SBarry Smith { 240566826eb6SBarry Smith int ierr,ii; 240666826eb6SBarry Smith Mat mat = (Mat)obj; 240766826eb6SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 240866826eb6SBarry Smith mxArray *mmat; 240966826eb6SBarry Smith 24106c0721eeSBarry Smith PetscFunctionBegin; 241166826eb6SBarry Smith ierr = PetscFree(aij->a);CHKERRQ(ierr); 241266826eb6SBarry Smith 241362aa7f4eSBarry Smith mmat = engGetArray((Engine *)mengine,obj->name); 241466826eb6SBarry Smith 2415a65776f3SBarry Smith aij->nz = (mxGetJc(mmat))[mat->m]; 2416a7ed9263SMatthew Knepley ierr = PetscMalloc(((size_t) aij->nz)*(sizeof(int)+sizeof(PetscScalar))+(mat->m+1)*sizeof(int),&aij->a);CHKERRQ(ierr); 241766826eb6SBarry Smith aij->j = (int*)(aij->a + aij->nz); 241866826eb6SBarry Smith aij->i = aij->j + aij->nz; 241966826eb6SBarry Smith aij->singlemalloc = PETSC_TRUE; 242066826eb6SBarry Smith aij->freedata = PETSC_TRUE; 242166826eb6SBarry Smith 242287828ca2SBarry Smith ierr = PetscMemcpy(aij->a,mxGetPr(mmat),aij->nz*sizeof(PetscScalar));CHKERRQ(ierr); 242366826eb6SBarry Smith /* Matlab stores by column, not row so we pass in the transpose of the matrix */ 242466826eb6SBarry Smith ierr = PetscMemcpy(aij->j,mxGetIr(mmat),aij->nz*sizeof(int));CHKERRQ(ierr); 242566826eb6SBarry Smith ierr = PetscMemcpy(aij->i,mxGetJc(mmat),(mat->m+1)*sizeof(int));CHKERRQ(ierr); 242666826eb6SBarry Smith 242766826eb6SBarry Smith for (ii=0; ii<mat->m; ii++) { 242866826eb6SBarry Smith aij->ilen[ii] = aij->imax[ii] = aij->i[ii+1] - aij->i[ii]; 242966826eb6SBarry Smith } 243066826eb6SBarry Smith 243166826eb6SBarry Smith ierr = MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 243266826eb6SBarry Smith ierr = MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 243366826eb6SBarry Smith 243466826eb6SBarry Smith PetscFunctionReturn(0); 243566826eb6SBarry Smith } 243666826eb6SBarry Smith EXTERN_C_END 2437f83d6046SBarry Smith #endif 2438f83d6046SBarry Smith 2439be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 24404a2ae208SSatish Balay #undef __FUNCT__ 24414a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 244217ab2063SBarry Smith /*@C 2443682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 24440d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 24456e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 244651c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 24472bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 244817ab2063SBarry Smith 2449db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2450db81eaa0SLois Curfman McInnes 245117ab2063SBarry Smith Input Parameters: 2452db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 245317ab2063SBarry Smith . m - number of rows 245417ab2063SBarry Smith . n - number of columns 245517ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 245651c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 24572bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 245817ab2063SBarry Smith 245917ab2063SBarry Smith Output Parameter: 2460416022c9SBarry Smith . A - the matrix 246117ab2063SBarry Smith 2462b259b22eSLois Curfman McInnes Notes: 246317ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 246417ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 24650002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 246644cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 246717ab2063SBarry Smith 246817ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2469a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 24703d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 24716da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 247217ab2063SBarry Smith 2473682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 24744fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 2475682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 24766c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 24776c7ebb05SLois Curfman McInnes 24786c7ebb05SLois Curfman McInnes Options Database Keys: 2479db81eaa0SLois Curfman McInnes + -mat_aij_no_inode - Do not use inodes 2480db81eaa0SLois Curfman McInnes . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2481db81eaa0SLois Curfman McInnes - -mat_aij_oneindex - Internally use indexing starting at 1 2482db81eaa0SLois Curfman McInnes rather than 0. Note that when calling MatSetValues(), 2483db81eaa0SLois Curfman McInnes the user still MUST index entries starting at 0! 248417ab2063SBarry Smith 2485027ccd11SLois Curfman McInnes Level: intermediate 2486027ccd11SLois Curfman McInnes 248736db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 248836db0b34SBarry Smith 248917ab2063SBarry Smith @*/ 2490ca01db9bSBarry Smith int MatCreateSeqAIJ(MPI_Comm comm,int m,int n,int nz,const int nnz[],Mat *A) 249117ab2063SBarry Smith { 2492273d9f13SBarry Smith int ierr; 24936945ee14SBarry Smith 24943a40ed3dSBarry Smith PetscFunctionBegin; 2495273d9f13SBarry Smith ierr = MatCreate(comm,m,n,m,n,A);CHKERRQ(ierr); 2496273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 2497273d9f13SBarry Smith ierr = MatSeqAIJSetPreallocation(*A,nz,nnz);CHKERRQ(ierr); 2498273d9f13SBarry Smith PetscFunctionReturn(0); 2499273d9f13SBarry Smith } 2500273d9f13SBarry Smith 25015da197adSKris Buschelman #define SKIP_ALLOCATION -4 25025da197adSKris Buschelman 25034a2ae208SSatish Balay #undef __FUNCT__ 25044a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 2505273d9f13SBarry Smith /*@C 2506273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 2507273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 2508273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 2509273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 2510273d9f13SBarry Smith 2511273d9f13SBarry Smith Collective on MPI_Comm 2512273d9f13SBarry Smith 2513273d9f13SBarry Smith Input Parameters: 2514273d9f13SBarry Smith + comm - MPI communicator, set to PETSC_COMM_SELF 2515273d9f13SBarry Smith . m - number of rows 2516273d9f13SBarry Smith . n - number of columns 2517273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 2518273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 2519273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 2520273d9f13SBarry Smith 2521273d9f13SBarry Smith Output Parameter: 2522273d9f13SBarry Smith . A - the matrix 2523273d9f13SBarry Smith 2524273d9f13SBarry Smith Notes: 2525273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 2526273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 2527273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 2528273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 2529273d9f13SBarry Smith 2530273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 2531273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 2532273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 2533273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 2534273d9f13SBarry Smith 2535273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 2536273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 2537273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 2538273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 2539273d9f13SBarry Smith 2540273d9f13SBarry Smith Options Database Keys: 2541273d9f13SBarry Smith + -mat_aij_no_inode - Do not use inodes 2542273d9f13SBarry Smith . -mat_aij_inode_limit <limit> - Sets inode limit (max limit=5) 2543273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 2544273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 2545273d9f13SBarry Smith the user still MUST index entries starting at 0! 2546273d9f13SBarry Smith 2547273d9f13SBarry Smith Level: intermediate 2548273d9f13SBarry Smith 2549273d9f13SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 2550273d9f13SBarry Smith 2551273d9f13SBarry Smith @*/ 2552ca01db9bSBarry Smith int MatSeqAIJSetPreallocation(Mat B,int nz,const int nnz[]) 2553273d9f13SBarry Smith { 2554ca01db9bSBarry Smith int ierr,(*f)(Mat,int,const int[]); 2555a23d5eceSKris Buschelman 2556a23d5eceSKris Buschelman PetscFunctionBegin; 2557a23d5eceSKris Buschelman ierr = PetscObjectQueryFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",(void (**)(void))&f);CHKERRQ(ierr); 2558a23d5eceSKris Buschelman if (f) { 2559a23d5eceSKris Buschelman ierr = (*f)(B,nz,nnz);CHKERRQ(ierr); 2560a23d5eceSKris Buschelman } 2561a23d5eceSKris Buschelman PetscFunctionReturn(0); 2562a23d5eceSKris Buschelman } 2563a23d5eceSKris Buschelman 2564a23d5eceSKris Buschelman EXTERN_C_BEGIN 2565a23d5eceSKris Buschelman #undef __FUNCT__ 2566a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 2567a23d5eceSKris Buschelman int MatSeqAIJSetPreallocation_SeqAIJ(Mat B,int nz,int *nnz) 2568a23d5eceSKris Buschelman { 2569273d9f13SBarry Smith Mat_SeqAIJ *b; 2570a7ed9263SMatthew Knepley size_t len = 0; 2571a43ee2ecSKris Buschelman PetscTruth skipallocation = PETSC_FALSE; 2572a7ed9263SMatthew Knepley int i,ierr; 2573273d9f13SBarry Smith 2574273d9f13SBarry Smith PetscFunctionBegin; 2575d5d45c9bSBarry Smith 2576c461c341SBarry Smith if (nz == SKIP_ALLOCATION) { 2577c461c341SBarry Smith skipallocation = PETSC_TRUE; 2578c461c341SBarry Smith nz = 0; 2579c461c341SBarry Smith } 2580c461c341SBarry Smith 2581435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 2582435da068SBarry Smith if (nz < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 2583b73539f3SBarry Smith if (nnz) { 2584273d9f13SBarry Smith for (i=0; i<B->m; i++) { 258529bbc08cSBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 25863a7fca6bSBarry 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); 2587b73539f3SBarry Smith } 2588b73539f3SBarry Smith } 2589b73539f3SBarry Smith 2590273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2591273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 2592273d9f13SBarry Smith 2593b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->imax);CHKERRQ(ierr); 2594273d9f13SBarry Smith if (!nnz) { 2595435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 2596273d9f13SBarry Smith else if (nz <= 0) nz = 1; 2597273d9f13SBarry Smith for (i=0; i<B->m; i++) b->imax[i] = nz; 2598273d9f13SBarry Smith nz = nz*B->m; 2599273d9f13SBarry Smith } else { 2600273d9f13SBarry Smith nz = 0; 2601273d9f13SBarry Smith for (i=0; i<B->m; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 2602273d9f13SBarry Smith } 2603273d9f13SBarry Smith 2604c461c341SBarry Smith if (!skipallocation) { 2605273d9f13SBarry Smith /* allocate the matrix space */ 2606a7ed9263SMatthew Knepley len = ((size_t) nz)*(sizeof(int) + sizeof(PetscScalar)) + (B->m+1)*sizeof(int); 2607b0a32e0cSBarry Smith ierr = PetscMalloc(len,&b->a);CHKERRQ(ierr); 2608273d9f13SBarry Smith b->j = (int*)(b->a + nz); 2609273d9f13SBarry Smith ierr = PetscMemzero(b->j,nz*sizeof(int));CHKERRQ(ierr); 2610273d9f13SBarry Smith b->i = b->j + nz; 2611bfeeae90SHong Zhang b->i[0] = 0; 26125da197adSKris Buschelman for (i=1; i<B->m+1; i++) { 26135da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 26145da197adSKris Buschelman } 2615273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 2616273d9f13SBarry Smith b->freedata = PETSC_TRUE; 2617c461c341SBarry Smith } else { 2618c461c341SBarry Smith b->freedata = PETSC_FALSE; 2619c461c341SBarry Smith } 2620273d9f13SBarry Smith 2621273d9f13SBarry Smith /* b->ilen will count nonzeros in each row so far. */ 2622b0a32e0cSBarry Smith ierr = PetscMalloc((B->m+1)*sizeof(int),&b->ilen);CHKERRQ(ierr); 2623b0a32e0cSBarry Smith PetscLogObjectMemory(B,len+2*(B->m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2624273d9f13SBarry Smith for (i=0; i<B->m; i++) { b->ilen[i] = 0;} 2625273d9f13SBarry Smith 2626273d9f13SBarry Smith b->nz = 0; 2627273d9f13SBarry Smith b->maxnz = nz; 2628273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 2629273d9f13SBarry Smith PetscFunctionReturn(0); 2630273d9f13SBarry Smith } 2631a23d5eceSKris Buschelman EXTERN_C_END 2632273d9f13SBarry Smith 2633eb9c0419SKris Buschelman EXTERN int RegisterApplyPtAPRoutines_Private(Mat); 2634eb9c0419SKris Buschelman 2635273d9f13SBarry Smith EXTERN_C_BEGIN 263605b94e36SKris Buschelman EXTERN int MatConvert_SeqAIJ_SeqSBAIJ(Mat,MatType,Mat*); 263705b94e36SKris Buschelman EXTERN int MatConvert_SeqAIJ_SeqBAIJ(Mat,MatType,Mat*); 263805b94e36SKris Buschelman EXTERN int MatReorderForNonzeroDiagonal_SeqAIJ(Mat,PetscReal,IS,IS); 26390a99d0a2SKris Buschelman EXTERN int MatAdjustForInodes_SeqAIJ(Mat,IS*,IS*); 2640d758967fSKris Buschelman EXTERN int MatSeqAIJGetInodeSizes_SeqAIJ(Mat,int*,int*[],int*); 2641a6175056SHong Zhang EXTERN_C_END 2642a6175056SHong Zhang 2643a6175056SHong Zhang EXTERN_C_BEGIN 26444a2ae208SSatish Balay #undef __FUNCT__ 26454a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 2646273d9f13SBarry Smith int MatCreate_SeqAIJ(Mat B) 2647273d9f13SBarry Smith { 2648273d9f13SBarry Smith Mat_SeqAIJ *b; 2649273d9f13SBarry Smith int ierr,size; 2650273d9f13SBarry Smith PetscTruth flg; 2651273d9f13SBarry Smith 2652273d9f13SBarry Smith PetscFunctionBegin; 2653273d9f13SBarry Smith ierr = MPI_Comm_size(B->comm,&size);CHKERRQ(ierr); 2654273d9f13SBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 2655273d9f13SBarry Smith 2656273d9f13SBarry Smith B->m = B->M = PetscMax(B->m,B->M); 2657273d9f13SBarry Smith B->n = B->N = PetscMax(B->n,B->N); 2658273d9f13SBarry Smith 2659b0a32e0cSBarry Smith ierr = PetscNew(Mat_SeqAIJ,&b);CHKERRQ(ierr); 2660b0a32e0cSBarry Smith B->data = (void*)b; 2661549d3d68SSatish Balay ierr = PetscMemzero(b,sizeof(Mat_SeqAIJ));CHKERRQ(ierr); 2662549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 2663416022c9SBarry Smith B->factor = 0; 2664416022c9SBarry Smith B->lupivotthreshold = 1.0; 266590f02eecSBarry Smith B->mapping = 0; 2666e82a3eeeSBarry Smith ierr = PetscOptionsGetReal(B->prefix,"-mat_lu_pivotthreshold",&B->lupivotthreshold,PETSC_NULL);CHKERRQ(ierr); 2667e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-pc_ilu_preserve_row_sums",&b->ilu_preserve_row_sums);CHKERRQ(ierr); 2668416022c9SBarry Smith b->row = 0; 2669416022c9SBarry Smith b->col = 0; 267082bf6240SBarry Smith b->icol = 0; 2671b810aeb4SBarry Smith b->reallocs = 0; 267217ab2063SBarry Smith 26738a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->m,B->m,&B->rmap);CHKERRQ(ierr); 26748a124369SBarry Smith ierr = PetscMapCreateMPI(B->comm,B->n,B->n,&B->cmap);CHKERRQ(ierr); 2675a5ae1ecdSBarry Smith 2676f1e2ffcdSBarry Smith b->sorted = PETSC_FALSE; 267736db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 2678f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 2679416022c9SBarry Smith b->nonew = 0; 2680416022c9SBarry Smith b->diag = 0; 2681416022c9SBarry Smith b->solve_work = 0; 26822a1b7f2aSHong Zhang B->spptr = 0; 2683b65db4caSBarry Smith b->inode.use = PETSC_TRUE; 2684754ec7b1SSatish Balay b->inode.node_count = 0; 2685754ec7b1SSatish Balay b->inode.size = 0; 26866c7ebb05SLois Curfman McInnes b->inode.limit = 5; 26876c7ebb05SLois Curfman McInnes b->inode.max_limit = 5; 2688be6bf707SBarry Smith b->saved_values = 0; 2689d7f994e1SBarry Smith b->idiag = 0; 2690d7f994e1SBarry Smith b->ssor = 0; 2691f1e2ffcdSBarry Smith b->keepzeroedrows = PETSC_FALSE; 2692a30b2313SHong Zhang b->xtoy = 0; 2693a30b2313SHong Zhang b->XtoY = 0; 269417ab2063SBarry Smith 269535d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 269635d8aa7fSBarry Smith 2697e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_essl",&flg);CHKERRQ(ierr); 269869957df2SSatish Balay if (flg) { ierr = MatUseEssl_SeqAIJ(B);CHKERRQ(ierr); } 2699e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_lusol",&flg);CHKERRQ(ierr); 2700cd5578b5SBarry Smith if (flg) { ierr = MatUseLUSOL_SeqAIJ(B);CHKERRQ(ierr); } 2701e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_matlab",&flg);CHKERRQ(ierr); 2702ca44d042SBarry Smith if (flg) {ierr = MatUseMatlab_SeqAIJ(B);CHKERRQ(ierr);} 2703e82a3eeeSBarry Smith ierr = PetscOptionsHasName(B->prefix,"-mat_aij_dxml",&flg);CHKERRQ(ierr); 270469957df2SSatish Balay if (flg){ 2705416022c9SBarry Smith ierr = MatUseDXML_SeqAIJ(B);CHKERRQ(ierr); 270617ab2063SBarry Smith } 2707f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C", 2708bef8e0ddSBarry Smith "MatSeqAIJSetColumnIndices_SeqAIJ", 2709bc4b532fSSatish Balay MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 2710f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C", 2711be6bf707SBarry Smith "MatStoreValues_SeqAIJ", 2712bc4b532fSSatish Balay MatStoreValues_SeqAIJ);CHKERRQ(ierr); 2713f1af5d2fSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C", 2714be6bf707SBarry Smith "MatRetrieveValues_SeqAIJ", 2715bc4b532fSSatish Balay MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 2716a6175056SHong Zhang ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C", 2717a6175056SHong Zhang "MatConvert_SeqAIJ_SeqSBAIJ", 2718a6175056SHong Zhang MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 271985fc7724SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C", 272085fc7724SBarry Smith "MatConvert_SeqAIJ_SeqBAIJ", 272185fc7724SBarry Smith MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 2722cd0d46ebSvictorle ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsSymmetric_C", 2723cd0d46ebSvictorle "MatIsSymmetric_SeqAIJ", 2724cd0d46ebSvictorle MatIsSymmetric_SeqAIJ);CHKERRQ(ierr); 2725a23d5eceSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C", 2726a23d5eceSKris Buschelman "MatSeqAIJSetPreallocation_SeqAIJ", 2727a23d5eceSKris Buschelman MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 272805b94e36SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C", 272905b94e36SKris Buschelman "MatReorderForNonzeroDiagonal_SeqAIJ", 273005b94e36SKris Buschelman MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 27310a99d0a2SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatAdjustForInodes_C", 27320a99d0a2SKris Buschelman "MatAdjustForInodes_SeqAIJ", 27330a99d0a2SKris Buschelman MatAdjustForInodes_SeqAIJ);CHKERRQ(ierr); 2734d758967fSKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJGetInodeSizes_C", 2735d758967fSKris Buschelman "MatSeqAIJGetInodeSizes_SeqAIJ", 2736d758967fSKris Buschelman MatSeqAIJGetInodeSizes_SeqAIJ);CHKERRQ(ierr); 273787828ca2SBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 2738f83d6046SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatMatlabEnginePut_SeqAIJ",MatMatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 273966826eb6SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatMatlabEngineGet_SeqAIJ",MatMatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 2740f83d6046SBarry Smith #endif 2741eb9c0419SKris Buschelman ierr = RegisterApplyPtAPRoutines_Private(B);CHKERRQ(ierr); 27423a40ed3dSBarry Smith PetscFunctionReturn(0); 274317ab2063SBarry Smith } 2744273d9f13SBarry Smith EXTERN_C_END 274517ab2063SBarry Smith 27464a2ae208SSatish Balay #undef __FUNCT__ 27474a2ae208SSatish Balay #define __FUNCT__ "MatDuplicate_SeqAIJ" 2748be6bf707SBarry Smith int MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 274917ab2063SBarry Smith { 2750416022c9SBarry Smith Mat C; 2751416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 2752bfeeae90SHong Zhang int i,m = A->m,ierr; 2753a7ed9263SMatthew Knepley size_t len; 275417ab2063SBarry Smith 27553a40ed3dSBarry Smith PetscFunctionBegin; 27564043dd9cSLois Curfman McInnes *B = 0; 2757273d9f13SBarry Smith ierr = MatCreate(A->comm,A->m,A->n,A->m,A->n,&C);CHKERRQ(ierr); 2758273d9f13SBarry Smith ierr = MatSetType(C,MATSEQAIJ);CHKERRQ(ierr); 2759273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 2760273d9f13SBarry Smith 2761416022c9SBarry Smith C->factor = A->factor; 2762416022c9SBarry Smith c->row = 0; 2763416022c9SBarry Smith c->col = 0; 276482bf6240SBarry Smith c->icol = 0; 2765f1e2ffcdSBarry Smith c->keepzeroedrows = a->keepzeroedrows; 2766c456f294SBarry Smith C->assembled = PETSC_TRUE; 276717ab2063SBarry Smith 2768273d9f13SBarry Smith C->M = A->m; 2769273d9f13SBarry Smith C->N = A->n; 277017ab2063SBarry Smith 2771b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->imax);CHKERRQ(ierr); 2772b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->ilen);CHKERRQ(ierr); 277317ab2063SBarry Smith for (i=0; i<m; i++) { 2774416022c9SBarry Smith c->imax[i] = a->imax[i]; 2775416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 277617ab2063SBarry Smith } 277717ab2063SBarry Smith 277817ab2063SBarry Smith /* allocate the matrix space */ 2779f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 2780a7ed9263SMatthew Knepley len = ((size_t) (m+1))*sizeof(int)+(a->i[m])*(sizeof(PetscScalar)+sizeof(int)); 2781b0a32e0cSBarry Smith ierr = PetscMalloc(len,&c->a);CHKERRQ(ierr); 2782bfeeae90SHong Zhang c->j = (int*)(c->a + a->i[m] ); 2783bfeeae90SHong Zhang c->i = c->j + a->i[m]; 2784549d3d68SSatish Balay ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(int));CHKERRQ(ierr); 278517ab2063SBarry Smith if (m > 0) { 2786bfeeae90SHong Zhang ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(int));CHKERRQ(ierr); 2787be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 2788bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 2789be6bf707SBarry Smith } else { 2790bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 279117ab2063SBarry Smith } 279208480c60SBarry Smith } 279317ab2063SBarry Smith 2794b0a32e0cSBarry Smith PetscLogObjectMemory(C,len+2*(m+1)*sizeof(int)+sizeof(struct _p_Mat)+sizeof(Mat_SeqAIJ)); 2795416022c9SBarry Smith c->sorted = a->sorted; 2796416022c9SBarry Smith c->roworiented = a->roworiented; 2797416022c9SBarry Smith c->nonew = a->nonew; 27987a743949SBarry Smith c->ilu_preserve_row_sums = a->ilu_preserve_row_sums; 2799be6bf707SBarry Smith c->saved_values = 0; 2800d7f994e1SBarry Smith c->idiag = 0; 2801d7f994e1SBarry Smith c->ssor = 0; 280236db0b34SBarry Smith c->ignorezeroentries = a->ignorezeroentries; 280336db0b34SBarry Smith c->freedata = PETSC_TRUE; 280417ab2063SBarry Smith 2805416022c9SBarry Smith if (a->diag) { 2806b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->diag);CHKERRQ(ierr); 2807b0a32e0cSBarry Smith PetscLogObjectMemory(C,(m+1)*sizeof(int)); 280817ab2063SBarry Smith for (i=0; i<m; i++) { 2809416022c9SBarry Smith c->diag[i] = a->diag[i]; 281017ab2063SBarry Smith } 28113a40ed3dSBarry Smith } else c->diag = 0; 2812b65db4caSBarry Smith c->inode.use = a->inode.use; 28136c7ebb05SLois Curfman McInnes c->inode.limit = a->inode.limit; 28146c7ebb05SLois Curfman McInnes c->inode.max_limit = a->inode.max_limit; 2815754ec7b1SSatish Balay if (a->inode.size){ 2816b0a32e0cSBarry Smith ierr = PetscMalloc((m+1)*sizeof(int),&c->inode.size);CHKERRQ(ierr); 2817754ec7b1SSatish Balay c->inode.node_count = a->inode.node_count; 2818549d3d68SSatish Balay ierr = PetscMemcpy(c->inode.size,a->inode.size,(m+1)*sizeof(int));CHKERRQ(ierr); 2819754ec7b1SSatish Balay } else { 2820754ec7b1SSatish Balay c->inode.size = 0; 2821754ec7b1SSatish Balay c->inode.node_count = 0; 2822754ec7b1SSatish Balay } 2823416022c9SBarry Smith c->nz = a->nz; 2824416022c9SBarry Smith c->maxnz = a->maxnz; 2825416022c9SBarry Smith c->solve_work = 0; 28262a1b7f2aSHong Zhang C->spptr = 0; /* Dangerous -I'm throwing away a->spptr */ 2827273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 2828754ec7b1SSatish Balay 2829416022c9SBarry Smith *B = C; 2830b0a32e0cSBarry Smith ierr = PetscFListDuplicate(A->qlist,&C->qlist);CHKERRQ(ierr); 28313a40ed3dSBarry Smith PetscFunctionReturn(0); 283217ab2063SBarry Smith } 283317ab2063SBarry Smith 2834273d9f13SBarry Smith EXTERN_C_BEGIN 28354a2ae208SSatish Balay #undef __FUNCT__ 28364a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 2837b0a32e0cSBarry Smith int MatLoad_SeqAIJ(PetscViewer viewer,MatType type,Mat *A) 283817ab2063SBarry Smith { 2839416022c9SBarry Smith Mat_SeqAIJ *a; 2840416022c9SBarry Smith Mat B; 2841efb16452SHong Zhang int i,nz,ierr,fd,header[4],size,*rowlengths = 0,M,N; 2842bcd2baecSBarry Smith MPI_Comm comm; 2843*1677d0b8SKris Buschelman #if defined(PETSC_HAVE_MUMPS) 284427fa2452SHong Zhang PetscTruth flag; 284527fa2452SHong Zhang #endif 284617ab2063SBarry Smith 28473a40ed3dSBarry Smith PetscFunctionBegin; 2848e864ced6SBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 2849d132466eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 285029bbc08cSBarry Smith if (size > 1) SETERRQ(PETSC_ERR_ARG_SIZ,"view must have one processor"); 2851b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 28520752156aSBarry Smith ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 2853552e946dSBarry Smith if (header[0] != MAT_FILE_COOKIE) SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 285417ab2063SBarry Smith M = header[1]; N = header[2]; nz = header[3]; 285517ab2063SBarry Smith 2856d64ed03dSBarry Smith if (nz < 0) { 285729bbc08cSBarry Smith SETERRQ(PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 2858d64ed03dSBarry Smith } 2859d64ed03dSBarry Smith 286017ab2063SBarry Smith /* read in row lengths */ 2861b0a32e0cSBarry Smith ierr = PetscMalloc(M*sizeof(int),&rowlengths);CHKERRQ(ierr); 28620752156aSBarry Smith ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 286317ab2063SBarry Smith 286417ab2063SBarry Smith /* create our matrix */ 2865b3a1e11cSKris Buschelman ierr = MatCreate(comm,PETSC_DECIDE,PETSC_DECIDE,M,N,&B);CHKERRQ(ierr); 2866b3a1e11cSKris Buschelman ierr = MatSetType(B,type);CHKERRQ(ierr); 2867b3a1e11cSKris Buschelman ierr = MatSeqAIJSetPreallocation(B,0,rowlengths);CHKERRQ(ierr); 2868416022c9SBarry Smith a = (Mat_SeqAIJ*)B->data; 286917ab2063SBarry Smith 287017ab2063SBarry Smith /* read in column indices and adjust for Fortran indexing*/ 28710752156aSBarry Smith ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 287217ab2063SBarry Smith 287317ab2063SBarry Smith /* read in nonzero values */ 28740752156aSBarry Smith ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 287517ab2063SBarry Smith 287617ab2063SBarry Smith /* set matrix "i" values */ 2877efb16452SHong Zhang a->i[0] = 0; 287817ab2063SBarry Smith for (i=1; i<= M; i++) { 2879416022c9SBarry Smith a->i[i] = a->i[i-1] + rowlengths[i-1]; 2880416022c9SBarry Smith a->ilen[i-1] = rowlengths[i-1]; 288117ab2063SBarry Smith } 2882606d414cSSatish Balay ierr = PetscFree(rowlengths);CHKERRQ(ierr); 288317ab2063SBarry Smith 28846d4a8577SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 28856d4a8577SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2886eee76cafSHong Zhang #if defined(PETSC_HAVE_MUMPS) 2887eee76cafSHong Zhang ierr = PetscOptionsHasName(B->prefix,"-mat_aij_mumps",&flag);CHKERRQ(ierr); 2888eee76cafSHong Zhang if (flag) { ierr = MatUseMUMPS_MPIAIJ(B);CHKERRQ(ierr); } 2889eee76cafSHong Zhang #endif 2890b3a1e11cSKris Buschelman *A = B; 28913a40ed3dSBarry Smith PetscFunctionReturn(0); 289217ab2063SBarry Smith } 2893273d9f13SBarry Smith EXTERN_C_END 289417ab2063SBarry Smith 28954a2ae208SSatish Balay #undef __FUNCT__ 2896b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 28978f6be9afSLois Curfman McInnes int MatEqual_SeqAIJ(Mat A,Mat B,PetscTruth* flg) 28987264ac53SSatish Balay { 28997264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 29000f5bd95cSBarry Smith int ierr; 29017264ac53SSatish Balay 29023a40ed3dSBarry Smith PetscFunctionBegin; 2903bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 2904bfeeae90SHong Zhang if ((A->m != B->m) || (A->n != B->n) ||(a->nz != b->nz)) { 2905ca44d042SBarry Smith *flg = PETSC_FALSE; 2906ca44d042SBarry Smith PetscFunctionReturn(0); 2907bcd2baecSBarry Smith } 29087264ac53SSatish Balay 29097264ac53SSatish Balay /* if the a->i are the same */ 2910273d9f13SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->m+1)*sizeof(int),flg);CHKERRQ(ierr); 29110f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 29127264ac53SSatish Balay 29137264ac53SSatish Balay /* if a->j are the same */ 29140f5bd95cSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(int),flg);CHKERRQ(ierr); 29150f5bd95cSBarry Smith if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 2916bcd2baecSBarry Smith 2917bcd2baecSBarry Smith /* if a->a are the same */ 291887828ca2SBarry Smith ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 29190f5bd95cSBarry Smith 29203a40ed3dSBarry Smith PetscFunctionReturn(0); 29217264ac53SSatish Balay 29227264ac53SSatish Balay } 292336db0b34SBarry Smith 29244a2ae208SSatish Balay #undef __FUNCT__ 29254a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 292636db0b34SBarry Smith /*@C 292736db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 292836db0b34SBarry Smith provided by the user. 292936db0b34SBarry Smith 293036db0b34SBarry Smith Coolective on MPI_Comm 293136db0b34SBarry Smith 293236db0b34SBarry Smith Input Parameters: 293336db0b34SBarry Smith + comm - must be an MPI communicator of size 1 293436db0b34SBarry Smith . m - number of rows 293536db0b34SBarry Smith . n - number of columns 293636db0b34SBarry Smith . i - row indices 293736db0b34SBarry Smith . j - column indices 293836db0b34SBarry Smith - a - matrix values 293936db0b34SBarry Smith 294036db0b34SBarry Smith Output Parameter: 294136db0b34SBarry Smith . mat - the matrix 294236db0b34SBarry Smith 294336db0b34SBarry Smith Level: intermediate 294436db0b34SBarry Smith 294536db0b34SBarry Smith Notes: 29460551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 294736db0b34SBarry Smith once the matrix is destroyed 294836db0b34SBarry Smith 294936db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 295036db0b34SBarry Smith 2951bfeeae90SHong Zhang The i and j indices are 0 based 295236db0b34SBarry Smith 295336db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ() 295436db0b34SBarry Smith 295536db0b34SBarry Smith @*/ 295687828ca2SBarry Smith int MatCreateSeqAIJWithArrays(MPI_Comm comm,int m,int n,int* i,int*j,PetscScalar *a,Mat *mat) 295736db0b34SBarry Smith { 295836db0b34SBarry Smith int ierr,ii; 295936db0b34SBarry Smith Mat_SeqAIJ *aij; 296036db0b34SBarry Smith 296136db0b34SBarry Smith PetscFunctionBegin; 2962c461c341SBarry Smith ierr = MatCreateSeqAIJ(comm,m,n,SKIP_ALLOCATION,0,mat);CHKERRQ(ierr); 296336db0b34SBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 296436db0b34SBarry Smith 2965bfeeae90SHong Zhang if (i[0] != 0) { 2966bfeeae90SHong Zhang SETERRQ(1,"i (row indices) must start with 0"); 296736db0b34SBarry Smith } 296836db0b34SBarry Smith aij->i = i; 296936db0b34SBarry Smith aij->j = j; 297036db0b34SBarry Smith aij->a = a; 297136db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 297236db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 297336db0b34SBarry Smith aij->freedata = PETSC_FALSE; 297436db0b34SBarry Smith 297536db0b34SBarry Smith for (ii=0; ii<m; ii++) { 297636db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 29779860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 297829bbc08cSBarry 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]); 297936db0b34SBarry Smith #endif 298036db0b34SBarry Smith } 29819860f2b2SBarry Smith #if defined(PETSC_USE_BOPT_g) 298236db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 2983bfeeae90SHong Zhang if (j[ii] < 0) SETERRQ2(1,"Negative column index at location = %d index = %d",ii,j[ii]); 2984bfeeae90SHong Zhang if (j[ii] > n - 1) SETERRQ2(1,"Column index to large at location = %d index = %d",ii,j[ii]); 298536db0b34SBarry Smith } 298636db0b34SBarry Smith #endif 298736db0b34SBarry Smith 2988b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2989b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 299036db0b34SBarry Smith PetscFunctionReturn(0); 299136db0b34SBarry Smith } 299236db0b34SBarry Smith 2993cc8ba8e1SBarry Smith #undef __FUNCT__ 2994ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 2995ee4f033dSBarry Smith int MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 2996cc8ba8e1SBarry Smith { 2997cc8ba8e1SBarry Smith int ierr; 2998cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 299936db0b34SBarry Smith 3000cc8ba8e1SBarry Smith PetscFunctionBegin; 300112c595b3SBarry Smith if (coloring->ctype == IS_COLORING_LOCAL) { 3002cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 3003cc8ba8e1SBarry Smith a->coloring = coloring; 300412c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 300508b6dcc0SBarry Smith int i,*larray; 300612c595b3SBarry Smith ISColoring ocoloring; 300708b6dcc0SBarry Smith ISColoringValue *colors; 300812c595b3SBarry Smith 300912c595b3SBarry Smith /* set coloring for diagonal portion */ 301012c595b3SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(int),&larray);CHKERRQ(ierr); 301112c595b3SBarry Smith for (i=0; i<A->n; i++) { 301212c595b3SBarry Smith larray[i] = i; 301312c595b3SBarry Smith } 301412c595b3SBarry Smith ierr = ISGlobalToLocalMappingApply(A->mapping,IS_GTOLM_MASK,A->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 301508b6dcc0SBarry Smith ierr = PetscMalloc((A->n+1)*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 301612c595b3SBarry Smith for (i=0; i<A->n; i++) { 301712c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 301812c595b3SBarry Smith } 301912c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 302012c595b3SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,A->n,colors,&ocoloring);CHKERRQ(ierr); 302112c595b3SBarry Smith a->coloring = ocoloring; 302212c595b3SBarry Smith } 3023cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3024cc8ba8e1SBarry Smith } 3025cc8ba8e1SBarry Smith 302687828ca2SBarry Smith #if defined(PETSC_HAVE_ADIC) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) 3027ee4f033dSBarry Smith EXTERN_C_BEGIN 302829c1e371SBarry Smith #include "adic/ad_utils.h" 3029ee4f033dSBarry Smith EXTERN_C_END 3030cc8ba8e1SBarry Smith 3031cc8ba8e1SBarry Smith #undef __FUNCT__ 3032ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3033ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3034cc8ba8e1SBarry Smith { 3035cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 303608b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j,nlen; 30374440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 303808b6dcc0SBarry Smith ISColoringValue *color; 3039cc8ba8e1SBarry Smith 3040cc8ba8e1SBarry Smith PetscFunctionBegin; 3041cc8ba8e1SBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 30424440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 3043cc8ba8e1SBarry Smith color = a->coloring->colors; 3044cc8ba8e1SBarry Smith /* loop over rows */ 3045cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 3046cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 3047cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 3048cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 3049cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 3050cc8ba8e1SBarry Smith } 30514440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 3052ee4f033dSBarry Smith } 3053ee4f033dSBarry Smith PetscFunctionReturn(0); 3054ee4f033dSBarry Smith } 3055ee4f033dSBarry Smith 3056ee4f033dSBarry Smith #else 3057ee4f033dSBarry Smith 3058ee4f033dSBarry Smith #undef __FUNCT__ 3059ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 3060ee4f033dSBarry Smith int MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 3061ee4f033dSBarry Smith { 3062ee4f033dSBarry Smith PetscFunctionBegin; 3063ee4f033dSBarry Smith SETERRQ(1,"PETSc installed without ADIC"); 3064ee4f033dSBarry Smith } 3065ee4f033dSBarry Smith 3066ee4f033dSBarry Smith #endif 3067ee4f033dSBarry Smith 3068ee4f033dSBarry Smith #undef __FUNCT__ 3069ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 3070ee4f033dSBarry Smith int MatSetValuesAdifor_SeqAIJ(Mat A,int nl,void *advalues) 3071ee4f033dSBarry Smith { 3072ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 307308b6dcc0SBarry Smith int m = A->m,*ii = a->i,*jj = a->j,nz,i,j; 307487828ca2SBarry Smith PetscScalar *v = a->a,*values = (PetscScalar *)advalues; 307508b6dcc0SBarry Smith ISColoringValue *color; 3076ee4f033dSBarry Smith 3077ee4f033dSBarry Smith PetscFunctionBegin; 3078ee4f033dSBarry Smith if (!a->coloring) SETERRQ(1,"Coloring not set for matrix"); 3079ee4f033dSBarry Smith color = a->coloring->colors; 3080ee4f033dSBarry Smith /* loop over rows */ 3081ee4f033dSBarry Smith for (i=0; i<m; i++) { 3082ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 3083ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 3084ee4f033dSBarry Smith for (j=0; j<nz; j++) { 3085ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 3086ee4f033dSBarry Smith } 3087ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 3088cc8ba8e1SBarry Smith } 3089cc8ba8e1SBarry Smith PetscFunctionReturn(0); 3090cc8ba8e1SBarry Smith } 309136db0b34SBarry Smith 3092