1b377110cSBarry Smith 2d5d45c9bSBarry Smith /* 33369ce9aSBarry Smith Defines the basic matrix operations for the AIJ (compressed row) 4d5d45c9bSBarry Smith matrix storage format. 5d5d45c9bSBarry Smith */ 63369ce9aSBarry Smith 77c4f633dSBarry Smith 8c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 9c6db04a5SJed Brown #include <petscblaslapack.h> 10c6db04a5SJed Brown #include <petscbt.h> 1117ab2063SBarry Smith 120716a85fSBarry Smith 130716a85fSBarry Smith #undef __FUNCT__ 140716a85fSBarry Smith #define __FUNCT__ "MatGetColumnNorms_SeqAIJ" 150716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 160716a85fSBarry Smith { 170716a85fSBarry Smith PetscErrorCode ierr; 180716a85fSBarry Smith PetscInt i,m,n; 190716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 200716a85fSBarry Smith 210716a85fSBarry Smith PetscFunctionBegin; 220716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 230716a85fSBarry Smith ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr); 240716a85fSBarry Smith if (type == NORM_2) { 250716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 260716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 270716a85fSBarry Smith } 280716a85fSBarry Smith } else if (type == NORM_1) { 290716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 300716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 310716a85fSBarry Smith } 320716a85fSBarry Smith } else if (type == NORM_INFINITY) { 330716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 340716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 350716a85fSBarry Smith } 360716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 370716a85fSBarry Smith 380716a85fSBarry Smith if (type == NORM_2) { 390716a85fSBarry Smith for (i=0; i<n; i++) norms[i] = sqrt(norms[i]); 400716a85fSBarry Smith } 410716a85fSBarry Smith PetscFunctionReturn(0); 420716a85fSBarry Smith } 430716a85fSBarry Smith 444a2ae208SSatish Balay #undef __FUNCT__ 456ce1633cSBarry Smith #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ" 466ce1633cSBarry Smith PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 476ce1633cSBarry Smith { 486ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 496ce1633cSBarry Smith const MatScalar *aa = a->a; 506ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 516ce1633cSBarry Smith const PetscInt *jj = a->j,*diag; 526ce1633cSBarry Smith PetscInt *rows; 536ce1633cSBarry Smith PetscErrorCode ierr; 546ce1633cSBarry Smith 556ce1633cSBarry Smith PetscFunctionBegin; 566ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 576ce1633cSBarry Smith diag = a->diag; 586ce1633cSBarry Smith for (i=0; i<m; i++) { 596ce1633cSBarry Smith if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 606ce1633cSBarry Smith cnt++; 616ce1633cSBarry Smith } 626ce1633cSBarry Smith } 636ce1633cSBarry Smith ierr = PetscMalloc(cnt*sizeof(PetscInt),&rows);CHKERRQ(ierr); 646ce1633cSBarry Smith cnt = 0; 656ce1633cSBarry Smith for (i=0; i<m; i++) { 666ce1633cSBarry Smith if ((jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 676ce1633cSBarry Smith rows[cnt++] = i; 686ce1633cSBarry Smith } 696ce1633cSBarry Smith } 706ce1633cSBarry Smith ierr = ISCreateGeneral(((PetscObject)A)->comm,cnt,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 716ce1633cSBarry Smith PetscFunctionReturn(0); 726ce1633cSBarry Smith } 736ce1633cSBarry Smith 746ce1633cSBarry Smith #undef __FUNCT__ 75b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ" 76b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 77b3a44c85SBarry Smith { 78b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 79b3a44c85SBarry Smith const MatScalar *aa; 80b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 81b3a44c85SBarry Smith const PetscInt *ii; 82b3a44c85SBarry Smith PetscInt n,i,j,*rows; 83b3a44c85SBarry Smith PetscErrorCode ierr; 84b3a44c85SBarry Smith 85b3a44c85SBarry Smith PetscFunctionBegin; 86b3a44c85SBarry Smith *keptrows = 0; 87b3a44c85SBarry Smith ii = a->i; 88b3a44c85SBarry Smith for (i=0; i<m; i++) { 89b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 90b3a44c85SBarry Smith if (!n) { 91b3a44c85SBarry Smith cnt++; 92b3a44c85SBarry Smith goto ok1; 93b3a44c85SBarry Smith } 94b3a44c85SBarry Smith aa = a->a + ii[i]; 95b3a44c85SBarry Smith for (j=0; j<n; j++) { 96b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 97b3a44c85SBarry Smith } 98b3a44c85SBarry Smith cnt++; 99b3a44c85SBarry Smith ok1:; 100b3a44c85SBarry Smith } 101b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 102b3a44c85SBarry Smith ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr); 103b3a44c85SBarry Smith cnt = 0; 104b3a44c85SBarry Smith for (i=0; i<m; i++) { 105b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 106b3a44c85SBarry Smith if (!n) continue; 107b3a44c85SBarry Smith aa = a->a + ii[i]; 108b3a44c85SBarry Smith for (j=0; j<n; j++) { 109b3a44c85SBarry Smith if (aa[j] != 0.0) { 110b3a44c85SBarry Smith rows[cnt++] = i; 111b3a44c85SBarry Smith break; 112b3a44c85SBarry Smith } 113b3a44c85SBarry Smith } 114b3a44c85SBarry Smith } 115b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 116b3a44c85SBarry Smith PetscFunctionReturn(0); 117b3a44c85SBarry Smith } 118b3a44c85SBarry Smith 119b3a44c85SBarry Smith #undef __FUNCT__ 12079299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 1217087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 12279299369SBarry Smith { 12379299369SBarry Smith PetscErrorCode ierr; 12479299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 125d0f46423SBarry Smith PetscInt i,*diag, m = Y->rmap->n; 12654f21887SBarry Smith MatScalar *aa = aij->a; 12754f21887SBarry Smith PetscScalar *v; 128ace3abfcSBarry Smith PetscBool missing; 12979299369SBarry Smith 13079299369SBarry Smith PetscFunctionBegin; 13109f38230SBarry Smith if (Y->assembled) { 13209f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr); 13309f38230SBarry Smith if (!missing) { 13479299369SBarry Smith diag = aij->diag; 13579299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 13679299369SBarry Smith if (is == INSERT_VALUES) { 13779299369SBarry Smith for (i=0; i<m; i++) { 13879299369SBarry Smith aa[diag[i]] = v[i]; 13979299369SBarry Smith } 14079299369SBarry Smith } else { 14179299369SBarry Smith for (i=0; i<m; i++) { 14279299369SBarry Smith aa[diag[i]] += v[i]; 14379299369SBarry Smith } 14479299369SBarry Smith } 14579299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 14679299369SBarry Smith PetscFunctionReturn(0); 14779299369SBarry Smith } 14809f38230SBarry Smith } 14909f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 15009f38230SBarry Smith PetscFunctionReturn(0); 15109f38230SBarry Smith } 15279299369SBarry Smith 15379299369SBarry Smith #undef __FUNCT__ 1544a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 155ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 15617ab2063SBarry Smith { 157416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 158dfbe8321SBarry Smith PetscErrorCode ierr; 15997f1f81fSBarry Smith PetscInt i,ishift; 16017ab2063SBarry Smith 1613a40ed3dSBarry Smith PetscFunctionBegin; 162d0f46423SBarry Smith *m = A->rmap->n; 1633a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 164bfeeae90SHong Zhang ishift = 0; 16553e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 166d0f46423SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 167bfeeae90SHong Zhang } else if (oshift == 1) { 168d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 1693b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 170d0f46423SBarry Smith ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr); 171d0f46423SBarry Smith for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1; 172ecc77c7aSBarry Smith if (ja) { 17397f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr); 1743b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 175ecc77c7aSBarry Smith } 1766945ee14SBarry Smith } else { 177ecc77c7aSBarry Smith *ia = a->i; 178ecc77c7aSBarry Smith if (ja) *ja = a->j; 179a2ce50c7SBarry Smith } 1803a40ed3dSBarry Smith PetscFunctionReturn(0); 181a2744918SBarry Smith } 182a2744918SBarry Smith 1834a2ae208SSatish Balay #undef __FUNCT__ 1844a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 185ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 1866945ee14SBarry Smith { 187dfbe8321SBarry Smith PetscErrorCode ierr; 1886945ee14SBarry Smith 1893a40ed3dSBarry Smith PetscFunctionBegin; 1903a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 191bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 192606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 193ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 194bcd2baecSBarry Smith } 1953a40ed3dSBarry Smith PetscFunctionReturn(0); 19617ab2063SBarry Smith } 19717ab2063SBarry Smith 1984a2ae208SSatish Balay #undef __FUNCT__ 1994a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 200ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 2013b2fbd54SBarry Smith { 2023b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 203dfbe8321SBarry Smith PetscErrorCode ierr; 204d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 20597f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2063b2fbd54SBarry Smith 2073a40ed3dSBarry Smith PetscFunctionBegin; 208899cda47SBarry Smith *nn = n; 2093a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2103b2fbd54SBarry Smith if (symmetric) { 211d0f46423SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 2123b2fbd54SBarry Smith } else { 21397f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 21497f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 21597f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 21697f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 2173b2fbd54SBarry Smith jj = a->j; 2183b2fbd54SBarry Smith for (i=0; i<nz; i++) { 219bfeeae90SHong Zhang collengths[jj[i]]++; 2203b2fbd54SBarry Smith } 2213b2fbd54SBarry Smith cia[0] = oshift; 2223b2fbd54SBarry Smith for (i=0; i<n; i++) { 2233b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2243b2fbd54SBarry Smith } 22597f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2263b2fbd54SBarry Smith jj = a->j; 227a93ec695SBarry Smith for (row=0; row<m; row++) { 228a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 229a93ec695SBarry Smith for (i=0; i<mr; i++) { 230bfeeae90SHong Zhang col = *jj++; 2313b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2323b2fbd54SBarry Smith } 2333b2fbd54SBarry Smith } 234606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2353b2fbd54SBarry Smith *ia = cia; *ja = cja; 2363b2fbd54SBarry Smith } 2373a40ed3dSBarry Smith PetscFunctionReturn(0); 2383b2fbd54SBarry Smith } 2393b2fbd54SBarry Smith 2404a2ae208SSatish Balay #undef __FUNCT__ 2414a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 242ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 2433b2fbd54SBarry Smith { 244dfbe8321SBarry Smith PetscErrorCode ierr; 245606d414cSSatish Balay 2463a40ed3dSBarry Smith PetscFunctionBegin; 2473a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2483b2fbd54SBarry Smith 249606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 250606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2513b2fbd54SBarry Smith 2523a40ed3dSBarry Smith PetscFunctionReturn(0); 2533b2fbd54SBarry Smith } 2543b2fbd54SBarry Smith 25587d4246cSBarry Smith #undef __FUNCT__ 25687d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 25787d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 25887d4246cSBarry Smith { 25987d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26087d4246cSBarry Smith PetscInt *ai = a->i; 26187d4246cSBarry Smith PetscErrorCode ierr; 26287d4246cSBarry Smith 26387d4246cSBarry Smith PetscFunctionBegin; 26487d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 26587d4246cSBarry Smith PetscFunctionReturn(0); 26687d4246cSBarry Smith } 26787d4246cSBarry Smith 2684a2ae208SSatish Balay #undef __FUNCT__ 2694a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 27097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 27117ab2063SBarry Smith { 272416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 273e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 27497f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 2756849ba73SBarry Smith PetscErrorCode ierr; 276e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 27754f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 278ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 279ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 28017ab2063SBarry Smith 2813a40ed3dSBarry Smith PetscFunctionBegin; 28271fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 28317ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 284416022c9SBarry Smith row = im[k]; 2855ef9f2a5SBarry Smith if (row < 0) continue; 2862515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 287e32f2f54SBarry Smith if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 2883b2fbd54SBarry Smith #endif 289bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 29017ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 291416022c9SBarry Smith low = 0; 292c71e6ed7SBarry Smith high = nrow; 29317ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 2945ef9f2a5SBarry Smith if (in[l] < 0) continue; 2952515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 296e32f2f54SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 2973b2fbd54SBarry Smith #endif 298bfeeae90SHong Zhang col = in[l]; 29916371a99SBarry Smith if (v) { 3004b0e389bSBarry Smith if (roworiented) { 3015ef9f2a5SBarry Smith value = v[l + k*n]; 302bef8e0ddSBarry Smith } else { 3034b0e389bSBarry Smith value = v[k + l*m]; 3044b0e389bSBarry Smith } 30516371a99SBarry Smith } else { 30675567043SBarry Smith value = 0.; 30716371a99SBarry Smith } 308abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 30936db0b34SBarry Smith 3107cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 311e2ee6c50SBarry Smith lastcol = col; 312416022c9SBarry Smith while (high-low > 5) { 313416022c9SBarry Smith t = (low+high)/2; 314416022c9SBarry Smith if (rp[t] > col) high = t; 315416022c9SBarry Smith else low = t; 31617ab2063SBarry Smith } 317416022c9SBarry Smith for (i=low; i<high; i++) { 31817ab2063SBarry Smith if (rp[i] > col) break; 31917ab2063SBarry Smith if (rp[i] == col) { 320416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 32117ab2063SBarry Smith else ap[i] = value; 322e44c0bd4SBarry Smith low = i + 1; 32317ab2063SBarry Smith goto noinsert; 32417ab2063SBarry Smith } 32517ab2063SBarry Smith } 326abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 327c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 328e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 329fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 330c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 331416022c9SBarry Smith /* shift up all the later entries in this row */ 332416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 33317ab2063SBarry Smith rp[ii+1] = rp[ii]; 33417ab2063SBarry Smith ap[ii+1] = ap[ii]; 33517ab2063SBarry Smith } 33617ab2063SBarry Smith rp[i] = col; 33717ab2063SBarry Smith ap[i] = value; 338416022c9SBarry Smith low = i + 1; 339e44c0bd4SBarry Smith noinsert:; 34017ab2063SBarry Smith } 34117ab2063SBarry Smith ailen[row] = nrow; 34217ab2063SBarry Smith } 34388e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 3443a40ed3dSBarry Smith PetscFunctionReturn(0); 34517ab2063SBarry Smith } 34617ab2063SBarry Smith 34781824310SBarry Smith 3484a2ae208SSatish Balay #undef __FUNCT__ 3494a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 350a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 3517eb43aa7SLois Curfman McInnes { 3527eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 35397f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 35497f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 35554f21887SBarry Smith MatScalar *ap,*aa = a->a; 3567eb43aa7SLois Curfman McInnes 3573a40ed3dSBarry Smith PetscFunctionBegin; 3587eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 3597eb43aa7SLois Curfman McInnes row = im[k]; 360e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 361e32f2f54SBarry Smith if (row >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",row,A->rmap->n-1); 362bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 3637eb43aa7SLois Curfman McInnes nrow = ailen[row]; 3647eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 365e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 366e32f2f54SBarry Smith if (in[l] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",in[l],A->cmap->n-1); 367bfeeae90SHong Zhang col = in[l] ; 3687eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 3697eb43aa7SLois Curfman McInnes while (high-low > 5) { 3707eb43aa7SLois Curfman McInnes t = (low+high)/2; 3717eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 3727eb43aa7SLois Curfman McInnes else low = t; 3737eb43aa7SLois Curfman McInnes } 3747eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 3757eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 3767eb43aa7SLois Curfman McInnes if (rp[i] == col) { 377b49de8d1SLois Curfman McInnes *v++ = ap[i]; 3787eb43aa7SLois Curfman McInnes goto finished; 3797eb43aa7SLois Curfman McInnes } 3807eb43aa7SLois Curfman McInnes } 38197e567efSBarry Smith *v++ = 0.0; 3827eb43aa7SLois Curfman McInnes finished:; 3837eb43aa7SLois Curfman McInnes } 3847eb43aa7SLois Curfman McInnes } 3853a40ed3dSBarry Smith PetscFunctionReturn(0); 3867eb43aa7SLois Curfman McInnes } 3877eb43aa7SLois Curfman McInnes 38817ab2063SBarry Smith 3894a2ae208SSatish Balay #undef __FUNCT__ 3904a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 391dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 39217ab2063SBarry Smith { 393416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3946849ba73SBarry Smith PetscErrorCode ierr; 3956f69ff64SBarry Smith PetscInt i,*col_lens; 3966f69ff64SBarry Smith int fd; 39717ab2063SBarry Smith 3983a40ed3dSBarry Smith PetscFunctionBegin; 399b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 400d0f46423SBarry Smith ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 4010700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 402d0f46423SBarry Smith col_lens[1] = A->rmap->n; 403d0f46423SBarry Smith col_lens[2] = A->cmap->n; 404416022c9SBarry Smith col_lens[3] = a->nz; 405416022c9SBarry Smith 406416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 407d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 408416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 40917ab2063SBarry Smith } 410d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 411606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 412416022c9SBarry Smith 413416022c9SBarry Smith /* store column indices (zero start index) */ 4146f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 415416022c9SBarry Smith 416416022c9SBarry Smith /* store nonzero values */ 4176f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 4183a40ed3dSBarry Smith PetscFunctionReturn(0); 41917ab2063SBarry Smith } 420416022c9SBarry Smith 42109573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 422cd155464SBarry Smith 4234a2ae208SSatish Balay #undef __FUNCT__ 4244a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 425dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 426416022c9SBarry Smith { 427416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 428dfbe8321SBarry Smith PetscErrorCode ierr; 429d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,shift=0; 430e060cb09SBarry Smith const char *name; 431f3ef73ceSBarry Smith PetscViewerFormat format; 43217ab2063SBarry Smith 4333a40ed3dSBarry Smith PetscFunctionBegin; 434b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 43571c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 43697f1f81fSBarry Smith PetscInt nofinalvalue = 0; 437d0f46423SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) { 438d00d2cf4SBarry Smith nofinalvalue = 1; 439d00d2cf4SBarry Smith } 440d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 441d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 44277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 44377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 444b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 44517ab2063SBarry Smith 44617ab2063SBarry Smith for (i=0; i<m; i++) { 447416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 448aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 44977431f27SBarry 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); 45017ab2063SBarry Smith #else 45177431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 45217ab2063SBarry Smith #endif 45317ab2063SBarry Smith } 45417ab2063SBarry Smith } 455d00d2cf4SBarry Smith if (nofinalvalue) { 456d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 457d00d2cf4SBarry Smith } 458317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 459fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 460d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 46168369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 462cd155464SBarry Smith PetscFunctionReturn(0); 463fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 464d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 4657566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 46644cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 46777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 46844cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 469aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 47036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 471a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 47236db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 473a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 47436db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 475a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 4766831982aSBarry Smith } 47744cd7ae7SLois Curfman McInnes #else 478a83599f4SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 47944cd7ae7SLois Curfman McInnes #endif 48044cd7ae7SLois Curfman McInnes } 481b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 48244cd7ae7SLois Curfman McInnes } 483d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 484fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 48597f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 486d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 4877566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 48897f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 489496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 490496be53dSLois Curfman McInnes sptr[i] = nzd+1; 491496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 492496be53dSLois Curfman McInnes if (a->j[j] >= i) { 493aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 49436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 495496be53dSLois Curfman McInnes #else 496496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 497496be53dSLois Curfman McInnes #endif 498496be53dSLois Curfman McInnes } 499496be53dSLois Curfman McInnes } 500496be53dSLois Curfman McInnes } 5012e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 50277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 5032e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 50477431f27SBarry 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);} 50577431f27SBarry 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);} 50677431f27SBarry 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);} 50777431f27SBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 50877431f27SBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 50977431f27SBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);} 510496be53dSLois Curfman McInnes } 511b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 512606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 513496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 514496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 51577431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 516496be53dSLois Curfman McInnes } 517b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 518496be53dSLois Curfman McInnes } 519b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 520496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 521496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 522496be53dSLois Curfman McInnes if (a->j[j] >= i) { 523aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 52436db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 525b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 5266831982aSBarry Smith } 527496be53dSLois Curfman McInnes #else 528b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 529496be53dSLois Curfman McInnes #endif 530496be53dSLois Curfman McInnes } 531496be53dSLois Curfman McInnes } 532b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 533496be53dSLois Curfman McInnes } 534d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 535fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 53697f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 53787828ca2SBarry Smith PetscScalar value; 53802594712SBarry Smith 539d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5407566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 54102594712SBarry Smith for (i=0; i<m; i++) { 54202594712SBarry Smith jcnt = 0; 543d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 544e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 54502594712SBarry Smith value = a->a[cnt++]; 546e24b481bSBarry Smith jcnt++; 54702594712SBarry Smith } else { 54802594712SBarry Smith value = 0.0; 54902594712SBarry Smith } 550aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 551b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 55202594712SBarry Smith #else 553b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 55402594712SBarry Smith #endif 55502594712SBarry Smith } 556b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 55702594712SBarry Smith } 558d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 5593c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 560d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5617566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 5623c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 5633c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 5643c215bfdSMatthew Knepley #else 5653c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 5663c215bfdSMatthew Knepley #endif 567d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 5683c215bfdSMatthew Knepley for (i=0; i<m; i++) { 5693c215bfdSMatthew Knepley for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 5703c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 5713c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 5723c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 5733c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 5743c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G -%G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 5753c215bfdSMatthew Knepley } else { 5763c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 5773c215bfdSMatthew Knepley } 5783c215bfdSMatthew Knepley #else 5793c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr); 5803c215bfdSMatthew Knepley #endif 5813c215bfdSMatthew Knepley } 5823c215bfdSMatthew Knepley } 583d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 5843a40ed3dSBarry Smith } else { 585d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5867566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 587d5f3da31SBarry Smith if (A->factortype){ 58816cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 58916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 59016cd7e1dSShri Abhyankar /* L part */ 59116cd7e1dSShri Abhyankar for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 59216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 59316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 59416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 59516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 59616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 59716cd7e1dSShri Abhyankar } else { 59816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 59916cd7e1dSShri Abhyankar } 60016cd7e1dSShri Abhyankar #else 60116cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 60216cd7e1dSShri Abhyankar #endif 60316cd7e1dSShri Abhyankar } 60416cd7e1dSShri Abhyankar /* diagonal */ 60516cd7e1dSShri Abhyankar j = a->diag[i]; 60616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 60716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 60816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 60916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 61016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 61116cd7e1dSShri Abhyankar } else { 61216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 61316cd7e1dSShri Abhyankar } 61416cd7e1dSShri Abhyankar #else 61516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 61616cd7e1dSShri Abhyankar #endif 61716cd7e1dSShri Abhyankar 61816cd7e1dSShri Abhyankar /* U part */ 61916cd7e1dSShri Abhyankar for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) { 62016cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 62116cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 62216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 62316cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 62416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 62516cd7e1dSShri Abhyankar } else { 62616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 62716cd7e1dSShri Abhyankar } 62816cd7e1dSShri Abhyankar #else 62916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 63016cd7e1dSShri Abhyankar #endif 63116cd7e1dSShri Abhyankar } 63216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 63316cd7e1dSShri Abhyankar } 63416cd7e1dSShri Abhyankar } else { 63517ab2063SBarry Smith for (i=0; i<m; i++) { 63677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 637416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 638aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 63936db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 640a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 64136db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 642a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6433a40ed3dSBarry Smith } else { 644a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 64517ab2063SBarry Smith } 64617ab2063SBarry Smith #else 647a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 64817ab2063SBarry Smith #endif 64917ab2063SBarry Smith } 650b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 65117ab2063SBarry Smith } 65216cd7e1dSShri Abhyankar } 653d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 65417ab2063SBarry Smith } 655b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 6563a40ed3dSBarry Smith PetscFunctionReturn(0); 657416022c9SBarry Smith } 658416022c9SBarry Smith 6594a2ae208SSatish Balay #undef __FUNCT__ 6604a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 661dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 662416022c9SBarry Smith { 663480ef9eaSBarry Smith Mat A = (Mat) Aa; 664416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 665dfbe8321SBarry Smith PetscErrorCode ierr; 666d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 66736db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 668b0a32e0cSBarry Smith PetscViewer viewer; 669f3ef73ceSBarry Smith PetscViewerFormat format; 670cddf8d76SBarry Smith 6713a40ed3dSBarry Smith PetscFunctionBegin; 672480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 673b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 67419bcc07fSBarry Smith 675b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 676416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 6770513a670SBarry Smith 678fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 6790513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 680b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 681416022c9SBarry Smith for (i=0; i<m; i++) { 682cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 683bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 684bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 685aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 68636db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 687cddf8d76SBarry Smith #else 688cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 689cddf8d76SBarry Smith #endif 690b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 691cddf8d76SBarry Smith } 692cddf8d76SBarry Smith } 693b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 694cddf8d76SBarry Smith for (i=0; i<m; i++) { 695cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 696bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 697bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 698cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 699b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 700cddf8d76SBarry Smith } 701cddf8d76SBarry Smith } 702b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 703cddf8d76SBarry Smith for (i=0; i<m; i++) { 704cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 705bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 706bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 707aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70836db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 709cddf8d76SBarry Smith #else 710cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 711cddf8d76SBarry Smith #endif 712b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 713416022c9SBarry Smith } 714416022c9SBarry Smith } 7150513a670SBarry Smith } else { 7160513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 7170513a670SBarry Smith /* first determine max of all nonzero values */ 71897f1f81fSBarry Smith PetscInt nz = a->nz,count; 719b0a32e0cSBarry Smith PetscDraw popup; 72036db0b34SBarry Smith PetscReal scale; 7210513a670SBarry Smith 7220513a670SBarry Smith for (i=0; i<nz; i++) { 7230513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 7240513a670SBarry Smith } 725b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 726b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 727b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 7280513a670SBarry Smith count = 0; 7290513a670SBarry Smith for (i=0; i<m; i++) { 7300513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 731bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 732bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 73397f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 734b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 7350513a670SBarry Smith count++; 7360513a670SBarry Smith } 7370513a670SBarry Smith } 7380513a670SBarry Smith } 739480ef9eaSBarry Smith PetscFunctionReturn(0); 740480ef9eaSBarry Smith } 741cddf8d76SBarry Smith 7424a2ae208SSatish Balay #undef __FUNCT__ 7434a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 744dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 745480ef9eaSBarry Smith { 746dfbe8321SBarry Smith PetscErrorCode ierr; 747b0a32e0cSBarry Smith PetscDraw draw; 74836db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 749ace3abfcSBarry Smith PetscBool isnull; 750480ef9eaSBarry Smith 751480ef9eaSBarry Smith PetscFunctionBegin; 752b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 753b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 754480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 755480ef9eaSBarry Smith 756480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 757d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 758480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 759b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 760b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 761480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 7623a40ed3dSBarry Smith PetscFunctionReturn(0); 763416022c9SBarry Smith } 764416022c9SBarry Smith 7654a2ae208SSatish Balay #undef __FUNCT__ 7664a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 767dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 768416022c9SBarry Smith { 769dfbe8321SBarry Smith PetscErrorCode ierr; 770ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 771416022c9SBarry Smith 7723a40ed3dSBarry Smith PetscFunctionBegin; 7732692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 7742692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 7752692d6eeSBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 776c45a1595SBarry Smith if (iascii) { 7773a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 7780f5bd95cSBarry Smith } else if (isbinary) { 7793a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 7800f5bd95cSBarry Smith } else if (isdraw) { 7813a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 7825cd90555SBarry Smith } else { 783e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 78417ab2063SBarry Smith } 7854108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 7863a40ed3dSBarry Smith PetscFunctionReturn(0); 78717ab2063SBarry Smith } 78819bcc07fSBarry Smith 7894a2ae208SSatish Balay #undef __FUNCT__ 7904a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 791dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 79217ab2063SBarry Smith { 793416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 7946849ba73SBarry Smith PetscErrorCode ierr; 79597f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 796d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 79754f21887SBarry Smith MatScalar *aa = a->a,*ap; 7983447b6efSHong Zhang PetscReal ratio=0.6; 79917ab2063SBarry Smith 8003a40ed3dSBarry Smith PetscFunctionBegin; 8013a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 80217ab2063SBarry Smith 80343ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 80417ab2063SBarry Smith for (i=1; i<m; i++) { 805416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 80617ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 80794a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 80817ab2063SBarry Smith if (fshift) { 809bfeeae90SHong Zhang ip = aj + ai[i] ; 810bfeeae90SHong Zhang ap = aa + ai[i] ; 81117ab2063SBarry Smith N = ailen[i]; 81217ab2063SBarry Smith for (j=0; j<N; j++) { 81317ab2063SBarry Smith ip[j-fshift] = ip[j]; 81417ab2063SBarry Smith ap[j-fshift] = ap[j]; 81517ab2063SBarry Smith } 81617ab2063SBarry Smith } 81717ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 81817ab2063SBarry Smith } 81917ab2063SBarry Smith if (m) { 82017ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 82117ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 82217ab2063SBarry Smith } 82317ab2063SBarry Smith /* reset ilen and imax for each row */ 82417ab2063SBarry Smith for (i=0; i<m; i++) { 82517ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 82617ab2063SBarry Smith } 827bfeeae90SHong Zhang a->nz = ai[m]; 82865e19b50SBarry Smith if (fshift && a->nounused == -1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB, "Unused space detected in matrix: %D X %D, %D unneeded", m, A->cmap->n, fshift); 82917ab2063SBarry Smith 83009f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 831d0f46423SBarry Smith ierr = PetscInfo4(A,"Matrix size: %D X %D; storage space: %D unneeded,%D used\n",m,A->cmap->n,fshift,a->nz);CHKERRQ(ierr); 832ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 833ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 8348e58a170SBarry Smith A->info.mallocs += a->reallocs; 835dd5f02e7SSatish Balay a->reallocs = 0; 8364e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 83736db0b34SBarry Smith a->rmax = rmax; 8384e220ebcSLois Curfman McInnes 839cd6b891eSBarry Smith ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 84088e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 84171c2f376SKris Buschelman 8424108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 84371f1c65dSBarry Smith 84471f1c65dSBarry Smith a->idiagvalid = PETSC_FALSE; 8453a40ed3dSBarry Smith PetscFunctionReturn(0); 84617ab2063SBarry Smith } 84717ab2063SBarry Smith 8484a2ae208SSatish Balay #undef __FUNCT__ 84999cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 85099cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 85199cafbc1SBarry Smith { 85299cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 85399cafbc1SBarry Smith PetscInt i,nz = a->nz; 85454f21887SBarry Smith MatScalar *aa = a->a; 85599cafbc1SBarry Smith 85699cafbc1SBarry Smith PetscFunctionBegin; 85799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 85899cafbc1SBarry Smith PetscFunctionReturn(0); 85999cafbc1SBarry Smith } 86099cafbc1SBarry Smith 86199cafbc1SBarry Smith #undef __FUNCT__ 86299cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 86399cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 86499cafbc1SBarry Smith { 86599cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 86699cafbc1SBarry Smith PetscInt i,nz = a->nz; 86754f21887SBarry Smith MatScalar *aa = a->a; 86899cafbc1SBarry Smith 86999cafbc1SBarry Smith PetscFunctionBegin; 87099cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 87199cafbc1SBarry Smith PetscFunctionReturn(0); 87299cafbc1SBarry Smith } 87399cafbc1SBarry Smith 87499cafbc1SBarry Smith #undef __FUNCT__ 8754a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 876dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 87717ab2063SBarry Smith { 878416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 879dfbe8321SBarry Smith PetscErrorCode ierr; 8803a40ed3dSBarry Smith 8813a40ed3dSBarry Smith PetscFunctionBegin; 882d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 8833a40ed3dSBarry Smith PetscFunctionReturn(0); 88417ab2063SBarry Smith } 885416022c9SBarry Smith 8864a2ae208SSatish Balay #undef __FUNCT__ 8874a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 888dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 88917ab2063SBarry Smith { 890416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 891dfbe8321SBarry Smith PetscErrorCode ierr; 892d5d45c9bSBarry Smith 8933a40ed3dSBarry Smith PetscFunctionBegin; 894aa482453SBarry Smith #if defined(PETSC_USE_LOG) 895d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 89617ab2063SBarry Smith #endif 897e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 8986bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 8996bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 90005b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 90105b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 90271f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 90305b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 9046bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 90505b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 9066bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 90705b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 9086bf464f9SBarry Smith ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr); 909cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 910a30b2313SHong Zhang 9114108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 912bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 913901853e0SKris Buschelman 914dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 915901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 916901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 917901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 918901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr); 919901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 9205a11e1b2SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr); 921901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr); 922901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 923a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr); 924901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr); 9253a40ed3dSBarry Smith PetscFunctionReturn(0); 92617ab2063SBarry Smith } 92717ab2063SBarry Smith 9284a2ae208SSatish Balay #undef __FUNCT__ 9294a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 930ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 93117ab2063SBarry Smith { 932416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9334846f1f5SKris Buschelman PetscErrorCode ierr; 9343a40ed3dSBarry Smith 9353a40ed3dSBarry Smith PetscFunctionBegin; 936a65d3064SKris Buschelman switch (op) { 937a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 9384e0d8c25SBarry Smith a->roworiented = flg; 939a65d3064SKris Buschelman break; 940a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 941a9817697SBarry Smith a->keepnonzeropattern = flg; 942a65d3064SKris Buschelman break; 943512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 944512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 945a65d3064SKris Buschelman break; 946a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 9474e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 948a65d3064SKris Buschelman break; 949a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 9504e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 951a65d3064SKris Buschelman break; 95228b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 95328b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 95428b2fa4aSMatthew Knepley break; 955a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 9564e0d8c25SBarry Smith a->ignorezeroentries = flg; 9570df259c2SBarry Smith break; 958cd6b891eSBarry Smith case MAT_CHECK_COMPRESSED_ROW: 959cd6b891eSBarry Smith a->compressedrow.check = flg; 960d487561eSHong Zhang break; 9613d472b54SHong Zhang case MAT_SPD: 9623d472b54SHong Zhang A->spd_set = PETSC_TRUE; 9633d472b54SHong Zhang A->spd = flg; 9643d472b54SHong Zhang if (flg) { 9653d472b54SHong Zhang A->symmetric = PETSC_TRUE; 9663d472b54SHong Zhang A->structurally_symmetric = PETSC_TRUE; 9673d472b54SHong Zhang A->symmetric_set = PETSC_TRUE; 9683d472b54SHong Zhang A->structurally_symmetric_set = PETSC_TRUE; 9693d472b54SHong Zhang } 9703d472b54SHong Zhang break; 971b1646e73SJed Brown case MAT_SYMMETRIC: 972b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 973b1646e73SJed Brown case MAT_HERMITIAN: 974b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 9754e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 976a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 977a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 978290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 979a65d3064SKris Buschelman break; 980b87ac2d8SJed Brown case MAT_USE_INODES: 981b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 982b87ac2d8SJed Brown break; 983a65d3064SKris Buschelman default: 984e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 985a65d3064SKris Buschelman } 9864108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 9873a40ed3dSBarry Smith PetscFunctionReturn(0); 98817ab2063SBarry Smith } 98917ab2063SBarry Smith 9904a2ae208SSatish Balay #undef __FUNCT__ 9914a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 992dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 99317ab2063SBarry Smith { 994416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9956849ba73SBarry Smith PetscErrorCode ierr; 996d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 99735e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 99817ab2063SBarry Smith 9993a40ed3dSBarry Smith PetscFunctionBegin; 1000d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1001e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 100235e7444dSHong Zhang 1003d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){ 1004d3e70bfaSHong Zhang PetscInt *diag=a->diag; 100535e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 100635e7444dSHong Zhang for (i=0; i<n; i++) x[i] = aa[diag[i]]; 100735e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 100835e7444dSHong Zhang PetscFunctionReturn(0); 100935e7444dSHong Zhang } 101035e7444dSHong Zhang 10112dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 10121ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 101335e7444dSHong Zhang for (i=0; i<n; i++) { 101435e7444dSHong Zhang nz = ai[i+1] - ai[i]; 10152f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 101635e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++){ 101735e7444dSHong Zhang if (aj[j] == i) { 101835e7444dSHong Zhang x[i] = aa[j]; 101917ab2063SBarry Smith break; 102017ab2063SBarry Smith } 102117ab2063SBarry Smith } 102217ab2063SBarry Smith } 10231ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 10243a40ed3dSBarry Smith PetscFunctionReturn(0); 102517ab2063SBarry Smith } 102617ab2063SBarry Smith 1027c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 10284a2ae208SSatish Balay #undef __FUNCT__ 10294a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 1030dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 103117ab2063SBarry Smith { 1032416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10335c897100SBarry Smith PetscScalar *x,*y; 1034dfbe8321SBarry Smith PetscErrorCode ierr; 1035d0f46423SBarry Smith PetscInt m = A->rmap->n; 10365c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1037a77337e4SBarry Smith MatScalar *v; 1038a77337e4SBarry Smith PetscScalar alpha; 103904fbf559SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=PETSC_NULL; 10403447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1041ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 10425c897100SBarry Smith #endif 104317ab2063SBarry Smith 10443a40ed3dSBarry Smith PetscFunctionBegin; 10452e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 10461ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 10471ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 10485c897100SBarry Smith 10495c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1050bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 10515c897100SBarry Smith #else 10523447b6efSHong Zhang if (usecprow){ 10533447b6efSHong Zhang m = cprow.nrows; 10543447b6efSHong Zhang ii = cprow.i; 10557b2bb3b9SHong Zhang ridx = cprow.rindex; 10563447b6efSHong Zhang } else { 10573447b6efSHong Zhang ii = a->i; 10583447b6efSHong Zhang } 105917ab2063SBarry Smith for (i=0; i<m; i++) { 10603447b6efSHong Zhang idx = a->j + ii[i] ; 10613447b6efSHong Zhang v = a->a + ii[i] ; 10623447b6efSHong Zhang n = ii[i+1] - ii[i]; 10633447b6efSHong Zhang if (usecprow){ 10647b2bb3b9SHong Zhang alpha = x[ridx[i]]; 10653447b6efSHong Zhang } else { 106617ab2063SBarry Smith alpha = x[i]; 10673447b6efSHong Zhang } 106804fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 106917ab2063SBarry Smith } 10705c897100SBarry Smith #endif 1071dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 10721ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 10731ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 10743a40ed3dSBarry Smith PetscFunctionReturn(0); 107517ab2063SBarry Smith } 107617ab2063SBarry Smith 10774a2ae208SSatish Balay #undef __FUNCT__ 10785c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 1079dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 10805c897100SBarry Smith { 1081dfbe8321SBarry Smith PetscErrorCode ierr; 10825c897100SBarry Smith 10835c897100SBarry Smith PetscFunctionBegin; 1084170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 10855c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 10865c897100SBarry Smith PetscFunctionReturn(0); 10875c897100SBarry Smith } 10885c897100SBarry Smith 1089c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 10905c897100SBarry Smith #undef __FUNCT__ 10914a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 1092dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 109317ab2063SBarry Smith { 1094416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1095d9fead3dSBarry Smith PetscScalar *y; 109654f21887SBarry Smith const PetscScalar *x; 109754f21887SBarry Smith const MatScalar *aa; 1098dfbe8321SBarry Smith PetscErrorCode ierr; 1099003131ecSBarry Smith PetscInt m=A->rmap->n; 1100003131ecSBarry Smith const PetscInt *aj,*ii,*ridx=PETSC_NULL; 11018aee2decSHong Zhang PetscInt n,i,nonzerorow=0; 1102362ced78SSatish Balay PetscScalar sum; 1103ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 110417ab2063SBarry Smith 1105b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 110697952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1107fee21e36SBarry Smith #endif 1108fee21e36SBarry Smith 11093a40ed3dSBarry Smith PetscFunctionBegin; 11103649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 11111ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 111297952fefSHong Zhang aj = a->j; 111397952fefSHong Zhang aa = a->a; 1114416022c9SBarry Smith ii = a->i; 11154eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 111697952fefSHong Zhang m = a->compressedrow.nrows; 111797952fefSHong Zhang ii = a->compressedrow.i; 111897952fefSHong Zhang ridx = a->compressedrow.rindex; 111997952fefSHong Zhang for (i=0; i<m; i++){ 112097952fefSHong Zhang n = ii[i+1] - ii[i]; 112197952fefSHong Zhang aj = a->j + ii[i]; 112297952fefSHong Zhang aa = a->a + ii[i]; 112397952fefSHong Zhang sum = 0.0; 1124a46b3154SVictor Eijkhout nonzerorow += (n>0); 1125003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1126003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 112797952fefSHong Zhang y[*ridx++] = sum; 112897952fefSHong Zhang } 112997952fefSHong Zhang } else { /* do not use compressed row format */ 1130b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1131b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1132b05257ddSBarry Smith #else 113317ab2063SBarry Smith for (i=0; i<m; i++) { 1134003131ecSBarry Smith n = ii[i+1] - ii[i]; 1135003131ecSBarry Smith aj = a->j + ii[i]; 1136003131ecSBarry Smith aa = a->a + ii[i]; 113717ab2063SBarry Smith sum = 0.0; 1138a46b3154SVictor Eijkhout nonzerorow += (n>0); 1139003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 114017ab2063SBarry Smith y[i] = sum; 114117ab2063SBarry Smith } 11428d195f9aSBarry Smith #endif 1143b05257ddSBarry Smith } 1144dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 11453649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 11461ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 11473a40ed3dSBarry Smith PetscFunctionReturn(0); 114817ab2063SBarry Smith } 114917ab2063SBarry Smith 11500ca81413SKerry Stevens //******************* 11510ca81413SKerry Stevens typedef struct { 11520ca81413SKerry Stevens const MatScalar* matdata; 11530ca81413SKerry Stevens const PetscScalar* vecdata; 11540ca81413SKerry Stevens PetscScalar* vecout; 11550ca81413SKerry Stevens const PetscInt* colindnz; 11560ca81413SKerry Stevens const PetscInt* rownumnz; 11570ca81413SKerry Stevens PetscInt numrows; 11580ca81413SKerry Stevens const PetscInt* specidx; 11590ca81413SKerry Stevens PetscInt nzr; 11600ca81413SKerry Stevens } MatMult_KernelData; 116151d315f7SKerry Stevens MatMult_KernelData* kerneldatap_MatMult = NULL; 116251d315f7SKerry Stevens MatMult_KernelData** pdata_MatMult = NULL; 11630ca81413SKerry Stevens 11640ca81413SKerry Stevens void* MatMult_Kernel(void *arg) 11650ca81413SKerry Stevens { 11660ca81413SKerry Stevens MatMult_KernelData *data = (MatMult_KernelData*)arg; 11670ca81413SKerry Stevens PetscScalar sum; 11680ca81413SKerry Stevens const MatScalar *aabase = data->matdata,*aa; 11690ca81413SKerry Stevens const PetscScalar *x = data->vecdata; 11700ca81413SKerry Stevens PetscScalar *y = data->vecout; 11710ca81413SKerry Stevens const PetscInt *ajbase = data->colindnz,*aj; 11720ca81413SKerry Stevens const PetscInt *ii = data->rownumnz; 11730ca81413SKerry Stevens PetscInt m = data->numrows; 11740ca81413SKerry Stevens const PetscInt *ridx = data->specidx; 11750ca81413SKerry Stevens PetscInt i,n,nonzerorow = 0; 11760ca81413SKerry Stevens 11770ca81413SKerry Stevens if(ridx!=NULL) { 11780ca81413SKerry Stevens for (i=0; i<m; i++){ 11790ca81413SKerry Stevens n = ii[i+1] - ii[i]; 11800ca81413SKerry Stevens aj = ajbase + ii[i]; 11810ca81413SKerry Stevens aa = aabase + ii[i]; 11820ca81413SKerry Stevens sum = 0.0; 118351d315f7SKerry Stevens /*if(n>0) { 118451d315f7SKerry Stevens PetscSparseDensePlusDot(sum,x,aa,aj,n); 118551d315f7SKerry Stevens nonzerorow++; 118651d315f7SKerry Stevens }*/ 11870ca81413SKerry Stevens nonzerorow += (n>0); 11880ca81413SKerry Stevens PetscSparseDensePlusDot(sum,x,aa,aj,n); 11890ca81413SKerry Stevens y[*ridx++] = sum; 11900ca81413SKerry Stevens } 11910ca81413SKerry Stevens } 11920ca81413SKerry Stevens else { 119351d315f7SKerry Stevens PetscInt ibase = data->nzr; 11940ca81413SKerry Stevens for (i=0; i<m; i++) { 11950ca81413SKerry Stevens n = ii[i+1] - ii[i]; 11960ca81413SKerry Stevens aj = ajbase + ii[i]; 11970ca81413SKerry Stevens aa = aabase + ii[i]; 11980ca81413SKerry Stevens sum = 0.0; 119951d315f7SKerry Stevens /*if(n>0) { 120051d315f7SKerry Stevens PetscSparseDensePlusDot(sum,x,aa,aj,n); 120151d315f7SKerry Stevens nonzerorow++; 120251d315f7SKerry Stevens }*/ 12030ca81413SKerry Stevens nonzerorow += (n>0); 12040ca81413SKerry Stevens PetscSparseDensePlusDot(sum,x,aa,aj,n); 120551d315f7SKerry Stevens y[i+ibase] = sum; 12060ca81413SKerry Stevens } 12070ca81413SKerry Stevens } 12080ca81413SKerry Stevens data->nzr = nonzerorow; 12090ca81413SKerry Stevens return NULL; 12100ca81413SKerry Stevens } 12110ca81413SKerry Stevens 1212*ff34cdc8SBarry Smith #if defined(PETSC_HAVE_PTHREADCLASSES) 12130ca81413SKerry Stevens extern PetscMPIInt PetscMaxThreads; 12149e800a48SKerry Stevens PetscErrorCode (*MainJob)(void* (*pFunc)(void*),void**,PetscInt); 121551d315f7SKerry Stevens 12160ca81413SKerry Stevens #undef __FUNCT__ 121751d315f7SKerry Stevens #define __FUNCT__ "MatMult_SeqPThreadAIJ" 121851d315f7SKerry Stevens PetscErrorCode MatMult_SeqPThreadAIJ(Mat A,Vec xx,Vec yy) 12190ca81413SKerry Stevens { 12200ca81413SKerry Stevens Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12210ca81413SKerry Stevens PetscScalar *y; 12220ca81413SKerry Stevens const PetscScalar *x; 12230ca81413SKerry Stevens PetscErrorCode ierr; 12240ca81413SKerry Stevens PetscInt m=A->rmap->n,nonzerorow=0; 12250ca81413SKerry Stevens PetscBool usecprow=a->compressedrow.use; 12260ca81413SKerry Stevens 12270ca81413SKerry Stevens #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 12280ca81413SKerry Stevens #pragma disjoint(*x,*y,*aa) 12290ca81413SKerry Stevens #endif 12300ca81413SKerry Stevens 12310ca81413SKerry Stevens PetscFunctionBegin; 12320ca81413SKerry Stevens ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12330ca81413SKerry Stevens ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 12340ca81413SKerry Stevens 12350ca81413SKerry Stevens if(usecprow) { 12360ca81413SKerry Stevens PetscInt NumPerThread,iindex; 12370ca81413SKerry Stevens const MatScalar *aa = a->a; 12380ca81413SKerry Stevens const PetscInt *aj = a->j,*ii = a->compressedrow.i,*ridx=a->compressedrow.rindex; 12390ca81413SKerry Stevens PetscInt i,iStartVal,iEndVal,iStartIndex,iEndIndex; 12400ca81413SKerry Stevens const PetscInt iNumThreads = PetscMaxThreads; //this number could be different 124151d315f7SKerry Stevens //MatMult_KernelData* kerneldatap = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData)); 124251d315f7SKerry Stevens //MatMult_KernelData** pdata = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*)); 124351d315f7SKerry Stevens 124451d315f7SKerry Stevens if(kerneldatap_MatMult==NULL) { 124551d315f7SKerry Stevens //only need to check 1 of them 124651d315f7SKerry Stevens kerneldatap_MatMult = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData)); 124751d315f7SKerry Stevens pdata_MatMult = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*)); 124851d315f7SKerry Stevens for(i=0; i<iNumThreads; i++) { 124951d315f7SKerry Stevens pdata_MatMult[i] = &kerneldatap_MatMult[i]; 125051d315f7SKerry Stevens } 125151d315f7SKerry Stevens } 12520ca81413SKerry Stevens 12530ca81413SKerry Stevens m = a->compressedrow.nrows; 12540ca81413SKerry Stevens NumPerThread = ii[m]/iNumThreads; 12550ca81413SKerry Stevens iindex = 0; 12560ca81413SKerry Stevens for(i=0; i<iNumThreads;i++) { 12570ca81413SKerry Stevens iStartIndex = iindex; 12580ca81413SKerry Stevens iStartVal = ii[iStartIndex]; 12590ca81413SKerry Stevens iEndVal = iStartVal; 12600ca81413SKerry Stevens //determine number of rows to process 12610ca81413SKerry Stevens while(iEndVal-iStartVal<NumPerThread) { 12620ca81413SKerry Stevens iindex++; 12630ca81413SKerry Stevens iEndVal = ii[iindex]; 12640ca81413SKerry Stevens } 12650ca81413SKerry Stevens //determine whether to go back 1 12660ca81413SKerry Stevens if(iEndVal-iStartVal-NumPerThread>NumPerThread-(ii[iindex-1]-iStartVal)) { 12670ca81413SKerry Stevens iindex--; 12680ca81413SKerry Stevens iEndVal = ii[iindex]; 12690ca81413SKerry Stevens } 12700ca81413SKerry Stevens iEndIndex = iindex; 127151d315f7SKerry Stevens /*kerneldatap[i].matdata = aa; 12720ca81413SKerry Stevens kerneldatap[i].vecdata = x; 12730ca81413SKerry Stevens kerneldatap[i].vecout = y; 12740ca81413SKerry Stevens kerneldatap[i].colindnz = aj; 12750ca81413SKerry Stevens kerneldatap[i].rownumnz = ii + iStartIndex; 12760ca81413SKerry Stevens kerneldatap[i].numrows = iEndIndex - iStartIndex + 1; 12770ca81413SKerry Stevens kerneldatap[i].specidx = ridx + iStartVal; 12780ca81413SKerry Stevens kerneldatap[i].nzr = 0; 127951d315f7SKerry Stevens pdata[i] = &kerneldatap[i];*/ 128051d315f7SKerry Stevens kerneldatap_MatMult[i].matdata = aa; 128151d315f7SKerry Stevens kerneldatap_MatMult[i].vecdata = x; 128251d315f7SKerry Stevens kerneldatap_MatMult[i].vecout = y; 128351d315f7SKerry Stevens kerneldatap_MatMult[i].colindnz = aj; 128451d315f7SKerry Stevens kerneldatap_MatMult[i].rownumnz = ii + iStartIndex; 128551d315f7SKerry Stevens kerneldatap_MatMult[i].numrows = iEndIndex - iStartIndex + 1; 128651d315f7SKerry Stevens kerneldatap_MatMult[i].specidx = ridx + iStartVal; 128751d315f7SKerry Stevens kerneldatap_MatMult[i].nzr = 0; 12880ca81413SKerry Stevens iindex++; 12890ca81413SKerry Stevens } 129051d315f7SKerry Stevens //ierr = MainJob(MatMult_Kernel,(void**)pdata,iNumThreads); 129151d315f7SKerry Stevens ierr = MainJob(MatMult_Kernel,(void**)pdata_MatMult,iNumThreads); 129251d315f7SKerry Stevens //collect results 129351d315f7SKerry Stevens for(i=0; i<iNumThreads; i++) { 129451d315f7SKerry Stevens //nonzerorow += kerneldatap[i].nzr; 129551d315f7SKerry Stevens nonzerorow += kerneldatap_MatMult[i].nzr; 129651d315f7SKerry Stevens } 129751d315f7SKerry Stevens //free(kerneldatap); 129851d315f7SKerry Stevens //free(pdata); 129951d315f7SKerry Stevens } 130051d315f7SKerry Stevens else { 130151d315f7SKerry Stevens #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 130251d315f7SKerry Stevens fortranmultaij_(&m,x,a->i,a->j,a->a,y); 130351d315f7SKerry Stevens #else 130451d315f7SKerry Stevens PetscInt i,iindex; 130551d315f7SKerry Stevens const MatScalar *aa = a->a; 130651d315f7SKerry Stevens const PetscInt *aj = a->j,*ii = a->i; 130751d315f7SKerry Stevens const PetscInt iNumThreads = PetscMaxThreads; //this number could be different 130851d315f7SKerry Stevens PetscInt Q = m/iNumThreads; 130951d315f7SKerry Stevens PetscInt R = m-Q*iNumThreads; 131051d315f7SKerry Stevens PetscBool S; 131151d315f7SKerry Stevens 131251d315f7SKerry Stevens MatMult_KernelData* kerneldatap = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData)); 131351d315f7SKerry Stevens MatMult_KernelData** pdata = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*)); 131451d315f7SKerry Stevens 131551d315f7SKerry Stevens iindex = 0; 131651d315f7SKerry Stevens for(i=0; i<iNumThreads;i++) { 131751d315f7SKerry Stevens S = i<R; 131851d315f7SKerry Stevens kerneldatap[i].matdata = aa; 131951d315f7SKerry Stevens kerneldatap[i].vecdata = x; 132051d315f7SKerry Stevens kerneldatap[i].vecout = y; 132151d315f7SKerry Stevens kerneldatap[i].colindnz = aj; 132251d315f7SKerry Stevens kerneldatap[i].rownumnz = ii + iindex; 132351d315f7SKerry Stevens kerneldatap[i].numrows = S?Q+1:Q; 132451d315f7SKerry Stevens kerneldatap[i].specidx = PETSC_NULL; 132551d315f7SKerry Stevens kerneldatap[i].nzr = iindex; //serves as the 'base' row (needed to access correctly into output vector y) 132651d315f7SKerry Stevens pdata[i] = &kerneldatap[i]; 132751d315f7SKerry Stevens iindex += kerneldatap[i].numrows; 132851d315f7SKerry Stevens } 13290ca81413SKerry Stevens MainJob(MatMult_Kernel,(void**)pdata,iNumThreads); 13300ca81413SKerry Stevens //collect results 13310ca81413SKerry Stevens for(i=0; i<iNumThreads; i++) { 13320ca81413SKerry Stevens nonzerorow += kerneldatap[i].nzr; 13330ca81413SKerry Stevens } 133451d315f7SKerry Stevens free(kerneldatap); 133551d315f7SKerry Stevens free(pdata); 133651d315f7SKerry Stevens /*if(kerneldatap_MatMult==NULL) { 133751d315f7SKerry Stevens //only need to check 1 of them 133851d315f7SKerry Stevens kerneldatap_MatMult = (MatMult_KernelData*)malloc(iNumThreads*sizeof(MatMult_KernelData)); 133951d315f7SKerry Stevens pdata_MatMult = (MatMult_KernelData**)malloc(iNumThreads*sizeof(MatMult_KernelData*)); 134051d315f7SKerry Stevens for(i=0; i<iNumThreads; i++) { 134151d315f7SKerry Stevens pdata_MatMult[i] = &kerneldatap_MatMult[i]; 13420ca81413SKerry Stevens } 134351d315f7SKerry Stevens } 13440ca81413SKerry Stevens 13450ca81413SKerry Stevens NumPerThread = ii[m]/iNumThreads; 13460ca81413SKerry Stevens iindex = 0; 13470ca81413SKerry Stevens for(i=0; i<iNumThreads;i++) { 13480ca81413SKerry Stevens iStartIndex = iindex; 13490ca81413SKerry Stevens iStartVal = ii[iStartIndex]; 13500ca81413SKerry Stevens iEndVal = iStartVal; 13510ca81413SKerry Stevens //determine number of rows to process 13520ca81413SKerry Stevens while(iEndVal-iStartVal<NumPerThread) { 13530ca81413SKerry Stevens iindex++; 13540ca81413SKerry Stevens iEndVal = ii[iindex]; 13550ca81413SKerry Stevens } 13560ca81413SKerry Stevens //determine whether to go back 1 13570ca81413SKerry Stevens if(iEndVal-iStartVal-NumPerThread>NumPerThread-(ii[iindex-1]-iStartVal)) { 13580ca81413SKerry Stevens iindex--; 13590ca81413SKerry Stevens iEndVal = ii[iindex]; 13600ca81413SKerry Stevens } 136151d315f7SKerry Stevens iindex--; //needed b/c ii[k] gives # nonzero elements of rows 0 through k-1 13620ca81413SKerry Stevens iEndIndex = iindex; 136351d315f7SKerry Stevens kerneldatap_MatMult[i].matdata = aa; 136451d315f7SKerry Stevens kerneldatap_MatMult[i].vecdata = x; 136551d315f7SKerry Stevens kerneldatap_MatMult[i].vecout = y; 136651d315f7SKerry Stevens kerneldatap_MatMult[i].colindnz = aj; 136751d315f7SKerry Stevens kerneldatap_MatMult[i].rownumnz = ii + iStartIndex; 136851d315f7SKerry Stevens kerneldatap_MatMult[i].numrows = iEndIndex - iStartIndex + 1; 136951d315f7SKerry Stevens kerneldatap_MatMult[i].specidx = PETSC_NULL; 137051d315f7SKerry Stevens kerneldatap_MatMult[i].nzr = iStartIndex; 13710ca81413SKerry Stevens iindex++; 13720ca81413SKerry Stevens } 137351d315f7SKerry Stevens MainJob(MatMult_Kernel,(void**)pdata_MatMult,iNumThreads); 13740ca81413SKerry Stevens //collect results 13750ca81413SKerry Stevens for(i=0; i<iNumThreads; i++) { 137651d315f7SKerry Stevens nonzerorow += kerneldatap_MatMult[i].nzr; 137751d315f7SKerry Stevens }*/ 13780ca81413SKerry Stevens #endif 13790ca81413SKerry Stevens } 13800ca81413SKerry Stevens 13810ca81413SKerry Stevens ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 13820ca81413SKerry Stevens ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 13830ca81413SKerry Stevens ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 13840ca81413SKerry Stevens PetscFunctionReturn(0); 13850ca81413SKerry Stevens } 13860ca81413SKerry Stevens //******************* 1387ba61063dSBarry Smith #endif 13880ca81413SKerry Stevens 1389c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 13904a2ae208SSatish Balay #undef __FUNCT__ 13914a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1392dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 139317ab2063SBarry Smith { 1394416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1395f15663dcSBarry Smith PetscScalar *y,*z; 1396f15663dcSBarry Smith const PetscScalar *x; 139754f21887SBarry Smith const MatScalar *aa; 1398dfbe8321SBarry Smith PetscErrorCode ierr; 1399d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 1400f15663dcSBarry Smith PetscInt n,i,*ridx=PETSC_NULL; 1401362ced78SSatish Balay PetscScalar sum; 1402ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 14039ea0dfa2SSatish Balay 14043a40ed3dSBarry Smith PetscFunctionBegin; 1405f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 14061ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14072e8a6d31SBarry Smith if (zz != yy) { 14081ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 14092e8a6d31SBarry Smith } else { 14102e8a6d31SBarry Smith z = y; 14112e8a6d31SBarry Smith } 1412bfeeae90SHong Zhang 141397952fefSHong Zhang aj = a->j; 141497952fefSHong Zhang aa = a->a; 1415cddf8d76SBarry Smith ii = a->i; 14164eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 14174eb6d288SHong Zhang if (zz != yy){ 14184eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 14194eb6d288SHong Zhang } 142097952fefSHong Zhang m = a->compressedrow.nrows; 142197952fefSHong Zhang ii = a->compressedrow.i; 142297952fefSHong Zhang ridx = a->compressedrow.rindex; 142397952fefSHong Zhang for (i=0; i<m; i++){ 142497952fefSHong Zhang n = ii[i+1] - ii[i]; 142597952fefSHong Zhang aj = a->j + ii[i]; 142697952fefSHong Zhang aa = a->a + ii[i]; 142797952fefSHong Zhang sum = y[*ridx]; 1428f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 142997952fefSHong Zhang z[*ridx++] = sum; 143097952fefSHong Zhang } 143197952fefSHong Zhang } else { /* do not use compressed row format */ 1432f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1433f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1434f15663dcSBarry Smith #else 143517ab2063SBarry Smith for (i=0; i<m; i++) { 1436f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1437f15663dcSBarry Smith aj = a->j + ii[i]; 1438f15663dcSBarry Smith aa = a->a + ii[i]; 143917ab2063SBarry Smith sum = y[i]; 1440f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 144117ab2063SBarry Smith z[i] = sum; 144217ab2063SBarry Smith } 144302ab625aSSatish Balay #endif 1444f15663dcSBarry Smith } 1445dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1446f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 14471ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14482e8a6d31SBarry Smith if (zz != yy) { 14491ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 14502e8a6d31SBarry Smith } 14518154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14526b375ea7SVictor Minden /* 1453918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1454918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1455918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14566b375ea7SVictor Minden */ 1457918e98c3SVictor Minden #endif 14583a40ed3dSBarry Smith PetscFunctionReturn(0); 145917ab2063SBarry Smith } 146017ab2063SBarry Smith 146117ab2063SBarry Smith /* 146217ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 146317ab2063SBarry Smith */ 14644a2ae208SSatish Balay #undef __FUNCT__ 14654a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1466dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 146717ab2063SBarry Smith { 1468416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14696849ba73SBarry Smith PetscErrorCode ierr; 1470d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 147117ab2063SBarry Smith 14723a40ed3dSBarry Smith PetscFunctionBegin; 147309f38230SBarry Smith if (!a->diag) { 147409f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 14759518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr); 147609f38230SBarry Smith } 1477d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 147809f38230SBarry Smith a->diag[i] = a->i[i+1]; 1479bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1480bfeeae90SHong Zhang if (a->j[j] == i) { 148109f38230SBarry Smith a->diag[i] = j; 148217ab2063SBarry Smith break; 148317ab2063SBarry Smith } 148417ab2063SBarry Smith } 148517ab2063SBarry Smith } 14863a40ed3dSBarry Smith PetscFunctionReturn(0); 148717ab2063SBarry Smith } 148817ab2063SBarry Smith 1489be5855fcSBarry Smith /* 1490be5855fcSBarry Smith Checks for missing diagonals 1491be5855fcSBarry Smith */ 14924a2ae208SSatish Balay #undef __FUNCT__ 14934a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1494ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1495be5855fcSBarry Smith { 1496be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 149797f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1498be5855fcSBarry Smith 1499be5855fcSBarry Smith PetscFunctionBegin; 150009f38230SBarry Smith *missing = PETSC_FALSE; 1501d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 150209f38230SBarry Smith *missing = PETSC_TRUE; 150309f38230SBarry Smith if (d) *d = 0; 150409f38230SBarry Smith PetscInfo(A,"Matrix has no entries therefor is missing diagonal"); 150509f38230SBarry Smith } else { 1506f1e2ffcdSBarry Smith diag = a->diag; 1507d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1508bfeeae90SHong Zhang if (jj[diag[i]] != i) { 150909f38230SBarry Smith *missing = PETSC_TRUE; 151009f38230SBarry Smith if (d) *d = i; 151109f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 151209f38230SBarry Smith } 1513be5855fcSBarry Smith } 1514be5855fcSBarry Smith } 1515be5855fcSBarry Smith PetscFunctionReturn(0); 1516be5855fcSBarry Smith } 1517be5855fcSBarry Smith 151871f1c65dSBarry Smith EXTERN_C_BEGIN 151971f1c65dSBarry Smith #undef __FUNCT__ 152071f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 15217087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 152271f1c65dSBarry Smith { 152371f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 152471f1c65dSBarry Smith PetscErrorCode ierr; 1525d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 152654f21887SBarry Smith MatScalar *v = a->a; 152754f21887SBarry Smith PetscScalar *idiag,*mdiag; 152871f1c65dSBarry Smith 152971f1c65dSBarry Smith PetscFunctionBegin; 153071f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 153171f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 153271f1c65dSBarry Smith diag = a->diag; 153371f1c65dSBarry Smith if (!a->idiag) { 153471f1c65dSBarry Smith ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr); 153571f1c65dSBarry Smith ierr = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 153671f1c65dSBarry Smith v = a->a; 153771f1c65dSBarry Smith } 153871f1c65dSBarry Smith mdiag = a->mdiag; 153971f1c65dSBarry Smith idiag = a->idiag; 154071f1c65dSBarry Smith 1541028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 154271f1c65dSBarry Smith for (i=0; i<m; i++) { 154371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1544e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 154571f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 154671f1c65dSBarry Smith } 154771f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 154871f1c65dSBarry Smith } else { 154971f1c65dSBarry Smith for (i=0; i<m; i++) { 155071f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 155171f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 155271f1c65dSBarry Smith } 1553dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 155471f1c65dSBarry Smith } 155571f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 155671f1c65dSBarry Smith PetscFunctionReturn(0); 155771f1c65dSBarry Smith } 15585a9745a3SMatthew Knepley EXTERN_C_END 155971f1c65dSBarry Smith 1560c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 15614a2ae208SSatish Balay #undef __FUNCT__ 156241f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 156341f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 156417ab2063SBarry Smith { 1565416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1566e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1567e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 156854f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1569dfbe8321SBarry Smith PetscErrorCode ierr; 1570d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 157197f1f81fSBarry Smith const PetscInt *idx,*diag; 157217ab2063SBarry Smith 15733a40ed3dSBarry Smith PetscFunctionBegin; 1574b965ef7fSBarry Smith its = its*lits; 157591723122SBarry Smith 157671f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 157771f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 157871f1c65dSBarry Smith a->fshift = fshift; 157971f1c65dSBarry Smith a->omega = omega; 1580ed480e8bSBarry Smith 158171f1c65dSBarry Smith diag = a->diag; 158271f1c65dSBarry Smith t = a->ssor_work; 1583ed480e8bSBarry Smith idiag = a->idiag; 158471f1c65dSBarry Smith mdiag = a->mdiag; 1585ed480e8bSBarry Smith 15861ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 15873649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 158871f1c65dSBarry Smith CHKMEMQ; 1589ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 159017ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 159117ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1592ed480e8bSBarry Smith bs = b; 159317ab2063SBarry Smith for (i=0; i<m; i++) { 159471f1c65dSBarry Smith d = fshift + mdiag[i]; 1595416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1596ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1597ed480e8bSBarry Smith v = a->a + diag[i] + 1; 159817ab2063SBarry Smith sum = b[i]*d/omega; 1599003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 160017ab2063SBarry Smith x[i] = sum; 160117ab2063SBarry Smith } 16021ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16033649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1604efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16053a40ed3dSBarry Smith PetscFunctionReturn(0); 160617ab2063SBarry Smith } 1607c783ea89SBarry Smith 160848af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 1609e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 16103a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 161117ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1612887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 161317ab2063SBarry Smith 161417ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 161517ab2063SBarry Smith 1616887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 161717ab2063SBarry Smith */ 161817ab2063SBarry Smith scale = (2.0/omega) - 1.0; 161917ab2063SBarry Smith 162017ab2063SBarry Smith /* x = (E + U)^{-1} b */ 162117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1622416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1623ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1624ed480e8bSBarry Smith v = a->a + diag[i] + 1; 162517ab2063SBarry Smith sum = b[i]; 1626e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1627ed480e8bSBarry Smith x[i] = sum*idiag[i]; 162817ab2063SBarry Smith } 162917ab2063SBarry Smith 163017ab2063SBarry Smith /* t = b - (2*E - D)x */ 1631416022c9SBarry Smith v = a->a; 1632ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 163317ab2063SBarry Smith 163417ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1635ed480e8bSBarry Smith ts = t; 1636416022c9SBarry Smith diag = a->diag; 163717ab2063SBarry Smith for (i=0; i<m; i++) { 1638416022c9SBarry Smith n = diag[i] - a->i[i]; 1639ed480e8bSBarry Smith idx = a->j + a->i[i]; 1640ed480e8bSBarry Smith v = a->a + a->i[i]; 164117ab2063SBarry Smith sum = t[i]; 1642003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1643ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1644733d66baSBarry Smith /* x = x + t */ 1645733d66baSBarry Smith x[i] += t[i]; 164617ab2063SBarry Smith } 164717ab2063SBarry Smith 1648dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16491ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16503649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16513a40ed3dSBarry Smith PetscFunctionReturn(0); 165217ab2063SBarry Smith } 165317ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 165417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 165517ab2063SBarry Smith for (i=0; i<m; i++) { 1656416022c9SBarry Smith n = diag[i] - a->i[i]; 1657ed480e8bSBarry Smith idx = a->j + a->i[i]; 1658ed480e8bSBarry Smith v = a->a + a->i[i]; 165917ab2063SBarry Smith sum = b[i]; 1660e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16615c99c7daSBarry Smith t[i] = sum; 1662ed480e8bSBarry Smith x[i] = sum*idiag[i]; 166317ab2063SBarry Smith } 16645c99c7daSBarry Smith xb = t; 1665efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16663a40ed3dSBarry Smith } else xb = b; 166717ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 166817ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1669416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1670ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1671ed480e8bSBarry Smith v = a->a + diag[i] + 1; 167217ab2063SBarry Smith sum = xb[i]; 1673e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16745c99c7daSBarry Smith if (xb == b) { 1675ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16765c99c7daSBarry Smith } else { 16775c99c7daSBarry Smith x[i] = (1-omega)*x[i] + sum*idiag[i]; 167817ab2063SBarry Smith } 16795c99c7daSBarry Smith } 1680efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 168117ab2063SBarry Smith } 168217ab2063SBarry Smith its--; 168317ab2063SBarry Smith } 168417ab2063SBarry Smith while (its--) { 168517ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 168617ab2063SBarry Smith for (i=0; i<m; i++) { 1687416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1688ed480e8bSBarry Smith idx = a->j + a->i[i]; 1689ed480e8bSBarry Smith v = a->a + a->i[i]; 169017ab2063SBarry Smith sum = b[i]; 1691e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1692ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 169317ab2063SBarry Smith } 16949f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 169517ab2063SBarry Smith } 169617ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 169717ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1698416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1699ed480e8bSBarry Smith idx = a->j + a->i[i]; 1700ed480e8bSBarry Smith v = a->a + a->i[i]; 170117ab2063SBarry Smith sum = b[i]; 1702e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1703ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 170417ab2063SBarry Smith } 17059f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 170617ab2063SBarry Smith } 170717ab2063SBarry Smith } 17081ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17093649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 171071f1c65dSBarry Smith CHKMEMQ; PetscFunctionReturn(0); 171117ab2063SBarry Smith } 171217ab2063SBarry Smith 17132af78befSBarry Smith 17144a2ae208SSatish Balay #undef __FUNCT__ 17154a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1716dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 171717ab2063SBarry Smith { 1718416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17194e220ebcSLois Curfman McInnes 17203a40ed3dSBarry Smith PetscFunctionBegin; 17214e220ebcSLois Curfman McInnes info->block_size = 1.0; 17224e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17234e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17244e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17254e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17268e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17277adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1728d5f3da31SBarry Smith if (A->factortype) { 17294e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17304e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17314e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17324e220ebcSLois Curfman McInnes } else { 17334e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17344e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17354e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17364e220ebcSLois Curfman McInnes } 17373a40ed3dSBarry Smith PetscFunctionReturn(0); 173817ab2063SBarry Smith } 173917ab2063SBarry Smith 17404a2ae208SSatish Balay #undef __FUNCT__ 17414a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 17422b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 174317ab2063SBarry Smith { 1744416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17453b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 17466849ba73SBarry Smith PetscErrorCode ierr; 174797b48c8fSBarry Smith const PetscScalar *xx; 174897b48c8fSBarry Smith PetscScalar *bb; 1749ace3abfcSBarry Smith PetscBool missing; 175017ab2063SBarry Smith 17513a40ed3dSBarry Smith PetscFunctionBegin; 175297b48c8fSBarry Smith if (x && b) { 175397b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 175497b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 175597b48c8fSBarry Smith for (i=0; i<N; i++) { 175697b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 175797b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 175897b48c8fSBarry Smith } 175997b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 176097b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 176197b48c8fSBarry Smith } 176297b48c8fSBarry Smith 1763a9817697SBarry Smith if (a->keepnonzeropattern) { 1764f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1765e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1766bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1767f1e2ffcdSBarry Smith } 1768f4df32b1SMatthew Knepley if (diag != 0.0) { 176909f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1770e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1771f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1772f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1773f1e2ffcdSBarry Smith } 1774f1e2ffcdSBarry Smith } 177588e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1776f1e2ffcdSBarry Smith } else { 1777f4df32b1SMatthew Knepley if (diag != 0.0) { 177817ab2063SBarry Smith for (i=0; i<N; i++) { 1779e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 17807ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1781416022c9SBarry Smith a->ilen[rows[i]] = 1; 1782f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1783bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 17847ae801bdSBarry Smith } else { /* in case row was completely empty */ 1785f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 178617ab2063SBarry Smith } 178717ab2063SBarry Smith } 17883a40ed3dSBarry Smith } else { 178917ab2063SBarry Smith for (i=0; i<N; i++) { 1790e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1791416022c9SBarry Smith a->ilen[rows[i]] = 0; 179217ab2063SBarry Smith } 179317ab2063SBarry Smith } 179488e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1795f1e2ffcdSBarry Smith } 179643a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17973a40ed3dSBarry Smith PetscFunctionReturn(0); 179817ab2063SBarry Smith } 179917ab2063SBarry Smith 18004a2ae208SSatish Balay #undef __FUNCT__ 18016e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 18026e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 18036e169961SBarry Smith { 18046e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18056e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18066e169961SBarry Smith PetscErrorCode ierr; 18072b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18086e169961SBarry Smith const PetscScalar *xx; 18096e169961SBarry Smith PetscScalar *bb; 18106e169961SBarry Smith 18116e169961SBarry Smith PetscFunctionBegin; 18126e169961SBarry Smith if (x && b) { 18136e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18146e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18152b40b63fSBarry Smith vecs = PETSC_TRUE; 18166e169961SBarry Smith } 18176e169961SBarry Smith ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr); 18186e169961SBarry Smith ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 18196e169961SBarry Smith for (i=0; i<N; i++) { 18206e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18216e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18226e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18236e169961SBarry Smith } 18246e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18256e169961SBarry Smith if (!zeroed[i]) { 18266e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18276e169961SBarry Smith if (zeroed[a->j[j]]) { 18282b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18296e169961SBarry Smith a->a[j] = 0.0; 18306e169961SBarry Smith } 18316e169961SBarry Smith } 18322b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18336e169961SBarry Smith } 18346e169961SBarry Smith if (x && b) { 18356e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18366e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18376e169961SBarry Smith } 18386e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18396e169961SBarry Smith if (diag != 0.0) { 18406e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18416e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18426e169961SBarry Smith for (i=0; i<N; i++) { 18436e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18446e169961SBarry Smith } 18456e169961SBarry Smith } 18466e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 18476e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18486e169961SBarry Smith PetscFunctionReturn(0); 18496e169961SBarry Smith } 18506e169961SBarry Smith 18516e169961SBarry Smith #undef __FUNCT__ 18524a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1853a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 185417ab2063SBarry Smith { 1855416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 185697f1f81fSBarry Smith PetscInt *itmp; 185717ab2063SBarry Smith 18583a40ed3dSBarry Smith PetscFunctionBegin; 1859e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 186017ab2063SBarry Smith 1861416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1862bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 186317ab2063SBarry Smith if (idx) { 1864bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1865bfeeae90SHong Zhang if (*nz) { 18664e093b46SBarry Smith *idx = itmp; 186717ab2063SBarry Smith } 186817ab2063SBarry Smith else *idx = 0; 186917ab2063SBarry Smith } 18703a40ed3dSBarry Smith PetscFunctionReturn(0); 187117ab2063SBarry Smith } 187217ab2063SBarry Smith 1873bfeeae90SHong Zhang /* remove this function? */ 18744a2ae208SSatish Balay #undef __FUNCT__ 18754a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1876a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 187717ab2063SBarry Smith { 18783a40ed3dSBarry Smith PetscFunctionBegin; 18793a40ed3dSBarry Smith PetscFunctionReturn(0); 188017ab2063SBarry Smith } 188117ab2063SBarry Smith 18824a2ae208SSatish Balay #undef __FUNCT__ 18834a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1884dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 188517ab2063SBarry Smith { 1886416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 188754f21887SBarry Smith MatScalar *v = a->a; 188836db0b34SBarry Smith PetscReal sum = 0.0; 18896849ba73SBarry Smith PetscErrorCode ierr; 189097f1f81fSBarry Smith PetscInt i,j; 189117ab2063SBarry Smith 18923a40ed3dSBarry Smith PetscFunctionBegin; 189317ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1894416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1895aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 189636db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 189717ab2063SBarry Smith #else 189817ab2063SBarry Smith sum += (*v)*(*v); v++; 189917ab2063SBarry Smith #endif 190017ab2063SBarry Smith } 1901064f8208SBarry Smith *nrm = sqrt(sum); 19023a40ed3dSBarry Smith } else if (type == NORM_1) { 190336db0b34SBarry Smith PetscReal *tmp; 190497f1f81fSBarry Smith PetscInt *jj = a->j; 1905d0f46423SBarry Smith ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1906d0f46423SBarry Smith ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr); 1907064f8208SBarry Smith *nrm = 0.0; 1908416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1909bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 191017ab2063SBarry Smith } 1911d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1912064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 191317ab2063SBarry Smith } 1914606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 19153a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1916064f8208SBarry Smith *nrm = 0.0; 1917d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1918bfeeae90SHong Zhang v = a->a + a->i[j]; 191917ab2063SBarry Smith sum = 0.0; 1920416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1921cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 192217ab2063SBarry Smith } 1923064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 192417ab2063SBarry Smith } 19253a40ed3dSBarry Smith } else { 1926e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 192717ab2063SBarry Smith } 19283a40ed3dSBarry Smith PetscFunctionReturn(0); 192917ab2063SBarry Smith } 193017ab2063SBarry Smith 19314a2ae208SSatish Balay #undef __FUNCT__ 19324a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1933fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 193417ab2063SBarry Smith { 1935416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1936416022c9SBarry Smith Mat C; 19376849ba73SBarry Smith PetscErrorCode ierr; 1938d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 193954f21887SBarry Smith MatScalar *array = a->a; 194017ab2063SBarry Smith 19413a40ed3dSBarry Smith PetscFunctionBegin; 1942e32f2f54SBarry Smith if (reuse == MAT_REUSE_MATRIX && A == *B && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 1943fc4dec0aSBarry Smith 1944fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 1945d0f46423SBarry Smith ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 1946d0f46423SBarry Smith ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr); 1947bfeeae90SHong Zhang 1948bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 19497adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1950d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 19517adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1952ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1953606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 1954a541d17aSBarry Smith } else { 1955a541d17aSBarry Smith C = *B; 1956a541d17aSBarry Smith } 1957a541d17aSBarry Smith 195817ab2063SBarry Smith for (i=0; i<m; i++) { 195917ab2063SBarry Smith len = ai[i+1]-ai[i]; 196087d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1961b9b97703SBarry Smith array += len; 1962b9b97703SBarry Smith aj += len; 196317ab2063SBarry Smith } 19646d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19656d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 196617ab2063SBarry Smith 1967815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 1968416022c9SBarry Smith *B = C; 196917ab2063SBarry Smith } else { 1970eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 197117ab2063SBarry Smith } 19723a40ed3dSBarry Smith PetscFunctionReturn(0); 197317ab2063SBarry Smith } 197417ab2063SBarry Smith 1975cd0d46ebSvictorle EXTERN_C_BEGIN 1976cd0d46ebSvictorle #undef __FUNCT__ 19775fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 19787087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 1979cd0d46ebSvictorle { 1980cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 198154f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 198254f21887SBarry Smith MatScalar *va,*vb; 19836849ba73SBarry Smith PetscErrorCode ierr; 198497f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1985cd0d46ebSvictorle 1986cd0d46ebSvictorle PetscFunctionBegin; 1987cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1988cd0d46ebSvictorle 1989cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1990cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 19915485867bSBarry Smith if (ma!=nb || na!=mb){ 19925485867bSBarry Smith *f = PETSC_FALSE; 19935485867bSBarry Smith PetscFunctionReturn(0); 19945485867bSBarry Smith } 1995cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1996cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1997cd0d46ebSvictorle va = aij->a; vb = bij->a; 199897f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 199997f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 2000cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2001cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2002cd0d46ebSvictorle 2003cd0d46ebSvictorle *f = PETSC_TRUE; 2004cd0d46ebSvictorle for (i=0; i<ma; i++) { 2005cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 200697f1f81fSBarry Smith PetscInt idc,idr; 20075485867bSBarry Smith PetscScalar vc,vr; 2008cd0d46ebSvictorle /* column/row index/value */ 20095485867bSBarry Smith idc = adx[aptr[i]]; 20105485867bSBarry Smith idr = bdx[bptr[idc]]; 20115485867bSBarry Smith vc = va[aptr[i]]; 20125485867bSBarry Smith vr = vb[bptr[idc]]; 20135485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20145485867bSBarry Smith *f = PETSC_FALSE; 20155485867bSBarry Smith goto done; 2016cd0d46ebSvictorle } else { 20175485867bSBarry Smith aptr[i]++; 20185485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2019cd0d46ebSvictorle } 2020cd0d46ebSvictorle } 2021cd0d46ebSvictorle } 2022cd0d46ebSvictorle done: 2023cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20243aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2025cd0d46ebSvictorle PetscFunctionReturn(0); 2026cd0d46ebSvictorle } 2027cd0d46ebSvictorle EXTERN_C_END 2028cd0d46ebSvictorle 20291cbb95d3SBarry Smith EXTERN_C_BEGIN 20301cbb95d3SBarry Smith #undef __FUNCT__ 20311cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 20327087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 20331cbb95d3SBarry Smith { 20341cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 203554f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 203654f21887SBarry Smith MatScalar *va,*vb; 20371cbb95d3SBarry Smith PetscErrorCode ierr; 20381cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 20391cbb95d3SBarry Smith 20401cbb95d3SBarry Smith PetscFunctionBegin; 20411cbb95d3SBarry Smith bij = (Mat_SeqAIJ *) B->data; 20421cbb95d3SBarry Smith 20431cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 20441cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20451cbb95d3SBarry Smith if (ma!=nb || na!=mb){ 20461cbb95d3SBarry Smith *f = PETSC_FALSE; 20471cbb95d3SBarry Smith PetscFunctionReturn(0); 20481cbb95d3SBarry Smith } 20491cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 20501cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 20511cbb95d3SBarry Smith va = aij->a; vb = bij->a; 20521cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 20531cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 20541cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 20551cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 20561cbb95d3SBarry Smith 20571cbb95d3SBarry Smith *f = PETSC_TRUE; 20581cbb95d3SBarry Smith for (i=0; i<ma; i++) { 20591cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 20601cbb95d3SBarry Smith PetscInt idc,idr; 20611cbb95d3SBarry Smith PetscScalar vc,vr; 20621cbb95d3SBarry Smith /* column/row index/value */ 20631cbb95d3SBarry Smith idc = adx[aptr[i]]; 20641cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 20651cbb95d3SBarry Smith vc = va[aptr[i]]; 20661cbb95d3SBarry Smith vr = vb[bptr[idc]]; 20671cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 20681cbb95d3SBarry Smith *f = PETSC_FALSE; 20691cbb95d3SBarry Smith goto done; 20701cbb95d3SBarry Smith } else { 20711cbb95d3SBarry Smith aptr[i]++; 20721cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 20731cbb95d3SBarry Smith } 20741cbb95d3SBarry Smith } 20751cbb95d3SBarry Smith } 20761cbb95d3SBarry Smith done: 20771cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 20781cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 20791cbb95d3SBarry Smith PetscFunctionReturn(0); 20801cbb95d3SBarry Smith } 20811cbb95d3SBarry Smith EXTERN_C_END 20821cbb95d3SBarry Smith 20839e29f15eSvictorle #undef __FUNCT__ 20849e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 2085ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 20869e29f15eSvictorle { 2087dfbe8321SBarry Smith PetscErrorCode ierr; 20889e29f15eSvictorle PetscFunctionBegin; 20895485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 20909e29f15eSvictorle PetscFunctionReturn(0); 20919e29f15eSvictorle } 20929e29f15eSvictorle 20934a2ae208SSatish Balay #undef __FUNCT__ 20941cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 2095ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 20961cbb95d3SBarry Smith { 20971cbb95d3SBarry Smith PetscErrorCode ierr; 20981cbb95d3SBarry Smith PetscFunctionBegin; 20991cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21001cbb95d3SBarry Smith PetscFunctionReturn(0); 21011cbb95d3SBarry Smith } 21021cbb95d3SBarry Smith 21031cbb95d3SBarry Smith #undef __FUNCT__ 21044a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 2105dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 210617ab2063SBarry Smith { 2107416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 210854f21887SBarry Smith PetscScalar *l,*r,x; 210954f21887SBarry Smith MatScalar *v; 2110dfbe8321SBarry Smith PetscErrorCode ierr; 2111d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 211217ab2063SBarry Smith 21133a40ed3dSBarry Smith PetscFunctionBegin; 211417ab2063SBarry Smith if (ll) { 21153ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21163ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2117e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2118e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21191ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2120416022c9SBarry Smith v = a->a; 212117ab2063SBarry Smith for (i=0; i<m; i++) { 212217ab2063SBarry Smith x = l[i]; 2123416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 212417ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 212517ab2063SBarry Smith } 21261ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2127efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 212817ab2063SBarry Smith } 212917ab2063SBarry Smith if (rr) { 2130e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2131e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21321ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2133416022c9SBarry Smith v = a->a; jj = a->j; 213417ab2063SBarry Smith for (i=0; i<nz; i++) { 2135bfeeae90SHong Zhang (*v++) *= r[*jj++]; 213617ab2063SBarry Smith } 21371ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2138efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 213917ab2063SBarry Smith } 21403a40ed3dSBarry Smith PetscFunctionReturn(0); 214117ab2063SBarry Smith } 214217ab2063SBarry Smith 21434a2ae208SSatish Balay #undef __FUNCT__ 21444a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 214597f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 214617ab2063SBarry Smith { 2147db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 21486849ba73SBarry Smith PetscErrorCode ierr; 2149d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 215097f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 21515d0c19d7SBarry Smith const PetscInt *irow,*icol; 21525d0c19d7SBarry Smith PetscInt nrows,ncols; 215397f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 215454f21887SBarry Smith MatScalar *a_new,*mat_a; 2155416022c9SBarry Smith Mat C; 2156ace3abfcSBarry Smith PetscBool stride,sorted; 215717ab2063SBarry Smith 21583a40ed3dSBarry Smith PetscFunctionBegin; 215914ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 2160e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 216114ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2162e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 216399141d43SSatish Balay 216417ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2165b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2166b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 216717ab2063SBarry Smith 2168fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 21690dbe5b1eSSatish Balay ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2170fee21e36SBarry Smith if (stride && step == 1) { 217102834360SBarry Smith /* special case of contiguous rows */ 21720e83c824SBarry Smith ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr); 217302834360SBarry Smith /* loop over new rows determining lens and starting points */ 217402834360SBarry Smith for (i=0; i<nrows; i++) { 2175bfeeae90SHong Zhang kstart = ai[irow[i]]; 2176a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 217702834360SBarry Smith for (k=kstart; k<kend; k++) { 2178bfeeae90SHong Zhang if (aj[k] >= first) { 217902834360SBarry Smith starts[i] = k; 218002834360SBarry Smith break; 218102834360SBarry Smith } 218202834360SBarry Smith } 2183a2744918SBarry Smith sum = 0; 218402834360SBarry Smith while (k < kend) { 2185bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2186a2744918SBarry Smith sum++; 218702834360SBarry Smith } 2188a2744918SBarry Smith lens[i] = sum; 218902834360SBarry Smith } 219002834360SBarry Smith /* create submatrix */ 2191cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 219297f1f81fSBarry Smith PetscInt n_cols,n_rows; 219308480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2194e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2195d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 219608480c60SBarry Smith C = *B; 21973a40ed3dSBarry Smith } else { 21987adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 2199f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22007adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2201ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 220208480c60SBarry Smith } 2203db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2204db02288aSLois Curfman McInnes 220502834360SBarry Smith /* loop over rows inserting into submatrix */ 2206db02288aSLois Curfman McInnes a_new = c->a; 2207db02288aSLois Curfman McInnes j_new = c->j; 2208db02288aSLois Curfman McInnes i_new = c->i; 2209bfeeae90SHong Zhang 221002834360SBarry Smith for (i=0; i<nrows; i++) { 2211a2744918SBarry Smith ii = starts[i]; 2212a2744918SBarry Smith lensi = lens[i]; 2213a2744918SBarry Smith for (k=0; k<lensi; k++) { 2214a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 221502834360SBarry Smith } 221687828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2217a2744918SBarry Smith a_new += lensi; 2218a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2219a2744918SBarry Smith c->ilen[i] = lensi; 222002834360SBarry Smith } 22210e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22223a40ed3dSBarry Smith } else { 222302834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22240e83c824SBarry Smith ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr); 222597f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 22260e83c824SBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 22274dcab191SBarry Smith for (i=0; i<ncols; i++) { 22284dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 22294dcab191SBarry Smith if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols); 22304dcab191SBarry Smith #endif 22314dcab191SBarry Smith smap[icol[i]] = i+1; 22324dcab191SBarry Smith } 22334dcab191SBarry Smith 223402834360SBarry Smith /* determine lens of each row */ 223502834360SBarry Smith for (i=0; i<nrows; i++) { 2236bfeeae90SHong Zhang kstart = ai[irow[i]]; 223702834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 223802834360SBarry Smith lens[i] = 0; 223902834360SBarry Smith for (k=kstart; k<kend; k++) { 2240bfeeae90SHong Zhang if (smap[aj[k]]) { 224102834360SBarry Smith lens[i]++; 224202834360SBarry Smith } 224302834360SBarry Smith } 224402834360SBarry Smith } 224517ab2063SBarry Smith /* Create and fill new matrix */ 2246a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2247ace3abfcSBarry Smith PetscBool equal; 22480f5bd95cSBarry Smith 224999141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 2250e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2251d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 22520f5bd95cSBarry Smith if (!equal) { 2253e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 225499141d43SSatish Balay } 2255d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 225608480c60SBarry Smith C = *B; 22573a40ed3dSBarry Smith } else { 22587adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 2259f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22607adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2261ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 226208480c60SBarry Smith } 226399141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 226417ab2063SBarry Smith for (i=0; i<nrows; i++) { 226599141d43SSatish Balay row = irow[i]; 2266bfeeae90SHong Zhang kstart = ai[row]; 226799141d43SSatish Balay kend = kstart + a->ilen[row]; 2268bfeeae90SHong Zhang mat_i = c->i[i]; 226999141d43SSatish Balay mat_j = c->j + mat_i; 227099141d43SSatish Balay mat_a = c->a + mat_i; 227199141d43SSatish Balay mat_ilen = c->ilen + i; 227217ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2273bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2274ed480e8bSBarry Smith *mat_j++ = tcol - 1; 227599141d43SSatish Balay *mat_a++ = a->a[k]; 227699141d43SSatish Balay (*mat_ilen)++; 227799141d43SSatish Balay 227817ab2063SBarry Smith } 227917ab2063SBarry Smith } 228017ab2063SBarry Smith } 228102834360SBarry Smith /* Free work space */ 228202834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2283606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2284606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 228502834360SBarry Smith } 22866d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22876d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 228817ab2063SBarry Smith 228917ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2290416022c9SBarry Smith *B = C; 22913a40ed3dSBarry Smith PetscFunctionReturn(0); 229217ab2063SBarry Smith } 229317ab2063SBarry Smith 22941df811f5SHong Zhang #undef __FUNCT__ 229582d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 229682d44351SHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat) 229782d44351SHong Zhang { 229882d44351SHong Zhang PetscErrorCode ierr; 229982d44351SHong Zhang Mat B; 230082d44351SHong Zhang 230182d44351SHong Zhang PetscFunctionBegin; 230282d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 230382d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 230482d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 230582d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 230682d44351SHong Zhang *subMat = B; 230782d44351SHong Zhang PetscFunctionReturn(0); 230882d44351SHong Zhang } 230982d44351SHong Zhang 231082d44351SHong Zhang #undef __FUNCT__ 23114a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 23120481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2313a871dcd8SBarry Smith { 231463b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2315dfbe8321SBarry Smith PetscErrorCode ierr; 231663b91edcSBarry Smith Mat outA; 2317ace3abfcSBarry Smith PetscBool row_identity,col_identity; 231863b91edcSBarry Smith 23193a40ed3dSBarry Smith PetscFunctionBegin; 2320e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23211df811f5SHong Zhang 2322b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2323b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2324a871dcd8SBarry Smith 232563b91edcSBarry Smith outA = inA; 2326d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2327c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 23286bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 2329c3122656SLisandro Dalcin a->row = row; 2330c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 23316bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 2332c3122656SLisandro Dalcin a->col = col; 233363b91edcSBarry Smith 233436db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 23356bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 23364c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 233752e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 2338f0ec6fceSSatish Balay 233994a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2340d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 2341d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 234294a9d846SBarry Smith } 234363b91edcSBarry Smith 2344f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2345137fb511SHong Zhang if (row_identity && col_identity) { 2346ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2347137fb511SHong Zhang } else { 2348719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2349137fb511SHong Zhang } 23503a40ed3dSBarry Smith PetscFunctionReturn(0); 2351a871dcd8SBarry Smith } 2352a871dcd8SBarry Smith 23534a2ae208SSatish Balay #undef __FUNCT__ 23544a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2355f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2356f0b747eeSBarry Smith { 2357f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2358f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2359efee365bSSatish Balay PetscErrorCode ierr; 23600805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(a->nz); 23613a40ed3dSBarry Smith 23623a40ed3dSBarry Smith PetscFunctionBegin; 2363f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 2364efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 23653a40ed3dSBarry Smith PetscFunctionReturn(0); 2366f0b747eeSBarry Smith } 2367f0b747eeSBarry Smith 23684a2ae208SSatish Balay #undef __FUNCT__ 23694a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 237097f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2371cddf8d76SBarry Smith { 2372dfbe8321SBarry Smith PetscErrorCode ierr; 237397f1f81fSBarry Smith PetscInt i; 2374cddf8d76SBarry Smith 23753a40ed3dSBarry Smith PetscFunctionBegin; 2376cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2377b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 2378cddf8d76SBarry Smith } 2379cddf8d76SBarry Smith 2380cddf8d76SBarry Smith for (i=0; i<n; i++) { 23816a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2382cddf8d76SBarry Smith } 23833a40ed3dSBarry Smith PetscFunctionReturn(0); 2384cddf8d76SBarry Smith } 2385cddf8d76SBarry Smith 23864a2ae208SSatish Balay #undef __FUNCT__ 23874a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 238897f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 23894dcbc457SBarry Smith { 2390e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23916849ba73SBarry Smith PetscErrorCode ierr; 23925d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 23935d0c19d7SBarry Smith const PetscInt *idx; 239497f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2395f1af5d2fSBarry Smith PetscBT table; 2396bbd702dbSSatish Balay 23973a40ed3dSBarry Smith PetscFunctionBegin; 2398d0f46423SBarry Smith m = A->rmap->n; 2399e4d965acSSatish Balay ai = a->i; 2400bfeeae90SHong Zhang aj = a->j; 24018a047759SSatish Balay 2402e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 240306763907SSatish Balay 240497f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 24056831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 240606763907SSatish Balay 2407e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2408b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2409e4d965acSSatish Balay isz = 0; 24106831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2411e4d965acSSatish Balay 2412e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 24134dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2414b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2415e4d965acSSatish Balay 2416dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2417e4d965acSSatish Balay for (j=0; j<n ; ++j){ 2418f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 24194dcbc457SBarry Smith } 242006763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 24216bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2422e4d965acSSatish Balay 242304a348a9SBarry Smith k = 0; 242404a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 242504a348a9SBarry Smith n = isz; 242606763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 2427e4d965acSSatish Balay row = nidx[k]; 2428e4d965acSSatish Balay start = ai[row]; 2429e4d965acSSatish Balay end = ai[row+1]; 243004a348a9SBarry Smith for (l = start; l<end ; l++){ 2431efb16452SHong Zhang val = aj[l] ; 2432f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 2433e4d965acSSatish Balay } 2434e4d965acSSatish Balay } 2435e4d965acSSatish Balay } 243670b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2437e4d965acSSatish Balay } 24386831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 2439606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 24403a40ed3dSBarry Smith PetscFunctionReturn(0); 24414dcbc457SBarry Smith } 244217ab2063SBarry Smith 24430513a670SBarry Smith /* -------------------------------------------------------------- */ 24444a2ae208SSatish Balay #undef __FUNCT__ 24454a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2446dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 24470513a670SBarry Smith { 24480513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 24496849ba73SBarry Smith PetscErrorCode ierr; 24503b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 24515d0c19d7SBarry Smith const PetscInt *row,*col; 24525d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 245356cd22aeSBarry Smith IS icolp,irowp; 24543b98c0a2SBarry Smith PetscInt *cwork = PETSC_NULL; 24553b98c0a2SBarry Smith PetscScalar *vwork = PETSC_NULL; 24560513a670SBarry Smith 24573a40ed3dSBarry Smith PetscFunctionBegin; 24584c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 245956cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 24604c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 246156cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 24620513a670SBarry Smith 24630513a670SBarry Smith /* determine lengths of permuted rows */ 246497f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 24650513a670SBarry Smith for (i=0; i<m; i++) { 24660513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 24670513a670SBarry Smith } 24687adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 2469f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 24707adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2471ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2472606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 24730513a670SBarry Smith 247497f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 24750513a670SBarry Smith for (i=0; i<m; i++) { 247632ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 24770513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 2478cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 247932ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 24800513a670SBarry Smith } 2481606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 24823c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 24830513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24840513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 248556cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 248656cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 24876bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 24886bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 24893a40ed3dSBarry Smith PetscFunctionReturn(0); 24900513a670SBarry Smith } 24910513a670SBarry Smith 24924a2ae208SSatish Balay #undef __FUNCT__ 24934a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2494dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2495cb5b572fSBarry Smith { 2496dfbe8321SBarry Smith PetscErrorCode ierr; 2497cb5b572fSBarry Smith 2498cb5b572fSBarry Smith PetscFunctionBegin; 249933f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 250033f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2501be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2502be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2503be6bf707SBarry Smith 2504700c5bfcSBarry Smith if (a->i[A->rmap->n] != b->i[B->rmap->n]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Number of nonzeros in two matrices are different"); 2505d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2506cb5b572fSBarry Smith } else { 2507cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2508cb5b572fSBarry Smith } 2509cb5b572fSBarry Smith PetscFunctionReturn(0); 2510cb5b572fSBarry Smith } 2511cb5b572fSBarry Smith 25124a2ae208SSatish Balay #undef __FUNCT__ 25134a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 2514dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 2515273d9f13SBarry Smith { 2516dfbe8321SBarry Smith PetscErrorCode ierr; 2517273d9f13SBarry Smith 2518273d9f13SBarry Smith PetscFunctionBegin; 2519ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2520273d9f13SBarry Smith PetscFunctionReturn(0); 2521273d9f13SBarry Smith } 2522273d9f13SBarry Smith 25234a2ae208SSatish Balay #undef __FUNCT__ 25244a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 2525a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 25266c0721eeSBarry Smith { 25276c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25286c0721eeSBarry Smith PetscFunctionBegin; 25296c0721eeSBarry Smith *array = a->a; 25306c0721eeSBarry Smith PetscFunctionReturn(0); 25316c0721eeSBarry Smith } 25326c0721eeSBarry Smith 25334a2ae208SSatish Balay #undef __FUNCT__ 25344a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 2535dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 25366c0721eeSBarry Smith { 25376c0721eeSBarry Smith PetscFunctionBegin; 25386c0721eeSBarry Smith PetscFunctionReturn(0); 25396c0721eeSBarry Smith } 2540273d9f13SBarry Smith 2541ee4f033dSBarry Smith #undef __FUNCT__ 2542ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2543dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2544ee4f033dSBarry Smith { 25456849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 25466849ba73SBarry Smith PetscErrorCode ierr; 254797f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 2548efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 254987828ca2SBarry Smith PetscScalar *vscale_array; 2550ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2551ee4f033dSBarry Smith Vec w1,w2,w3; 2552ee4f033dSBarry Smith void *fctx = coloring->fctx; 2553ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2554ee4f033dSBarry Smith 2555ee4f033dSBarry Smith PetscFunctionBegin; 2556ee4f033dSBarry Smith if (!coloring->w1) { 2557ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 255852e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 2559ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 256052e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 2561ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 256252e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 2563ee4f033dSBarry Smith } 2564ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2565ee4f033dSBarry Smith 2566ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2567acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr); 2568ee4f033dSBarry Smith if (flg) { 2569ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2570ee4f033dSBarry Smith } else { 2571ace3abfcSBarry Smith PetscBool assembled; 25720b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 25730b9b6f31SBarry Smith if (assembled) { 2574ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2575ee4f033dSBarry Smith } 25760b9b6f31SBarry Smith } 2577ee4f033dSBarry Smith 2578ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2579ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2580ee4f033dSBarry Smith 2581ee4f033dSBarry Smith /* 2582ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 2583ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 2584ee4f033dSBarry Smith */ 2585ee4f033dSBarry Smith if (coloring->F) { 2586ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2587ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2588ee4f033dSBarry Smith if (m1 != m2) { 2589ee4f033dSBarry Smith coloring->F = 0; 2590ee4f033dSBarry Smith } 2591ee4f033dSBarry Smith } 2592ee4f033dSBarry Smith 2593ee4f033dSBarry Smith if (coloring->F) { 2594ee4f033dSBarry Smith w1 = coloring->F; 2595ee4f033dSBarry Smith coloring->F = 0; 2596ee4f033dSBarry Smith } else { 259766f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2598ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 259966f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2600ee4f033dSBarry Smith } 2601ee4f033dSBarry Smith 2602ee4f033dSBarry Smith /* 2603ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2604ee4f033dSBarry Smith */ 26051ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 26061ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2607ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2608ee4f033dSBarry Smith /* 2609ee4f033dSBarry Smith Loop over each column associated with color adding the 2610ee4f033dSBarry Smith perturbation to the vector w3. 2611ee4f033dSBarry Smith */ 2612ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2613ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2614ee4f033dSBarry Smith dx = xx[col]; 2615ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2616ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2617ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2618ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2619ee4f033dSBarry Smith #else 2620ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2621ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2622ee4f033dSBarry Smith #endif 2623ee4f033dSBarry Smith dx *= epsilon; 2624ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2625ee4f033dSBarry Smith } 2626ee4f033dSBarry Smith } 26271ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2628ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2629ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2630ee4f033dSBarry Smith 2631ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2632ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2633ee4f033dSBarry Smith 2634ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2635ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2636ee4f033dSBarry Smith 26371ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2638ee4f033dSBarry Smith /* 2639ee4f033dSBarry Smith Loop over each color 2640ee4f033dSBarry Smith */ 2641ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 264249b058dcSBarry Smith coloring->currentcolor = k; 2643ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 26441ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2645ee4f033dSBarry Smith /* 2646ee4f033dSBarry Smith Loop over each column associated with color adding the 2647ee4f033dSBarry Smith perturbation to the vector w3. 2648ee4f033dSBarry Smith */ 2649ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2650ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2651ee4f033dSBarry Smith dx = xx[col]; 26525b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2653ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2654ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2655ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2656ee4f033dSBarry Smith #else 2657ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2658ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2659ee4f033dSBarry Smith #endif 2660ee4f033dSBarry Smith dx *= epsilon; 2661e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2662ee4f033dSBarry Smith w3_array[col] += dx; 2663ee4f033dSBarry Smith } 26641ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2665ee4f033dSBarry Smith 2666ee4f033dSBarry Smith /* 2667ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2668ee4f033dSBarry Smith */ 2669ee4f033dSBarry Smith 267066f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2671ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 267266f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2673efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2674ee4f033dSBarry Smith 2675ee4f033dSBarry Smith /* 2676ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2677ee4f033dSBarry Smith */ 26781ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2679ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2680ee4f033dSBarry Smith row = coloring->rows[k][l]; 2681ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2682ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2683ee4f033dSBarry Smith srow = row + start; 2684ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2685ee4f033dSBarry Smith } 26861ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2687ee4f033dSBarry Smith } 268849b058dcSBarry Smith coloring->currentcolor = k; 26891ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 26901ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2691ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2692ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2693ee4f033dSBarry Smith PetscFunctionReturn(0); 2694ee4f033dSBarry Smith } 2695ee4f033dSBarry Smith 26968229c054SShri Abhyankar /* 26978229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26988229c054SShri Abhyankar have different nonzero structure. 26998229c054SShri Abhyankar */ 2700ac90fabeSBarry Smith #undef __FUNCT__ 27018229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 27028229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz) 2703ec7775f6SShri Abhyankar { 27048229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 2705ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2706ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2707ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 2708ec7775f6SShri Abhyankar 2709ec7775f6SShri Abhyankar PetscFunctionBegin; 2710ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2711ec7775f6SShri Abhyankar for(i=0; i<m; i++) { 27128af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 27138af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 27148af7cee1SJed Brown nnz[i] = 0; 27158af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 27168af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 27178af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 27188af7cee1SJed Brown nnz[i]++; 27198af7cee1SJed Brown } 27208af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2721ec7775f6SShri Abhyankar } 2722ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2723ec7775f6SShri Abhyankar } 2724ec7775f6SShri Abhyankar 2725ec7775f6SShri Abhyankar #undef __FUNCT__ 2726ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2727f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2728ac90fabeSBarry Smith { 2729dfbe8321SBarry Smith PetscErrorCode ierr; 273097f1f81fSBarry Smith PetscInt i; 2731ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 27320805154bSBarry Smith PetscBLASInt one=1,bnz = PetscBLASIntCast(x->nz); 2733ac90fabeSBarry Smith 2734ac90fabeSBarry Smith PetscFunctionBegin; 2735ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2736f4df32b1SMatthew Knepley PetscScalar alpha = a; 2737f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 2738c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2739a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2740a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 27416bf464f9SBarry Smith ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr); 2742a30b2313SHong Zhang } 2743a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 2744d0f46423SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2745a30b2313SHong Zhang y->XtoY = X; 2746407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2747c537a176SHong Zhang } 2748f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 27491e2582c4SBarry Smith ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/y->nz);CHKERRQ(ierr); 2750ac90fabeSBarry Smith } else { 27518229c054SShri Abhyankar Mat B; 27528229c054SShri Abhyankar PetscInt *nnz; 275316b2e9dcSShri Abhyankar ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 2754ec7775f6SShri Abhyankar ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr); 2755bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 27564aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 2757ec7775f6SShri Abhyankar ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 27588229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 27598229c054SShri Abhyankar ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr); 2760ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2761ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 27628229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2763ac90fabeSBarry Smith } 2764ac90fabeSBarry Smith PetscFunctionReturn(0); 2765ac90fabeSBarry Smith } 2766ac90fabeSBarry Smith 2767521d7252SBarry Smith #undef __FUNCT__ 2768521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2769521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2770521d7252SBarry Smith { 277141c166b1SJed Brown PetscErrorCode ierr; 277241c166b1SJed Brown 2773521d7252SBarry Smith PetscFunctionBegin; 277441c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); 277541c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); 2776521d7252SBarry Smith PetscFunctionReturn(0); 2777521d7252SBarry Smith } 2778521d7252SBarry Smith 2779354c94deSBarry Smith #undef __FUNCT__ 2780354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 27817087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2782354c94deSBarry Smith { 2783354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2784354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2785354c94deSBarry Smith PetscInt i,nz; 2786354c94deSBarry Smith PetscScalar *a; 2787354c94deSBarry Smith 2788354c94deSBarry Smith PetscFunctionBegin; 2789354c94deSBarry Smith nz = aij->nz; 2790354c94deSBarry Smith a = aij->a; 2791354c94deSBarry Smith for (i=0; i<nz; i++) { 2792354c94deSBarry Smith a[i] = PetscConj(a[i]); 2793354c94deSBarry Smith } 2794354c94deSBarry Smith #else 2795354c94deSBarry Smith PetscFunctionBegin; 2796354c94deSBarry Smith #endif 2797354c94deSBarry Smith PetscFunctionReturn(0); 2798354c94deSBarry Smith } 2799354c94deSBarry Smith 2800e34fafa9SBarry Smith #undef __FUNCT__ 2801985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2802985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2803e34fafa9SBarry Smith { 2804e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2805e34fafa9SBarry Smith PetscErrorCode ierr; 2806d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2807e34fafa9SBarry Smith PetscReal atmp; 2808985db425SBarry Smith PetscScalar *x; 2809e34fafa9SBarry Smith MatScalar *aa; 2810e34fafa9SBarry Smith 2811e34fafa9SBarry Smith PetscFunctionBegin; 2812e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2813e34fafa9SBarry Smith aa = a->a; 2814e34fafa9SBarry Smith ai = a->i; 2815e34fafa9SBarry Smith aj = a->j; 2816e34fafa9SBarry Smith 2817985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2818e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2819e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2820e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2821e34fafa9SBarry Smith for (i=0; i<m; i++) { 2822e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 28239189402eSHong Zhang x[i] = 0.0; 2824e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2825985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2826985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2827985db425SBarry Smith aa++; aj++; 2828985db425SBarry Smith } 2829985db425SBarry Smith } 2830985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2831985db425SBarry Smith PetscFunctionReturn(0); 2832985db425SBarry Smith } 2833985db425SBarry Smith 2834985db425SBarry Smith #undef __FUNCT__ 2835985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2836985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2837985db425SBarry Smith { 2838985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2839985db425SBarry Smith PetscErrorCode ierr; 2840d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2841985db425SBarry Smith PetscScalar *x; 2842985db425SBarry Smith MatScalar *aa; 2843985db425SBarry Smith 2844985db425SBarry Smith PetscFunctionBegin; 2845e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2846985db425SBarry Smith aa = a->a; 2847985db425SBarry Smith ai = a->i; 2848985db425SBarry Smith aj = a->j; 2849985db425SBarry Smith 2850985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2851985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2852985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2853e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2854985db425SBarry Smith for (i=0; i<m; i++) { 2855985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2856d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2857985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2858985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2859985db425SBarry Smith x[i] = 0.0; 2860985db425SBarry Smith if (idx) { 2861985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2862985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2863985db425SBarry Smith if (aj[j] > j) { 2864985db425SBarry Smith idx[i] = j; 2865985db425SBarry Smith break; 2866985db425SBarry Smith } 2867985db425SBarry Smith } 2868985db425SBarry Smith } 2869985db425SBarry Smith } 2870985db425SBarry Smith for (j=0; j<ncols; j++){ 2871985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2872985db425SBarry Smith aa++; aj++; 2873985db425SBarry Smith } 2874985db425SBarry Smith } 2875985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2876985db425SBarry Smith PetscFunctionReturn(0); 2877985db425SBarry Smith } 2878985db425SBarry Smith 2879985db425SBarry Smith #undef __FUNCT__ 2880c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 2881c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2882c87e5d42SMatthew Knepley { 2883c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2884c87e5d42SMatthew Knepley PetscErrorCode ierr; 2885c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2886c87e5d42SMatthew Knepley PetscReal atmp; 2887c87e5d42SMatthew Knepley PetscScalar *x; 2888c87e5d42SMatthew Knepley MatScalar *aa; 2889c87e5d42SMatthew Knepley 2890c87e5d42SMatthew Knepley PetscFunctionBegin; 2891e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2892c87e5d42SMatthew Knepley aa = a->a; 2893c87e5d42SMatthew Knepley ai = a->i; 2894c87e5d42SMatthew Knepley aj = a->j; 2895c87e5d42SMatthew Knepley 2896c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2897c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2898c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2899e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2900c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2901c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2902289a08f5SMatthew Knepley if (ncols) { 2903289a08f5SMatthew Knepley /* Get first nonzero */ 2904289a08f5SMatthew Knepley for(j = 0; j < ncols; j++) { 2905289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 2906289a08f5SMatthew Knepley if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;} 2907289a08f5SMatthew Knepley } 2908289a08f5SMatthew Knepley if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;} 2909289a08f5SMatthew Knepley } else { 2910289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2911289a08f5SMatthew Knepley } 2912c87e5d42SMatthew Knepley for(j = 0; j < ncols; j++) { 2913c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2914289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2915c87e5d42SMatthew Knepley aa++; aj++; 2916c87e5d42SMatthew Knepley } 2917c87e5d42SMatthew Knepley } 2918c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2919c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2920c87e5d42SMatthew Knepley } 2921c87e5d42SMatthew Knepley 2922c87e5d42SMatthew Knepley #undef __FUNCT__ 2923985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 2924985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2925985db425SBarry Smith { 2926985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2927985db425SBarry Smith PetscErrorCode ierr; 2928d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2929985db425SBarry Smith PetscScalar *x; 2930985db425SBarry Smith MatScalar *aa; 2931985db425SBarry Smith 2932985db425SBarry Smith PetscFunctionBegin; 2933e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2934985db425SBarry Smith aa = a->a; 2935985db425SBarry Smith ai = a->i; 2936985db425SBarry Smith aj = a->j; 2937985db425SBarry Smith 2938985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2939985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2940985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2941e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2942985db425SBarry Smith for (i=0; i<m; i++) { 2943985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2944d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2945985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2946985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2947985db425SBarry Smith x[i] = 0.0; 2948985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2949985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2950985db425SBarry Smith for (j=0;j<ncols;j++) { 2951985db425SBarry Smith if (aj[j] > j) { 2952985db425SBarry Smith idx[i] = j; 2953985db425SBarry Smith break; 2954985db425SBarry Smith } 2955985db425SBarry Smith } 2956985db425SBarry Smith } 2957985db425SBarry Smith } 2958985db425SBarry Smith for (j=0; j<ncols; j++){ 2959985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2960985db425SBarry Smith aa++; aj++; 2961e34fafa9SBarry Smith } 2962e34fafa9SBarry Smith } 2963e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2964e34fafa9SBarry Smith PetscFunctionReturn(0); 2965e34fafa9SBarry Smith } 29667087cfbeSBarry Smith extern PetscErrorCode MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*); 2967682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 29680a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2969cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2970cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2971cb5b572fSBarry Smith MatMult_SeqAIJ, 297297304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 29737c922b88SBarry Smith MatMultTranspose_SeqAIJ, 29747c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2975db4efbfdSBarry Smith 0, 2976db4efbfdSBarry Smith 0, 2977db4efbfdSBarry Smith 0, 2978db4efbfdSBarry Smith /*10*/ 0, 2979cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2980cb5b572fSBarry Smith 0, 298141f059aeSBarry Smith MatSOR_SeqAIJ, 298217ab2063SBarry Smith MatTranspose_SeqAIJ, 298397304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2984cb5b572fSBarry Smith MatEqual_SeqAIJ, 2985cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2986cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2987cb5b572fSBarry Smith MatNorm_SeqAIJ, 298897304618SKris Buschelman /*20*/ 0, 2989cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 2990cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2991cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2992d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ, 2993db4efbfdSBarry Smith 0, 2994db4efbfdSBarry Smith 0, 2995db4efbfdSBarry Smith 0, 2996db4efbfdSBarry Smith 0, 2997d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ, 2998db4efbfdSBarry Smith 0, 2999db4efbfdSBarry Smith 0, 30006c0721eeSBarry Smith MatGetArray_SeqAIJ, 30016c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 3002d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ, 3003cb5b572fSBarry Smith 0, 3004cb5b572fSBarry Smith 0, 3005cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3006cb5b572fSBarry Smith 0, 3007d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ, 3008cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3009cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3010cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3011cb5b572fSBarry Smith MatCopy_SeqAIJ, 3012d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ, 3013cb5b572fSBarry Smith MatScale_SeqAIJ, 3014cb5b572fSBarry Smith 0, 301579299369SBarry Smith MatDiagonalSet_SeqAIJ, 30166e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 3017d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ, 30183b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 30193b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 30203b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3021a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 3022d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ, 3023b9617806SBarry Smith 0, 30240513a670SBarry Smith 0, 3025cda55fadSBarry Smith MatPermute_SeqAIJ, 3026cda55fadSBarry Smith 0, 3027d519adbfSMatthew Knepley /*59*/ 0, 3028b9b97703SBarry Smith MatDestroy_SeqAIJ, 3029b9b97703SBarry Smith MatView_SeqAIJ, 3030357abbc8SBarry Smith 0, 3031ee4f033dSBarry Smith 0, 3032d519adbfSMatthew Knepley /*64*/ 0, 3033ee4f033dSBarry Smith 0, 3034ee4f033dSBarry Smith 0, 3035ee4f033dSBarry Smith 0, 3036ee4f033dSBarry Smith 0, 3037d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ, 3038c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3039ee4f033dSBarry Smith 0, 3040ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 3041dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 3042ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 3043dcf5cc72SBarry Smith #else 3044dcf5cc72SBarry Smith 0, 3045dcf5cc72SBarry Smith #endif 3046d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ, 30473acb8795SBarry Smith MatFDColoringApply_AIJ, 304897304618SKris Buschelman 0, 304997304618SKris Buschelman 0, 305097304618SKris Buschelman 0, 30516ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ, 305297304618SKris Buschelman 0, 305397304618SKris Buschelman 0, 305497304618SKris Buschelman 0, 3055bc011b1eSHong Zhang MatLoad_SeqAIJ, 3056d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ, 30571cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 30586284ec50SHong Zhang 0, 30596284ec50SHong Zhang 0, 3060bc011b1eSHong Zhang 0, 3061d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ, 306226be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 306326be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3064d439da42SKris Buschelman MatPtAP_Basic, 30657ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 3066d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ, 3067bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 3068bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 3069bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 30707ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 3071d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 3072609c6c4dSKris Buschelman 0, 3073609c6c4dSKris Buschelman 0, 307487d4246cSBarry Smith MatConjugate_SeqAIJ, 307587d4246cSBarry Smith 0, 3076d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ, 307799cafbc1SBarry Smith MatRealPart_SeqAIJ, 3078f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3079f5edf698SHong Zhang 0, 30802bebee5dSHong Zhang 0, 3081cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ, 3082985db425SBarry Smith 0, 30832af78befSBarry Smith MatGetRowMin_SeqAIJ, 30842af78befSBarry Smith 0, 3085599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3086d519adbfSMatthew Knepley /*114*/0, 3087599ef60dSHong Zhang 0, 30883c2a7987SHong Zhang 0, 3089fe97e370SBarry Smith 0, 3090fbdbba38SShri Abhyankar 0, 3091fbdbba38SShri Abhyankar /*119*/0, 3092fbdbba38SShri Abhyankar 0, 3093fbdbba38SShri Abhyankar 0, 309482d44351SHong Zhang 0, 3095b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 30960716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ, 30970716a85fSBarry Smith MatGetColumnNorms_SeqAIJ 30989e29f15eSvictorle }; 309917ab2063SBarry Smith 3100fb2e594dSBarry Smith EXTERN_C_BEGIN 31014a2ae208SSatish Balay #undef __FUNCT__ 31024a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 31037087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3104bef8e0ddSBarry Smith { 3105bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 310697f1f81fSBarry Smith PetscInt i,nz,n; 3107bef8e0ddSBarry Smith 3108bef8e0ddSBarry Smith PetscFunctionBegin; 3109bef8e0ddSBarry Smith 3110bef8e0ddSBarry Smith nz = aij->maxnz; 3111d0f46423SBarry Smith n = mat->rmap->n; 3112bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3113bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3114bef8e0ddSBarry Smith } 3115bef8e0ddSBarry Smith aij->nz = nz; 3116bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3117bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3118bef8e0ddSBarry Smith } 3119bef8e0ddSBarry Smith 3120bef8e0ddSBarry Smith PetscFunctionReturn(0); 3121bef8e0ddSBarry Smith } 3122fb2e594dSBarry Smith EXTERN_C_END 3123bef8e0ddSBarry Smith 31244a2ae208SSatish Balay #undef __FUNCT__ 31254a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3126bef8e0ddSBarry Smith /*@ 3127bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3128bef8e0ddSBarry Smith in the matrix. 3129bef8e0ddSBarry Smith 3130bef8e0ddSBarry Smith Input Parameters: 3131bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3132bef8e0ddSBarry Smith - indices - the column indices 3133bef8e0ddSBarry Smith 313415091d37SBarry Smith Level: advanced 313515091d37SBarry Smith 3136bef8e0ddSBarry Smith Notes: 3137bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3138bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3139bef8e0ddSBarry Smith of the MatSetValues() operation. 3140bef8e0ddSBarry Smith 3141bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3142d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3143bef8e0ddSBarry Smith 3144bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3145bef8e0ddSBarry Smith 3146b9617806SBarry Smith The indices should start with zero, not one. 3147b9617806SBarry Smith 3148bef8e0ddSBarry Smith @*/ 31497087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3150bef8e0ddSBarry Smith { 31514ac538c5SBarry Smith PetscErrorCode ierr; 3152bef8e0ddSBarry Smith 3153bef8e0ddSBarry Smith PetscFunctionBegin; 31540700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 31554482741eSBarry Smith PetscValidPointer(indices,2); 31564ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr); 3157bef8e0ddSBarry Smith PetscFunctionReturn(0); 3158bef8e0ddSBarry Smith } 3159bef8e0ddSBarry Smith 3160be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3161be6bf707SBarry Smith 3162fb2e594dSBarry Smith EXTERN_C_BEGIN 31634a2ae208SSatish Balay #undef __FUNCT__ 31644a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 31657087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3166be6bf707SBarry Smith { 3167be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 31686849ba73SBarry Smith PetscErrorCode ierr; 3169d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3170be6bf707SBarry Smith 3171be6bf707SBarry Smith PetscFunctionBegin; 3172be6bf707SBarry Smith if (aij->nonew != 1) { 3173e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3174be6bf707SBarry Smith } 3175be6bf707SBarry Smith 3176be6bf707SBarry Smith /* allocate space for values if not already there */ 3177be6bf707SBarry Smith if (!aij->saved_values) { 317887828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 31799518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3180be6bf707SBarry Smith } 3181be6bf707SBarry Smith 3182be6bf707SBarry Smith /* copy values over */ 318387828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3184be6bf707SBarry Smith PetscFunctionReturn(0); 3185be6bf707SBarry Smith } 3186fb2e594dSBarry Smith EXTERN_C_END 3187be6bf707SBarry Smith 31884a2ae208SSatish Balay #undef __FUNCT__ 3189b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3190be6bf707SBarry Smith /*@ 3191be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3192be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3193be6bf707SBarry Smith nonlinear portion. 3194be6bf707SBarry Smith 3195be6bf707SBarry Smith Collect on Mat 3196be6bf707SBarry Smith 3197be6bf707SBarry Smith Input Parameters: 31980e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3199be6bf707SBarry Smith 320015091d37SBarry Smith Level: advanced 320115091d37SBarry Smith 3202be6bf707SBarry Smith Common Usage, with SNESSolve(): 3203be6bf707SBarry Smith $ Create Jacobian matrix 3204be6bf707SBarry Smith $ Set linear terms into matrix 3205be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3206be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3207be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3208512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3209be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3210be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3211be6bf707SBarry Smith $ In your Jacobian routine 3212be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3213be6bf707SBarry Smith $ Set nonlinear terms in matrix 3214be6bf707SBarry Smith 3215be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3216be6bf707SBarry Smith $ // build linear portion of Jacobian 3217512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3218be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3219be6bf707SBarry Smith $ loop over nonlinear iterations 3220be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3221be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3222be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3223be6bf707SBarry Smith $ Solve linear system with Jacobian 3224be6bf707SBarry Smith $ endloop 3225be6bf707SBarry Smith 3226be6bf707SBarry Smith Notes: 3227be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3228512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3229be6bf707SBarry Smith calling this routine. 3230be6bf707SBarry Smith 32310c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 32320c468ba9SBarry Smith and does not allocated additional space. 32330c468ba9SBarry Smith 3234be6bf707SBarry Smith .seealso: MatRetrieveValues() 3235be6bf707SBarry Smith 3236be6bf707SBarry Smith @*/ 32377087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3238be6bf707SBarry Smith { 32394ac538c5SBarry Smith PetscErrorCode ierr; 3240be6bf707SBarry Smith 3241be6bf707SBarry Smith PetscFunctionBegin; 32420700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3243e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3244e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32454ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3246be6bf707SBarry Smith PetscFunctionReturn(0); 3247be6bf707SBarry Smith } 3248be6bf707SBarry Smith 3249fb2e594dSBarry Smith EXTERN_C_BEGIN 32504a2ae208SSatish Balay #undef __FUNCT__ 32514a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 32527087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3253be6bf707SBarry Smith { 3254be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 32556849ba73SBarry Smith PetscErrorCode ierr; 3256d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3257be6bf707SBarry Smith 3258be6bf707SBarry Smith PetscFunctionBegin; 3259be6bf707SBarry Smith if (aij->nonew != 1) { 3260e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3261be6bf707SBarry Smith } 3262be6bf707SBarry Smith if (!aij->saved_values) { 3263e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3264be6bf707SBarry Smith } 3265be6bf707SBarry Smith /* copy values over */ 326687828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3267be6bf707SBarry Smith PetscFunctionReturn(0); 3268be6bf707SBarry Smith } 3269fb2e594dSBarry Smith EXTERN_C_END 3270be6bf707SBarry Smith 32714a2ae208SSatish Balay #undef __FUNCT__ 32724a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3273be6bf707SBarry Smith /*@ 3274be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3275be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3276be6bf707SBarry Smith nonlinear portion. 3277be6bf707SBarry Smith 3278be6bf707SBarry Smith Collect on Mat 3279be6bf707SBarry Smith 3280be6bf707SBarry Smith Input Parameters: 3281be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3282be6bf707SBarry Smith 328315091d37SBarry Smith Level: advanced 328415091d37SBarry Smith 3285be6bf707SBarry Smith .seealso: MatStoreValues() 3286be6bf707SBarry Smith 3287be6bf707SBarry Smith @*/ 32887087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3289be6bf707SBarry Smith { 32904ac538c5SBarry Smith PetscErrorCode ierr; 3291be6bf707SBarry Smith 3292be6bf707SBarry Smith PetscFunctionBegin; 32930700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3294e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3295e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32964ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3297be6bf707SBarry Smith PetscFunctionReturn(0); 3298be6bf707SBarry Smith } 3299be6bf707SBarry Smith 3300f83d6046SBarry Smith 3301be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 33024a2ae208SSatish Balay #undef __FUNCT__ 33034a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 330417ab2063SBarry Smith /*@C 3305682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 33060d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 33076e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 330851c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 33092bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 331017ab2063SBarry Smith 3311db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3312db81eaa0SLois Curfman McInnes 331317ab2063SBarry Smith Input Parameters: 3314db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 331517ab2063SBarry Smith . m - number of rows 331617ab2063SBarry Smith . n - number of columns 331717ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 331851c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 33192bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 332017ab2063SBarry Smith 332117ab2063SBarry Smith Output Parameter: 3322416022c9SBarry Smith . A - the matrix 332317ab2063SBarry Smith 3324175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3325ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3326175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3327175b88e8SBarry Smith 3328b259b22eSLois Curfman McInnes Notes: 332949a6f317SBarry Smith If nnz is given then nz is ignored 333049a6f317SBarry Smith 333117ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 333217ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 33330002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 333444cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 333517ab2063SBarry Smith 333617ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3337a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 33383d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 33396da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 334017ab2063SBarry Smith 3341682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 33424fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3343682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 33446c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 33456c7ebb05SLois Curfman McInnes 33466c7ebb05SLois Curfman McInnes Options Database Keys: 3347698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 33489db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 334917ab2063SBarry Smith 3350027ccd11SLois Curfman McInnes Level: intermediate 3351027ccd11SLois Curfman McInnes 335236db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 335336db0b34SBarry Smith 335417ab2063SBarry Smith @*/ 33557087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 335617ab2063SBarry Smith { 3357dfbe8321SBarry Smith PetscErrorCode ierr; 33586945ee14SBarry Smith 33593a40ed3dSBarry Smith PetscFunctionBegin; 3360f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3361117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3362c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3363d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3364273d9f13SBarry Smith PetscFunctionReturn(0); 3365273d9f13SBarry Smith } 3366273d9f13SBarry Smith 33674a2ae208SSatish Balay #undef __FUNCT__ 33684a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3369273d9f13SBarry Smith /*@C 3370273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3371273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3372273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3373273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3374273d9f13SBarry Smith 3375273d9f13SBarry Smith Collective on MPI_Comm 3376273d9f13SBarry Smith 3377273d9f13SBarry Smith Input Parameters: 3378117016b1SBarry Smith + B - The matrix-free 3379273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3380273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 3381273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 3382273d9f13SBarry Smith 3383273d9f13SBarry Smith Notes: 338449a6f317SBarry Smith If nnz is given then nz is ignored 338549a6f317SBarry Smith 3386273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3387273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3388273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3389273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3390273d9f13SBarry Smith 3391273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3392273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 3393273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3394273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3395273d9f13SBarry Smith 3396aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3397aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3398aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3399aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3400aa95bbe8SBarry Smith 3401a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3402a96a251dSBarry Smith entries or columns indices 3403a96a251dSBarry Smith 3404273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3405273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3406273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3407273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3408273d9f13SBarry Smith 3409273d9f13SBarry Smith Options Database Keys: 3410698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3411698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3412273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3413273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3414273d9f13SBarry Smith the user still MUST index entries starting at 0! 3415273d9f13SBarry Smith 3416273d9f13SBarry Smith Level: intermediate 3417273d9f13SBarry Smith 3418aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3419273d9f13SBarry Smith 3420273d9f13SBarry Smith @*/ 34217087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3422273d9f13SBarry Smith { 34234ac538c5SBarry Smith PetscErrorCode ierr; 3424a23d5eceSKris Buschelman 3425a23d5eceSKris Buschelman PetscFunctionBegin; 34264ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3427a23d5eceSKris Buschelman PetscFunctionReturn(0); 3428a23d5eceSKris Buschelman } 3429a23d5eceSKris Buschelman 3430a23d5eceSKris Buschelman EXTERN_C_BEGIN 3431a23d5eceSKris Buschelman #undef __FUNCT__ 3432a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 34337087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3434a23d5eceSKris Buschelman { 3435273d9f13SBarry Smith Mat_SeqAIJ *b; 3436ace3abfcSBarry Smith PetscBool skipallocation = PETSC_FALSE; 34376849ba73SBarry Smith PetscErrorCode ierr; 343897f1f81fSBarry Smith PetscInt i; 3439273d9f13SBarry Smith 3440273d9f13SBarry Smith PetscFunctionBegin; 3441d5d45c9bSBarry Smith 3442a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3443c461c341SBarry Smith skipallocation = PETSC_TRUE; 3444c461c341SBarry Smith nz = 0; 3445c461c341SBarry Smith } 3446c461c341SBarry Smith 344726283091SBarry Smith ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr); 344826283091SBarry Smith ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr); 344926283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 345026283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3451899cda47SBarry Smith 3452435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3453e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3454b73539f3SBarry Smith if (nnz) { 3455d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3456e32f2f54SBarry Smith if (nnz[i] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be less than 0: local row %d value %d",i,nnz[i]); 3457e32f2f54SBarry Smith if (nnz[i] > B->cmap->n) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nnz cannot be greater than row length: local row %d value %d rowlength %d",i,nnz[i],B->cmap->n); 3458b73539f3SBarry Smith } 3459b73539f3SBarry Smith } 3460b73539f3SBarry Smith 3461273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3462273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3463273d9f13SBarry Smith 3464ab93d7beSBarry Smith if (!skipallocation) { 34652ee49352SLisandro Dalcin if (!b->imax) { 3466d0f46423SBarry Smith ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr); 3467d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 34682ee49352SLisandro Dalcin } 3469273d9f13SBarry Smith if (!nnz) { 3470435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3471c62bd62aSJed Brown else if (nz < 0) nz = 1; 3472d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3473d0f46423SBarry Smith nz = nz*B->rmap->n; 3474273d9f13SBarry Smith } else { 3475273d9f13SBarry Smith nz = 0; 3476d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3477273d9f13SBarry Smith } 3478ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3479d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; } 3480ab93d7beSBarry Smith 3481273d9f13SBarry Smith /* allocate the matrix space */ 34822ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3483d0f46423SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr); 3484d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3485bfeeae90SHong Zhang b->i[0] = 0; 3486d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 34875da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 34885da197adSKris Buschelman } 3489273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3490e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3491e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3492c461c341SBarry Smith } else { 3493e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3494e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3495c461c341SBarry Smith } 3496273d9f13SBarry Smith 3497273d9f13SBarry Smith b->nz = 0; 3498273d9f13SBarry Smith b->maxnz = nz; 3499273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 3500273d9f13SBarry Smith PetscFunctionReturn(0); 3501273d9f13SBarry Smith } 3502a23d5eceSKris Buschelman EXTERN_C_END 3503273d9f13SBarry Smith 3504a1661176SMatthew Knepley #undef __FUNCT__ 3505a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 350658d36128SBarry Smith /*@ 3507a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3508a1661176SMatthew Knepley 3509a1661176SMatthew Knepley Input Parameters: 3510a1661176SMatthew Knepley + B - the matrix 3511a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3512a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3513a1661176SMatthew Knepley - v - optional values in the matrix 3514a1661176SMatthew Knepley 3515a1661176SMatthew Knepley Level: developer 3516a1661176SMatthew Knepley 351758d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 351858d36128SBarry Smith 3519a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3520a1661176SMatthew Knepley 3521a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3522a1661176SMatthew Knepley @*/ 3523a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3524a1661176SMatthew Knepley { 3525a1661176SMatthew Knepley PetscErrorCode ierr; 3526a1661176SMatthew Knepley 3527a1661176SMatthew Knepley PetscFunctionBegin; 35280700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35294ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3530a1661176SMatthew Knepley PetscFunctionReturn(0); 3531a1661176SMatthew Knepley } 3532a1661176SMatthew Knepley 3533a1661176SMatthew Knepley EXTERN_C_BEGIN 3534a1661176SMatthew Knepley #undef __FUNCT__ 3535a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 35367087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3537a1661176SMatthew Knepley { 3538a1661176SMatthew Knepley PetscInt i; 3539a1661176SMatthew Knepley PetscInt m,n; 3540a1661176SMatthew Knepley PetscInt nz; 3541a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3542a1661176SMatthew Knepley PetscScalar *values; 3543a1661176SMatthew Knepley PetscErrorCode ierr; 3544a1661176SMatthew Knepley 3545a1661176SMatthew Knepley PetscFunctionBegin; 3546a1661176SMatthew Knepley ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3547a1661176SMatthew Knepley 354865e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3549a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 3550a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3551b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3552a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 355365e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3554a1661176SMatthew Knepley nnz[i] = nz; 3555a1661176SMatthew Knepley } 3556a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3557a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3558a1661176SMatthew Knepley 3559a1661176SMatthew Knepley if (v) { 3560a1661176SMatthew Knepley values = (PetscScalar*) v; 3561a1661176SMatthew Knepley } else { 35620e83c824SBarry Smith ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr); 3563a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 3564a1661176SMatthew Knepley } 3565a1661176SMatthew Knepley 3566a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3567b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3568b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3569a1661176SMatthew Knepley } 3570a1661176SMatthew Knepley 3571a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3572a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3573a1661176SMatthew Knepley 3574a1661176SMatthew Knepley if (!v) { 3575a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3576a1661176SMatthew Knepley } 3577a1661176SMatthew Knepley PetscFunctionReturn(0); 3578a1661176SMatthew Knepley } 3579a1661176SMatthew Knepley EXTERN_C_END 3580a1661176SMatthew Knepley 3581c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3582c6db04a5SJed Brown #include <private/petscaxpy.h> 3583170fe5c8SBarry Smith 3584170fe5c8SBarry Smith #undef __FUNCT__ 3585170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 3586170fe5c8SBarry Smith /* 3587170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3588170fe5c8SBarry Smith 3589170fe5c8SBarry Smith n p p 3590170fe5c8SBarry Smith ( ) ( ) ( ) 3591170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3592170fe5c8SBarry Smith ( ) ( ) ( ) 3593170fe5c8SBarry Smith 3594170fe5c8SBarry Smith */ 3595170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3596170fe5c8SBarry Smith { 3597170fe5c8SBarry Smith PetscErrorCode ierr; 3598170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3599170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3600170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 36011de00fd4SBarry Smith PetscInt i,n,m,q,p; 3602170fe5c8SBarry Smith const PetscInt *ii,*idx; 3603170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3604170fe5c8SBarry Smith PetscScalar *c,*c_q; 3605170fe5c8SBarry Smith 3606170fe5c8SBarry Smith PetscFunctionBegin; 3607d0f46423SBarry Smith m = A->rmap->n; 3608d0f46423SBarry Smith n = A->cmap->n; 3609d0f46423SBarry Smith p = B->cmap->n; 3610170fe5c8SBarry Smith a = sub_a->v; 3611170fe5c8SBarry Smith b = sub_b->a; 3612170fe5c8SBarry Smith c = sub_c->v; 3613170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3614170fe5c8SBarry Smith 3615170fe5c8SBarry Smith ii = sub_b->i; 3616170fe5c8SBarry Smith idx = sub_b->j; 3617170fe5c8SBarry Smith for (i=0; i<n; i++) { 3618170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3619170fe5c8SBarry Smith while (q-->0) { 3620170fe5c8SBarry Smith c_q = c + m*(*idx); 3621170fe5c8SBarry Smith a_q = a + m*i; 3622be7314b0SBarry Smith PetscAXPY(c_q,*b,a_q,m); 3623170fe5c8SBarry Smith idx++; 3624170fe5c8SBarry Smith b++; 3625170fe5c8SBarry Smith } 3626170fe5c8SBarry Smith } 3627170fe5c8SBarry Smith PetscFunctionReturn(0); 3628170fe5c8SBarry Smith } 3629170fe5c8SBarry Smith 3630170fe5c8SBarry Smith #undef __FUNCT__ 3631170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 3632170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3633170fe5c8SBarry Smith { 3634170fe5c8SBarry Smith PetscErrorCode ierr; 3635d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3636170fe5c8SBarry Smith Mat Cmat; 3637170fe5c8SBarry Smith 3638170fe5c8SBarry Smith PetscFunctionBegin; 3639e32f2f54SBarry Smith if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n); 364039804f7cSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr); 3641170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 3642170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 3643170fe5c8SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr); 3644170fe5c8SBarry Smith Cmat->assembled = PETSC_TRUE; 3645170fe5c8SBarry Smith *C = Cmat; 3646170fe5c8SBarry Smith PetscFunctionReturn(0); 3647170fe5c8SBarry Smith } 3648170fe5c8SBarry Smith 3649170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3650170fe5c8SBarry Smith #undef __FUNCT__ 3651170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 3652170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3653170fe5c8SBarry Smith { 3654170fe5c8SBarry Smith PetscErrorCode ierr; 3655170fe5c8SBarry Smith 3656170fe5c8SBarry Smith PetscFunctionBegin; 3657170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX){ 3658170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 3659170fe5c8SBarry Smith } 3660170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 3661170fe5c8SBarry Smith PetscFunctionReturn(0); 3662170fe5c8SBarry Smith } 3663170fe5c8SBarry Smith 3664170fe5c8SBarry Smith 36650bad9183SKris Buschelman /*MC 3666fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 36670bad9183SKris Buschelman based on compressed sparse row format. 36680bad9183SKris Buschelman 36690bad9183SKris Buschelman Options Database Keys: 36700bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 36710bad9183SKris Buschelman 36720bad9183SKris Buschelman Level: beginner 36730bad9183SKris Buschelman 3674f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 36750bad9183SKris Buschelman M*/ 36760bad9183SKris Buschelman 3677a6175056SHong Zhang EXTERN_C_BEGIN 3678b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3679b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 3680b5e56a35SBarry Smith #endif 3681ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 3682af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *); 3683af1023dbSSatish Balay #endif 36847087cfbeSBarry Smith extern PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 36857087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 36867087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 36877087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool *); 3688611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 36897087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 3690611f576cSBarry Smith #endif 3691611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 36927087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 3693611f576cSBarry Smith #endif 3694f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3695f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 3696f3c0ef26SHong Zhang #endif 3697611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 36987087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*); 3699611f576cSBarry Smith #endif 3700eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 37017087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 3702eb3b5408SSatish Balay #endif 3703586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 37047087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 3705586621ddSJed Brown #endif 3706719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 37077087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 3708719d5645SBarry Smith #endif 3709b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 37107087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 37117087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 37127087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3713b3866ffcSBarry Smith #endif 371417667f90SBarry Smith EXTERN_C_END 371517667f90SBarry Smith 371617667f90SBarry Smith EXTERN_C_BEGIN 37174a2ae208SSatish Balay #undef __FUNCT__ 37184a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 37197087cfbeSBarry Smith PetscErrorCode MatCreate_SeqAIJ(Mat B) 3720273d9f13SBarry Smith { 3721273d9f13SBarry Smith Mat_SeqAIJ *b; 3722dfbe8321SBarry Smith PetscErrorCode ierr; 372338baddfdSBarry Smith PetscMPIInt size; 3724273d9f13SBarry Smith 3725273d9f13SBarry Smith PetscFunctionBegin; 37267adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 3727e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3728273d9f13SBarry Smith 372938f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr); 3730b0a32e0cSBarry Smith B->data = (void*)b; 3731549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 3732416022c9SBarry Smith b->row = 0; 3733416022c9SBarry Smith b->col = 0; 373482bf6240SBarry Smith b->icol = 0; 3735b810aeb4SBarry Smith b->reallocs = 0; 373636db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3737f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3738416022c9SBarry Smith b->nonew = 0; 3739416022c9SBarry Smith b->diag = 0; 3740416022c9SBarry Smith b->solve_work = 0; 37412a1b7f2aSHong Zhang B->spptr = 0; 3742be6bf707SBarry Smith b->saved_values = 0; 3743d7f994e1SBarry Smith b->idiag = 0; 374471f1c65dSBarry Smith b->mdiag = 0; 374571f1c65dSBarry Smith b->ssor_work = 0; 374671f1c65dSBarry Smith b->omega = 1.0; 374771f1c65dSBarry Smith b->fshift = 0.0; 374871f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3749a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 3750a30b2313SHong Zhang b->xtoy = 0; 3751a30b2313SHong Zhang b->XtoY = 0; 375288e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 375317ab2063SBarry Smith 375435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3755b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3756700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 3757b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3758b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3759b3866ffcSBarry Smith #endif 3760b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3761700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 3762b5e56a35SBarry Smith #endif 3763ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 3764700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 3765719d5645SBarry Smith #endif 3766611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 3767700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 3768611f576cSBarry Smith #endif 3769f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3770700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 3771f3c0ef26SHong Zhang #endif 3772611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 3773700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr); 3774611f576cSBarry Smith #endif 3775611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 3776700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr); 3777611f576cSBarry Smith #endif 3778eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 3779700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 3780eb3b5408SSatish Balay #endif 3781586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 3782700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 3783586621ddSJed Brown #endif 3784719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 3785700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 3786719d5645SBarry Smith #endif 3787700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 3788700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 3789700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 3790700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3791700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3792700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3793700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3794700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3795700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3796700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3797700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3798700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3799700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3800700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3801700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3802700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3803700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3804700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 38054108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 380617667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 38073a40ed3dSBarry Smith PetscFunctionReturn(0); 380817ab2063SBarry Smith } 3809273d9f13SBarry Smith EXTERN_C_END 381017ab2063SBarry Smith 3811*ff34cdc8SBarry Smith #if defined(PETSC_HAVE_PTHREADCLASSES) 381251d315f7SKerry Stevens EXTERN_C_BEGIN 381351d315f7SKerry Stevens #undef __FUNCT__ 381451d315f7SKerry Stevens #define __FUNCT__ "MatCreate_SeqPThreadAIJ" 381551d315f7SKerry Stevens PetscErrorCode MatCreate_SeqPThreadAIJ(Mat B) 381651d315f7SKerry Stevens { 381751d315f7SKerry Stevens PetscErrorCode ierr; 381851d315f7SKerry Stevens 381951d315f7SKerry Stevens PetscFunctionBegin; 382051d315f7SKerry Stevens ierr = MatCreate_SeqAIJ(B); 382151d315f7SKerry Stevens ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 382251d315f7SKerry Stevens B->ops->mult = MatMult_SeqPThreadAIJ; 382351d315f7SKerry Stevens ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQPTHREADAIJ);CHKERRQ(ierr); 382451d315f7SKerry Stevens PetscFunctionReturn(0); 382551d315f7SKerry Stevens } 382651d315f7SKerry Stevens EXTERN_C_END 3827ba61063dSBarry Smith #endif 382851d315f7SKerry Stevens 38294a2ae208SSatish Balay #undef __FUNCT__ 3830b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 3831b24902e0SBarry Smith /* 3832b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3833b24902e0SBarry Smith */ 3834ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 383517ab2063SBarry Smith { 3836416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 38376849ba73SBarry Smith PetscErrorCode ierr; 3838d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 383917ab2063SBarry Smith 38403a40ed3dSBarry Smith PetscFunctionBegin; 3841273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3842273d9f13SBarry Smith 3843d5f3da31SBarry Smith C->factortype = A->factortype; 3844416022c9SBarry Smith c->row = 0; 3845416022c9SBarry Smith c->col = 0; 384682bf6240SBarry Smith c->icol = 0; 38476ad4291fSHong Zhang c->reallocs = 0; 384817ab2063SBarry Smith 38496ad4291fSHong Zhang C->assembled = PETSC_TRUE; 385017ab2063SBarry Smith 3851aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3852aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3853eec197d1SBarry Smith 385433b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 38559518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 385617ab2063SBarry Smith for (i=0; i<m; i++) { 3857416022c9SBarry Smith c->imax[i] = a->imax[i]; 3858416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 385917ab2063SBarry Smith } 386017ab2063SBarry Smith 386117ab2063SBarry Smith /* allocate the matrix space */ 3862f77e22a1SHong Zhang if (mallocmatspace){ 3863a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 38649518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 3865f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 386697f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 386717ab2063SBarry Smith if (m > 0) { 386897f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3869be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3870bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3871be6bf707SBarry Smith } else { 3872bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 387317ab2063SBarry Smith } 387408480c60SBarry Smith } 3875f77e22a1SHong Zhang } 387617ab2063SBarry Smith 38776ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3878416022c9SBarry Smith c->roworiented = a->roworiented; 3879416022c9SBarry Smith c->nonew = a->nonew; 3880416022c9SBarry Smith if (a->diag) { 388197f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 388252e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 388317ab2063SBarry Smith for (i=0; i<m; i++) { 3884416022c9SBarry Smith c->diag[i] = a->diag[i]; 388517ab2063SBarry Smith } 38863a40ed3dSBarry Smith } else c->diag = 0; 38876ad4291fSHong Zhang c->solve_work = 0; 38886ad4291fSHong Zhang c->saved_values = 0; 38896ad4291fSHong Zhang c->idiag = 0; 389071f1c65dSBarry Smith c->ssor_work = 0; 3891a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 3892e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3893e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 38946ad4291fSHong Zhang c->xtoy = 0; 38956ad4291fSHong Zhang c->XtoY = 0; 38966ad4291fSHong Zhang 3897416022c9SBarry Smith c->nz = a->nz; 38988ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 3899273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 3900754ec7b1SSatish Balay 39016ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 39026ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 3903cd6b891eSBarry Smith c->compressedrow.check = a->compressedrow.check; 3904cd6b891eSBarry Smith if (a->compressedrow.use){ 39056ad4291fSHong Zhang i = a->compressedrow.nrows; 39060e83c824SBarry Smith ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr); 39076ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 39086ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 390927ea64f8SHong Zhang } else { 391027ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 391127ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 391227ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 39136ad4291fSHong Zhang } 391488e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 39154108e4d5SBarry Smith ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 39164846f1f5SKris Buschelman 39177adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 39183a40ed3dSBarry Smith PetscFunctionReturn(0); 391917ab2063SBarry Smith } 392017ab2063SBarry Smith 39214a2ae208SSatish Balay #undef __FUNCT__ 3922b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 3923b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 3924b24902e0SBarry Smith { 3925b24902e0SBarry Smith PetscErrorCode ierr; 3926b24902e0SBarry Smith 3927b24902e0SBarry Smith PetscFunctionBegin; 3928b24902e0SBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 39294b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 3930b24902e0SBarry Smith ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr); 3931f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 3932b24902e0SBarry Smith PetscFunctionReturn(0); 3933b24902e0SBarry Smith } 3934b24902e0SBarry Smith 3935b24902e0SBarry Smith #undef __FUNCT__ 39364a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 3937112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 3938fbdbba38SShri Abhyankar { 3939fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 3940fbdbba38SShri Abhyankar PetscErrorCode ierr; 3941fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 3942fbdbba38SShri Abhyankar int fd; 3943fbdbba38SShri Abhyankar PetscMPIInt size; 3944fbdbba38SShri Abhyankar MPI_Comm comm; 3945fbdbba38SShri Abhyankar 3946fbdbba38SShri Abhyankar PetscFunctionBegin; 3947fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 3948fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3949fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 3950fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 3951fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 3952fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 3953fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 3954fbdbba38SShri Abhyankar 3955fbdbba38SShri Abhyankar if (nz < 0) { 3956fbdbba38SShri Abhyankar SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 3957fbdbba38SShri Abhyankar } 3958fbdbba38SShri Abhyankar 3959fbdbba38SShri Abhyankar /* read in row lengths */ 3960fbdbba38SShri Abhyankar ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 3961fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 3962fbdbba38SShri Abhyankar 3963fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 3964fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 3965fbdbba38SShri Abhyankar if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %d, sum-row-lengths = %d\n",nz,sum); 3966fbdbba38SShri Abhyankar 3967fbdbba38SShri Abhyankar /* set global size if not set already*/ 3968f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 3969fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3970aabbc4fbSShri Abhyankar } else { 3971fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 3972fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 3973f501eaabSShri Abhyankar if (M != rows || N != cols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,rows,cols); 3974aabbc4fbSShri Abhyankar } 3975fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 3976fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 3977fbdbba38SShri Abhyankar 3978fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 3979fbdbba38SShri Abhyankar 3980fbdbba38SShri Abhyankar /* read in nonzero values */ 3981fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 3982fbdbba38SShri Abhyankar 3983fbdbba38SShri Abhyankar /* set matrix "i" values */ 3984fbdbba38SShri Abhyankar a->i[0] = 0; 3985fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 3986fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 3987fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 3988fbdbba38SShri Abhyankar } 3989fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 3990fbdbba38SShri Abhyankar 3991fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3992fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3993fbdbba38SShri Abhyankar PetscFunctionReturn(0); 3994fbdbba38SShri Abhyankar } 3995fbdbba38SShri Abhyankar 3996fbdbba38SShri Abhyankar #undef __FUNCT__ 3997b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3998ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 39997264ac53SSatish Balay { 40007264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 4001dfbe8321SBarry Smith PetscErrorCode ierr; 4002eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4003eeffb40dSHong Zhang PetscInt k; 4004eeffb40dSHong Zhang #endif 40057264ac53SSatish Balay 40063a40ed3dSBarry Smith PetscFunctionBegin; 4007bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4008d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4009ca44d042SBarry Smith *flg = PETSC_FALSE; 4010ca44d042SBarry Smith PetscFunctionReturn(0); 4011bcd2baecSBarry Smith } 40127264ac53SSatish Balay 40137264ac53SSatish Balay /* if the a->i are the same */ 4014d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4015abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 40167264ac53SSatish Balay 40177264ac53SSatish Balay /* if a->j are the same */ 401897f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4019abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4020bcd2baecSBarry Smith 4021bcd2baecSBarry Smith /* if a->a are the same */ 4022eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4023eeffb40dSHong Zhang for (k=0; k<a->nz; k++){ 4024eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){ 4025eeffb40dSHong Zhang *flg = PETSC_FALSE; 40263a40ed3dSBarry Smith PetscFunctionReturn(0); 4027eeffb40dSHong Zhang } 4028eeffb40dSHong Zhang } 4029eeffb40dSHong Zhang #else 4030eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4031eeffb40dSHong Zhang #endif 4032eeffb40dSHong Zhang PetscFunctionReturn(0); 40337264ac53SSatish Balay } 403436db0b34SBarry Smith 40354a2ae208SSatish Balay #undef __FUNCT__ 40364a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 403705869f15SSatish Balay /*@ 403836db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 403936db0b34SBarry Smith provided by the user. 404036db0b34SBarry Smith 4041c75a6043SHong Zhang Collective on MPI_Comm 404236db0b34SBarry Smith 404336db0b34SBarry Smith Input Parameters: 404436db0b34SBarry Smith + comm - must be an MPI communicator of size 1 404536db0b34SBarry Smith . m - number of rows 404636db0b34SBarry Smith . n - number of columns 404736db0b34SBarry Smith . i - row indices 404836db0b34SBarry Smith . j - column indices 404936db0b34SBarry Smith - a - matrix values 405036db0b34SBarry Smith 405136db0b34SBarry Smith Output Parameter: 405236db0b34SBarry Smith . mat - the matrix 405336db0b34SBarry Smith 405436db0b34SBarry Smith Level: intermediate 405536db0b34SBarry Smith 405636db0b34SBarry Smith Notes: 40570551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4058292fb18eSBarry Smith once the matrix is destroyed and not before 405936db0b34SBarry Smith 406036db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 406136db0b34SBarry Smith 4062bfeeae90SHong Zhang The i and j indices are 0 based 406336db0b34SBarry Smith 4064a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4065a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4066a4552177SSatish Balay as shown: 4067a4552177SSatish Balay 4068a4552177SSatish Balay 1 0 0 4069a4552177SSatish Balay 2 0 3 4070a4552177SSatish Balay 4 5 6 4071a4552177SSatish Balay 4072a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 40739985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4074a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4075a4552177SSatish Balay 40769985e31cSBarry Smith 40772fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 407836db0b34SBarry Smith 407936db0b34SBarry Smith @*/ 40807087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 408136db0b34SBarry Smith { 4082dfbe8321SBarry Smith PetscErrorCode ierr; 4083cbcfb4deSHong Zhang PetscInt ii; 408436db0b34SBarry Smith Mat_SeqAIJ *aij; 4085cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4086cbcfb4deSHong Zhang PetscInt jj; 4087cbcfb4deSHong Zhang #endif 408836db0b34SBarry Smith 408936db0b34SBarry Smith PetscFunctionBegin; 4090a96a251dSBarry Smith if (i[0]) { 4091e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 409236db0b34SBarry Smith } 4093f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4094f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4095ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4096ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4097ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4098ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 4099ab93d7beSBarry Smith 410036db0b34SBarry Smith aij->i = i; 410136db0b34SBarry Smith aij->j = j; 410236db0b34SBarry Smith aij->a = a; 410336db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 410436db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4105e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4106e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 410736db0b34SBarry Smith 410836db0b34SBarry Smith for (ii=0; ii<m; ii++) { 410936db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 41102515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 4111e32f2f54SBarry Smith if (i[ii+1] - i[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row length in i (row indices) row = %d length = %d",ii,i[ii+1] - i[ii]); 41129985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4113e32f2f54SBarry Smith if (j[jj] < j[jj-1]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is not sorted",jj-i[ii],j[jj],ii); 4114e32f2f54SBarry Smith if (j[jj] == j[jj]-1) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column entry number %D (actual colum %D) in row %D is identical to previous entry",jj-i[ii],j[jj],ii); 41159985e31cSBarry Smith } 411636db0b34SBarry Smith #endif 411736db0b34SBarry Smith } 41182515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 411936db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 4120e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 4121e32f2f54SBarry Smith if (j[ii] > n - 1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column index to large at location = %d index = %d",ii,j[ii]); 412236db0b34SBarry Smith } 412336db0b34SBarry Smith #endif 412436db0b34SBarry Smith 4125b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4126b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 412736db0b34SBarry Smith PetscFunctionReturn(0); 412836db0b34SBarry Smith } 412936db0b34SBarry Smith 4130cc8ba8e1SBarry Smith #undef __FUNCT__ 4131ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4132dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4133cc8ba8e1SBarry Smith { 4134dfbe8321SBarry Smith PetscErrorCode ierr; 4135cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 413636db0b34SBarry Smith 4137cc8ba8e1SBarry Smith PetscFunctionBegin; 41388ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4139cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4140cc8ba8e1SBarry Smith a->coloring = coloring; 414112c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 414297f1f81fSBarry Smith PetscInt i,*larray; 414312c595b3SBarry Smith ISColoring ocoloring; 414408b6dcc0SBarry Smith ISColoringValue *colors; 414512c595b3SBarry Smith 414612c595b3SBarry Smith /* set coloring for diagonal portion */ 41470e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr); 4148d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 414912c595b3SBarry Smith larray[i] = i; 415012c595b3SBarry Smith } 4151992144d0SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 41520e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 4153d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 415412c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 415512c595b3SBarry Smith } 415612c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4157d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 415812c595b3SBarry Smith a->coloring = ocoloring; 415912c595b3SBarry Smith } 4160cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4161cc8ba8e1SBarry Smith } 4162cc8ba8e1SBarry Smith 4163dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 4164ee4f033dSBarry Smith EXTERN_C_BEGIN 4165c6db04a5SJed Brown #include <adic/ad_utils.h> 4166ee4f033dSBarry Smith EXTERN_C_END 4167cc8ba8e1SBarry Smith 4168cc8ba8e1SBarry Smith #undef __FUNCT__ 4169ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 4170dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 4171cc8ba8e1SBarry Smith { 4172cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4173d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen; 41744440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 417508b6dcc0SBarry Smith ISColoringValue *color; 4176cc8ba8e1SBarry Smith 4177cc8ba8e1SBarry Smith PetscFunctionBegin; 4178e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 41794440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 4180cc8ba8e1SBarry Smith color = a->coloring->colors; 4181cc8ba8e1SBarry Smith /* loop over rows */ 4182cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 4183cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 4184cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 4185cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 4186cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 4187cc8ba8e1SBarry Smith } 41884440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 4189ee4f033dSBarry Smith } 4190ee4f033dSBarry Smith PetscFunctionReturn(0); 4191ee4f033dSBarry Smith } 4192ee4f033dSBarry Smith #endif 4193ee4f033dSBarry Smith 4194ee4f033dSBarry Smith #undef __FUNCT__ 4195ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 419697f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4197ee4f033dSBarry Smith { 4198ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4199d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 420054f21887SBarry Smith MatScalar *v = a->a; 420154f21887SBarry Smith PetscScalar *values = (PetscScalar *)advalues; 420208b6dcc0SBarry Smith ISColoringValue *color; 4203ee4f033dSBarry Smith 4204ee4f033dSBarry Smith PetscFunctionBegin; 4205e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4206ee4f033dSBarry Smith color = a->coloring->colors; 4207ee4f033dSBarry Smith /* loop over rows */ 4208ee4f033dSBarry Smith for (i=0; i<m; i++) { 4209ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4210ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 4211ee4f033dSBarry Smith for (j=0; j<nz; j++) { 4212ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 4213ee4f033dSBarry Smith } 4214ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4215cc8ba8e1SBarry Smith } 4216cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4217cc8ba8e1SBarry Smith } 421836db0b34SBarry Smith 421981824310SBarry Smith /* 422081824310SBarry Smith Special version for direct calls from Fortran 422181824310SBarry Smith */ 4222c6db04a5SJed Brown #include <private/fortranimpl.h> 422381824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 422481824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 422581824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 422681824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 422781824310SBarry Smith #endif 422881824310SBarry Smith 422981824310SBarry Smith /* Change these macros so can be used in void function */ 423081824310SBarry Smith #undef CHKERRQ 42317adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr) 423281824310SBarry Smith #undef SETERRQ2 4233e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 423481824310SBarry Smith 423581824310SBarry Smith EXTERN_C_BEGIN 423681824310SBarry Smith #undef __FUNCT__ 423781824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 42381f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 423981824310SBarry Smith { 424081824310SBarry Smith Mat A = *AA; 424181824310SBarry Smith PetscInt m = *mm, n = *nn; 424281824310SBarry Smith InsertMode is = *isis; 424381824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 424481824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 424581824310SBarry Smith PetscInt *imax,*ai,*ailen; 424681824310SBarry Smith PetscErrorCode ierr; 424781824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 424854f21887SBarry Smith MatScalar *ap,value,*aa; 4249ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4250ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 425181824310SBarry Smith 425281824310SBarry Smith PetscFunctionBegin; 4253d9e2c085SLisandro Dalcin ierr = MatPreallocated(A);CHKERRQ(ierr); 425481824310SBarry Smith imax = a->imax; 425581824310SBarry Smith ai = a->i; 425681824310SBarry Smith ailen = a->ilen; 425781824310SBarry Smith aj = a->j; 425881824310SBarry Smith aa = a->a; 425981824310SBarry Smith 426081824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 426181824310SBarry Smith row = im[k]; 426281824310SBarry Smith if (row < 0) continue; 426381824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4264d0f46423SBarry Smith if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 426581824310SBarry Smith #endif 426681824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 426781824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 426881824310SBarry Smith low = 0; 426981824310SBarry Smith high = nrow; 427081824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 427181824310SBarry Smith if (in[l] < 0) continue; 427281824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4273d0f46423SBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 427481824310SBarry Smith #endif 427581824310SBarry Smith col = in[l]; 427681824310SBarry Smith if (roworiented) { 427781824310SBarry Smith value = v[l + k*n]; 427881824310SBarry Smith } else { 427981824310SBarry Smith value = v[k + l*m]; 428081824310SBarry Smith } 428181824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 428281824310SBarry Smith 428381824310SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 428481824310SBarry Smith lastcol = col; 428581824310SBarry Smith while (high-low > 5) { 428681824310SBarry Smith t = (low+high)/2; 428781824310SBarry Smith if (rp[t] > col) high = t; 428881824310SBarry Smith else low = t; 428981824310SBarry Smith } 429081824310SBarry Smith for (i=low; i<high; i++) { 429181824310SBarry Smith if (rp[i] > col) break; 429281824310SBarry Smith if (rp[i] == col) { 429381824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 429481824310SBarry Smith else ap[i] = value; 429581824310SBarry Smith goto noinsert; 429681824310SBarry Smith } 429781824310SBarry Smith } 429881824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 429981824310SBarry Smith if (nonew == 1) goto noinsert; 43007adad957SLisandro Dalcin if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4301fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 430281824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 430381824310SBarry Smith /* shift up all the later entries in this row */ 430481824310SBarry Smith for (ii=N; ii>=i; ii--) { 430581824310SBarry Smith rp[ii+1] = rp[ii]; 430681824310SBarry Smith ap[ii+1] = ap[ii]; 430781824310SBarry Smith } 430881824310SBarry Smith rp[i] = col; 430981824310SBarry Smith ap[i] = value; 431081824310SBarry Smith noinsert:; 431181824310SBarry Smith low = i + 1; 431281824310SBarry Smith } 431381824310SBarry Smith ailen[row] = nrow; 431481824310SBarry Smith } 431581824310SBarry Smith A->same_nonzero = PETSC_FALSE; 431681824310SBarry Smith PetscFunctionReturnVoid(); 431781824310SBarry Smith } 431881824310SBarry Smith EXTERN_C_END 431962298a1eSBarry Smith 4320