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*ba61063dSBarry Smith #if defined(PETSC_USE_PTHREAD_CLASSES) 12130ca81413SKerry Stevens extern PetscMPIInt PetscMaxThreads; 121451d315f7SKerry 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 //******************* 1387*ba61063dSBarry 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; 139554f21887SBarry Smith PetscScalar *x,*y,*z; 139654f21887SBarry Smith const MatScalar *aa; 1397dfbe8321SBarry Smith PetscErrorCode ierr; 1398d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 1399aa482453SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 140097952fefSHong Zhang PetscInt n,i,jrow,j,*ridx=PETSC_NULL; 1401362ced78SSatish Balay PetscScalar sum; 1402ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 1403e36a17ebSSatish Balay #endif 14049ea0dfa2SSatish Balay 14053a40ed3dSBarry Smith PetscFunctionBegin; 14061ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 14071ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 14082e8a6d31SBarry Smith if (zz != yy) { 14091ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 14102e8a6d31SBarry Smith } else { 14112e8a6d31SBarry Smith z = y; 14122e8a6d31SBarry Smith } 1413bfeeae90SHong Zhang 141497952fefSHong Zhang aj = a->j; 141597952fefSHong Zhang aa = a->a; 1416cddf8d76SBarry Smith ii = a->i; 1417aa482453SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 141897952fefSHong Zhang fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 141902ab625aSSatish Balay #else 14204eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 14214eb6d288SHong Zhang if (zz != yy){ 14224eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 14234eb6d288SHong Zhang } 142497952fefSHong Zhang m = a->compressedrow.nrows; 142597952fefSHong Zhang ii = a->compressedrow.i; 142697952fefSHong Zhang ridx = a->compressedrow.rindex; 142797952fefSHong Zhang for (i=0; i<m; i++){ 142897952fefSHong Zhang n = ii[i+1] - ii[i]; 142997952fefSHong Zhang aj = a->j + ii[i]; 143097952fefSHong Zhang aa = a->a + ii[i]; 143197952fefSHong Zhang sum = y[*ridx]; 143297952fefSHong Zhang for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; 143397952fefSHong Zhang z[*ridx++] = sum; 143497952fefSHong Zhang } 143597952fefSHong Zhang } else { /* do not use compressed row format */ 143617ab2063SBarry Smith for (i=0; i<m; i++) { 14379ea0dfa2SSatish Balay jrow = ii[i]; 14389ea0dfa2SSatish Balay n = ii[i+1] - jrow; 143917ab2063SBarry Smith sum = y[i]; 14409ea0dfa2SSatish Balay for (j=0; j<n; j++) { 144197952fefSHong Zhang sum += aa[jrow]*x[aj[jrow]]; jrow++; 14429ea0dfa2SSatish Balay } 144317ab2063SBarry Smith z[i] = sum; 144417ab2063SBarry Smith } 144597952fefSHong Zhang } 144602ab625aSSatish Balay #endif 1447dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 14481ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 14491ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 14502e8a6d31SBarry Smith if (zz != yy) { 14511ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 14522e8a6d31SBarry Smith } 14538154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14546b375ea7SVictor Minden /* 1455918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1456918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1457918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14586b375ea7SVictor Minden */ 1459918e98c3SVictor Minden #endif 14603a40ed3dSBarry Smith PetscFunctionReturn(0); 146117ab2063SBarry Smith } 146217ab2063SBarry Smith 146317ab2063SBarry Smith /* 146417ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 146517ab2063SBarry Smith */ 14664a2ae208SSatish Balay #undef __FUNCT__ 14674a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1468dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 146917ab2063SBarry Smith { 1470416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14716849ba73SBarry Smith PetscErrorCode ierr; 1472d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 147317ab2063SBarry Smith 14743a40ed3dSBarry Smith PetscFunctionBegin; 147509f38230SBarry Smith if (!a->diag) { 147609f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 14779518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr); 147809f38230SBarry Smith } 1479d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 148009f38230SBarry Smith a->diag[i] = a->i[i+1]; 1481bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1482bfeeae90SHong Zhang if (a->j[j] == i) { 148309f38230SBarry Smith a->diag[i] = j; 148417ab2063SBarry Smith break; 148517ab2063SBarry Smith } 148617ab2063SBarry Smith } 148717ab2063SBarry Smith } 14883a40ed3dSBarry Smith PetscFunctionReturn(0); 148917ab2063SBarry Smith } 149017ab2063SBarry Smith 1491be5855fcSBarry Smith /* 1492be5855fcSBarry Smith Checks for missing diagonals 1493be5855fcSBarry Smith */ 14944a2ae208SSatish Balay #undef __FUNCT__ 14954a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1496ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1497be5855fcSBarry Smith { 1498be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 149997f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1500be5855fcSBarry Smith 1501be5855fcSBarry Smith PetscFunctionBegin; 150209f38230SBarry Smith *missing = PETSC_FALSE; 1503d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 150409f38230SBarry Smith *missing = PETSC_TRUE; 150509f38230SBarry Smith if (d) *d = 0; 150609f38230SBarry Smith PetscInfo(A,"Matrix has no entries therefor is missing diagonal"); 150709f38230SBarry Smith } else { 1508f1e2ffcdSBarry Smith diag = a->diag; 1509d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1510bfeeae90SHong Zhang if (jj[diag[i]] != i) { 151109f38230SBarry Smith *missing = PETSC_TRUE; 151209f38230SBarry Smith if (d) *d = i; 151309f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 151409f38230SBarry Smith } 1515be5855fcSBarry Smith } 1516be5855fcSBarry Smith } 1517be5855fcSBarry Smith PetscFunctionReturn(0); 1518be5855fcSBarry Smith } 1519be5855fcSBarry Smith 152071f1c65dSBarry Smith EXTERN_C_BEGIN 152171f1c65dSBarry Smith #undef __FUNCT__ 152271f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 15237087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 152471f1c65dSBarry Smith { 152571f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 152671f1c65dSBarry Smith PetscErrorCode ierr; 1527d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 152854f21887SBarry Smith MatScalar *v = a->a; 152954f21887SBarry Smith PetscScalar *idiag,*mdiag; 153071f1c65dSBarry Smith 153171f1c65dSBarry Smith PetscFunctionBegin; 153271f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 153371f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 153471f1c65dSBarry Smith diag = a->diag; 153571f1c65dSBarry Smith if (!a->idiag) { 153671f1c65dSBarry Smith ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr); 153771f1c65dSBarry Smith ierr = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 153871f1c65dSBarry Smith v = a->a; 153971f1c65dSBarry Smith } 154071f1c65dSBarry Smith mdiag = a->mdiag; 154171f1c65dSBarry Smith idiag = a->idiag; 154271f1c65dSBarry Smith 1543028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 154471f1c65dSBarry Smith for (i=0; i<m; i++) { 154571f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1546e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 154771f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 154871f1c65dSBarry Smith } 154971f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 155071f1c65dSBarry Smith } else { 155171f1c65dSBarry Smith for (i=0; i<m; i++) { 155271f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 155371f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 155471f1c65dSBarry Smith } 1555dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 155671f1c65dSBarry Smith } 155771f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 155871f1c65dSBarry Smith PetscFunctionReturn(0); 155971f1c65dSBarry Smith } 15605a9745a3SMatthew Knepley EXTERN_C_END 156171f1c65dSBarry Smith 1562c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 15634a2ae208SSatish Balay #undef __FUNCT__ 156441f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 156541f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 156617ab2063SBarry Smith { 1567416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1568e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1569e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 157054f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1571dfbe8321SBarry Smith PetscErrorCode ierr; 1572d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 157397f1f81fSBarry Smith const PetscInt *idx,*diag; 157417ab2063SBarry Smith 15753a40ed3dSBarry Smith PetscFunctionBegin; 1576b965ef7fSBarry Smith its = its*lits; 157791723122SBarry Smith 157871f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 157971f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 158071f1c65dSBarry Smith a->fshift = fshift; 158171f1c65dSBarry Smith a->omega = omega; 1582ed480e8bSBarry Smith 158371f1c65dSBarry Smith diag = a->diag; 158471f1c65dSBarry Smith t = a->ssor_work; 1585ed480e8bSBarry Smith idiag = a->idiag; 158671f1c65dSBarry Smith mdiag = a->mdiag; 1587ed480e8bSBarry Smith 15881ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 15893649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 159071f1c65dSBarry Smith CHKMEMQ; 1591ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 159217ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 159317ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1594ed480e8bSBarry Smith bs = b; 159517ab2063SBarry Smith for (i=0; i<m; i++) { 159671f1c65dSBarry Smith d = fshift + mdiag[i]; 1597416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1598ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1599ed480e8bSBarry Smith v = a->a + diag[i] + 1; 160017ab2063SBarry Smith sum = b[i]*d/omega; 1601003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 160217ab2063SBarry Smith x[i] = sum; 160317ab2063SBarry Smith } 16041ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16053649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1606efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16073a40ed3dSBarry Smith PetscFunctionReturn(0); 160817ab2063SBarry Smith } 1609c783ea89SBarry Smith 161048af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 1611e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 16123a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 161317ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1614887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 161517ab2063SBarry Smith 161617ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 161717ab2063SBarry Smith 1618887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 161917ab2063SBarry Smith */ 162017ab2063SBarry Smith scale = (2.0/omega) - 1.0; 162117ab2063SBarry Smith 162217ab2063SBarry Smith /* x = (E + U)^{-1} b */ 162317ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1624416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1625ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1626ed480e8bSBarry Smith v = a->a + diag[i] + 1; 162717ab2063SBarry Smith sum = b[i]; 1628e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1629ed480e8bSBarry Smith x[i] = sum*idiag[i]; 163017ab2063SBarry Smith } 163117ab2063SBarry Smith 163217ab2063SBarry Smith /* t = b - (2*E - D)x */ 1633416022c9SBarry Smith v = a->a; 1634ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 163517ab2063SBarry Smith 163617ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1637ed480e8bSBarry Smith ts = t; 1638416022c9SBarry Smith diag = a->diag; 163917ab2063SBarry Smith for (i=0; i<m; i++) { 1640416022c9SBarry Smith n = diag[i] - a->i[i]; 1641ed480e8bSBarry Smith idx = a->j + a->i[i]; 1642ed480e8bSBarry Smith v = a->a + a->i[i]; 164317ab2063SBarry Smith sum = t[i]; 1644003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1645ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1646733d66baSBarry Smith /* x = x + t */ 1647733d66baSBarry Smith x[i] += t[i]; 164817ab2063SBarry Smith } 164917ab2063SBarry Smith 1650dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16511ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16523649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16533a40ed3dSBarry Smith PetscFunctionReturn(0); 165417ab2063SBarry Smith } 165517ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 165617ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 165717ab2063SBarry Smith for (i=0; i<m; i++) { 1658416022c9SBarry Smith n = diag[i] - a->i[i]; 1659ed480e8bSBarry Smith idx = a->j + a->i[i]; 1660ed480e8bSBarry Smith v = a->a + a->i[i]; 166117ab2063SBarry Smith sum = b[i]; 1662e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16635c99c7daSBarry Smith t[i] = sum; 1664ed480e8bSBarry Smith x[i] = sum*idiag[i]; 166517ab2063SBarry Smith } 16665c99c7daSBarry Smith xb = t; 1667efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16683a40ed3dSBarry Smith } else xb = b; 166917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 167017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1671416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1672ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1673ed480e8bSBarry Smith v = a->a + diag[i] + 1; 167417ab2063SBarry Smith sum = xb[i]; 1675e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16765c99c7daSBarry Smith if (xb == b) { 1677ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16785c99c7daSBarry Smith } else { 16795c99c7daSBarry Smith x[i] = (1-omega)*x[i] + sum*idiag[i]; 168017ab2063SBarry Smith } 16815c99c7daSBarry Smith } 1682efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 168317ab2063SBarry Smith } 168417ab2063SBarry Smith its--; 168517ab2063SBarry Smith } 168617ab2063SBarry Smith while (its--) { 168717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 168817ab2063SBarry Smith for (i=0; i<m; i++) { 1689416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1690ed480e8bSBarry Smith idx = a->j + a->i[i]; 1691ed480e8bSBarry Smith v = a->a + a->i[i]; 169217ab2063SBarry Smith sum = b[i]; 1693e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1694ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 169517ab2063SBarry Smith } 16969f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 169717ab2063SBarry Smith } 169817ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 169917ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1700416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1701ed480e8bSBarry Smith idx = a->j + a->i[i]; 1702ed480e8bSBarry Smith v = a->a + a->i[i]; 170317ab2063SBarry Smith sum = b[i]; 1704e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1705ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 170617ab2063SBarry Smith } 17079f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 170817ab2063SBarry Smith } 170917ab2063SBarry Smith } 17101ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17113649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 171271f1c65dSBarry Smith CHKMEMQ; PetscFunctionReturn(0); 171317ab2063SBarry Smith } 171417ab2063SBarry Smith 17152af78befSBarry Smith 17164a2ae208SSatish Balay #undef __FUNCT__ 17174a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1718dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 171917ab2063SBarry Smith { 1720416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17214e220ebcSLois Curfman McInnes 17223a40ed3dSBarry Smith PetscFunctionBegin; 17234e220ebcSLois Curfman McInnes info->block_size = 1.0; 17244e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17254e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17264e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17274e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17288e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17297adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1730d5f3da31SBarry Smith if (A->factortype) { 17314e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17324e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17334e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17344e220ebcSLois Curfman McInnes } else { 17354e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17364e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17374e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17384e220ebcSLois Curfman McInnes } 17393a40ed3dSBarry Smith PetscFunctionReturn(0); 174017ab2063SBarry Smith } 174117ab2063SBarry Smith 17424a2ae208SSatish Balay #undef __FUNCT__ 17434a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 17442b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 174517ab2063SBarry Smith { 1746416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17473b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 17486849ba73SBarry Smith PetscErrorCode ierr; 174997b48c8fSBarry Smith const PetscScalar *xx; 175097b48c8fSBarry Smith PetscScalar *bb; 1751ace3abfcSBarry Smith PetscBool missing; 175217ab2063SBarry Smith 17533a40ed3dSBarry Smith PetscFunctionBegin; 175497b48c8fSBarry Smith if (x && b) { 175597b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 175697b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 175797b48c8fSBarry Smith for (i=0; i<N; i++) { 175897b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 175997b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 176097b48c8fSBarry Smith } 176197b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 176297b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 176397b48c8fSBarry Smith } 176497b48c8fSBarry Smith 1765a9817697SBarry Smith if (a->keepnonzeropattern) { 1766f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1767e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1768bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1769f1e2ffcdSBarry Smith } 1770f4df32b1SMatthew Knepley if (diag != 0.0) { 177109f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1772e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1773f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1774f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1775f1e2ffcdSBarry Smith } 1776f1e2ffcdSBarry Smith } 177788e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1778f1e2ffcdSBarry Smith } else { 1779f4df32b1SMatthew Knepley if (diag != 0.0) { 178017ab2063SBarry Smith for (i=0; i<N; i++) { 1781e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 17827ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1783416022c9SBarry Smith a->ilen[rows[i]] = 1; 1784f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1785bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 17867ae801bdSBarry Smith } else { /* in case row was completely empty */ 1787f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 178817ab2063SBarry Smith } 178917ab2063SBarry Smith } 17903a40ed3dSBarry Smith } else { 179117ab2063SBarry Smith for (i=0; i<N; i++) { 1792e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1793416022c9SBarry Smith a->ilen[rows[i]] = 0; 179417ab2063SBarry Smith } 179517ab2063SBarry Smith } 179688e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1797f1e2ffcdSBarry Smith } 179843a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17993a40ed3dSBarry Smith PetscFunctionReturn(0); 180017ab2063SBarry Smith } 180117ab2063SBarry Smith 18024a2ae208SSatish Balay #undef __FUNCT__ 18036e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 18046e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 18056e169961SBarry Smith { 18066e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18076e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18086e169961SBarry Smith PetscErrorCode ierr; 18092b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18106e169961SBarry Smith const PetscScalar *xx; 18116e169961SBarry Smith PetscScalar *bb; 18126e169961SBarry Smith 18136e169961SBarry Smith PetscFunctionBegin; 18146e169961SBarry Smith if (x && b) { 18156e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18166e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18172b40b63fSBarry Smith vecs = PETSC_TRUE; 18186e169961SBarry Smith } 18196e169961SBarry Smith ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr); 18206e169961SBarry Smith ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 18216e169961SBarry Smith for (i=0; i<N; i++) { 18226e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18236e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18246e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18256e169961SBarry Smith } 18266e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18276e169961SBarry Smith if (!zeroed[i]) { 18286e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18296e169961SBarry Smith if (zeroed[a->j[j]]) { 18302b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18316e169961SBarry Smith a->a[j] = 0.0; 18326e169961SBarry Smith } 18336e169961SBarry Smith } 18342b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18356e169961SBarry Smith } 18366e169961SBarry Smith if (x && b) { 18376e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18386e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18396e169961SBarry Smith } 18406e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18416e169961SBarry Smith if (diag != 0.0) { 18426e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18436e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18446e169961SBarry Smith for (i=0; i<N; i++) { 18456e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18466e169961SBarry Smith } 18476e169961SBarry Smith } 18486e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 18496e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18506e169961SBarry Smith PetscFunctionReturn(0); 18516e169961SBarry Smith } 18526e169961SBarry Smith 18536e169961SBarry Smith #undef __FUNCT__ 18544a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1855a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 185617ab2063SBarry Smith { 1857416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 185897f1f81fSBarry Smith PetscInt *itmp; 185917ab2063SBarry Smith 18603a40ed3dSBarry Smith PetscFunctionBegin; 1861e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 186217ab2063SBarry Smith 1863416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1864bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 186517ab2063SBarry Smith if (idx) { 1866bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1867bfeeae90SHong Zhang if (*nz) { 18684e093b46SBarry Smith *idx = itmp; 186917ab2063SBarry Smith } 187017ab2063SBarry Smith else *idx = 0; 187117ab2063SBarry Smith } 18723a40ed3dSBarry Smith PetscFunctionReturn(0); 187317ab2063SBarry Smith } 187417ab2063SBarry Smith 1875bfeeae90SHong Zhang /* remove this function? */ 18764a2ae208SSatish Balay #undef __FUNCT__ 18774a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1878a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 187917ab2063SBarry Smith { 18803a40ed3dSBarry Smith PetscFunctionBegin; 18813a40ed3dSBarry Smith PetscFunctionReturn(0); 188217ab2063SBarry Smith } 188317ab2063SBarry Smith 18844a2ae208SSatish Balay #undef __FUNCT__ 18854a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1886dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 188717ab2063SBarry Smith { 1888416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 188954f21887SBarry Smith MatScalar *v = a->a; 189036db0b34SBarry Smith PetscReal sum = 0.0; 18916849ba73SBarry Smith PetscErrorCode ierr; 189297f1f81fSBarry Smith PetscInt i,j; 189317ab2063SBarry Smith 18943a40ed3dSBarry Smith PetscFunctionBegin; 189517ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1896416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1897aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 189836db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 189917ab2063SBarry Smith #else 190017ab2063SBarry Smith sum += (*v)*(*v); v++; 190117ab2063SBarry Smith #endif 190217ab2063SBarry Smith } 1903064f8208SBarry Smith *nrm = sqrt(sum); 19043a40ed3dSBarry Smith } else if (type == NORM_1) { 190536db0b34SBarry Smith PetscReal *tmp; 190697f1f81fSBarry Smith PetscInt *jj = a->j; 1907d0f46423SBarry Smith ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1908d0f46423SBarry Smith ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr); 1909064f8208SBarry Smith *nrm = 0.0; 1910416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1911bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 191217ab2063SBarry Smith } 1913d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1914064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 191517ab2063SBarry Smith } 1916606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 19173a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1918064f8208SBarry Smith *nrm = 0.0; 1919d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1920bfeeae90SHong Zhang v = a->a + a->i[j]; 192117ab2063SBarry Smith sum = 0.0; 1922416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1923cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 192417ab2063SBarry Smith } 1925064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 192617ab2063SBarry Smith } 19273a40ed3dSBarry Smith } else { 1928e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 192917ab2063SBarry Smith } 19303a40ed3dSBarry Smith PetscFunctionReturn(0); 193117ab2063SBarry Smith } 193217ab2063SBarry Smith 19334a2ae208SSatish Balay #undef __FUNCT__ 19344a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1935fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 193617ab2063SBarry Smith { 1937416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1938416022c9SBarry Smith Mat C; 19396849ba73SBarry Smith PetscErrorCode ierr; 1940d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 194154f21887SBarry Smith MatScalar *array = a->a; 194217ab2063SBarry Smith 19433a40ed3dSBarry Smith PetscFunctionBegin; 1944e32f2f54SBarry 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"); 1945fc4dec0aSBarry Smith 1946fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 1947d0f46423SBarry Smith ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 1948d0f46423SBarry Smith ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr); 1949bfeeae90SHong Zhang 1950bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 19517adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1952d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 19537adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1954ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1955606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 1956a541d17aSBarry Smith } else { 1957a541d17aSBarry Smith C = *B; 1958a541d17aSBarry Smith } 1959a541d17aSBarry Smith 196017ab2063SBarry Smith for (i=0; i<m; i++) { 196117ab2063SBarry Smith len = ai[i+1]-ai[i]; 196287d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1963b9b97703SBarry Smith array += len; 1964b9b97703SBarry Smith aj += len; 196517ab2063SBarry Smith } 19666d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 19676d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 196817ab2063SBarry Smith 1969815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 1970416022c9SBarry Smith *B = C; 197117ab2063SBarry Smith } else { 1972eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 197317ab2063SBarry Smith } 19743a40ed3dSBarry Smith PetscFunctionReturn(0); 197517ab2063SBarry Smith } 197617ab2063SBarry Smith 1977cd0d46ebSvictorle EXTERN_C_BEGIN 1978cd0d46ebSvictorle #undef __FUNCT__ 19795fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 19807087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 1981cd0d46ebSvictorle { 1982cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 198354f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 198454f21887SBarry Smith MatScalar *va,*vb; 19856849ba73SBarry Smith PetscErrorCode ierr; 198697f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1987cd0d46ebSvictorle 1988cd0d46ebSvictorle PetscFunctionBegin; 1989cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1990cd0d46ebSvictorle 1991cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1992cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 19935485867bSBarry Smith if (ma!=nb || na!=mb){ 19945485867bSBarry Smith *f = PETSC_FALSE; 19955485867bSBarry Smith PetscFunctionReturn(0); 19965485867bSBarry Smith } 1997cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1998cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1999cd0d46ebSvictorle va = aij->a; vb = bij->a; 200097f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 200197f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 2002cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2003cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2004cd0d46ebSvictorle 2005cd0d46ebSvictorle *f = PETSC_TRUE; 2006cd0d46ebSvictorle for (i=0; i<ma; i++) { 2007cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 200897f1f81fSBarry Smith PetscInt idc,idr; 20095485867bSBarry Smith PetscScalar vc,vr; 2010cd0d46ebSvictorle /* column/row index/value */ 20115485867bSBarry Smith idc = adx[aptr[i]]; 20125485867bSBarry Smith idr = bdx[bptr[idc]]; 20135485867bSBarry Smith vc = va[aptr[i]]; 20145485867bSBarry Smith vr = vb[bptr[idc]]; 20155485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20165485867bSBarry Smith *f = PETSC_FALSE; 20175485867bSBarry Smith goto done; 2018cd0d46ebSvictorle } else { 20195485867bSBarry Smith aptr[i]++; 20205485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2021cd0d46ebSvictorle } 2022cd0d46ebSvictorle } 2023cd0d46ebSvictorle } 2024cd0d46ebSvictorle done: 2025cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20263aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2027cd0d46ebSvictorle PetscFunctionReturn(0); 2028cd0d46ebSvictorle } 2029cd0d46ebSvictorle EXTERN_C_END 2030cd0d46ebSvictorle 20311cbb95d3SBarry Smith EXTERN_C_BEGIN 20321cbb95d3SBarry Smith #undef __FUNCT__ 20331cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 20347087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 20351cbb95d3SBarry Smith { 20361cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 203754f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 203854f21887SBarry Smith MatScalar *va,*vb; 20391cbb95d3SBarry Smith PetscErrorCode ierr; 20401cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 20411cbb95d3SBarry Smith 20421cbb95d3SBarry Smith PetscFunctionBegin; 20431cbb95d3SBarry Smith bij = (Mat_SeqAIJ *) B->data; 20441cbb95d3SBarry Smith 20451cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 20461cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20471cbb95d3SBarry Smith if (ma!=nb || na!=mb){ 20481cbb95d3SBarry Smith *f = PETSC_FALSE; 20491cbb95d3SBarry Smith PetscFunctionReturn(0); 20501cbb95d3SBarry Smith } 20511cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 20521cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 20531cbb95d3SBarry Smith va = aij->a; vb = bij->a; 20541cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 20551cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 20561cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 20571cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 20581cbb95d3SBarry Smith 20591cbb95d3SBarry Smith *f = PETSC_TRUE; 20601cbb95d3SBarry Smith for (i=0; i<ma; i++) { 20611cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 20621cbb95d3SBarry Smith PetscInt idc,idr; 20631cbb95d3SBarry Smith PetscScalar vc,vr; 20641cbb95d3SBarry Smith /* column/row index/value */ 20651cbb95d3SBarry Smith idc = adx[aptr[i]]; 20661cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 20671cbb95d3SBarry Smith vc = va[aptr[i]]; 20681cbb95d3SBarry Smith vr = vb[bptr[idc]]; 20691cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 20701cbb95d3SBarry Smith *f = PETSC_FALSE; 20711cbb95d3SBarry Smith goto done; 20721cbb95d3SBarry Smith } else { 20731cbb95d3SBarry Smith aptr[i]++; 20741cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 20751cbb95d3SBarry Smith } 20761cbb95d3SBarry Smith } 20771cbb95d3SBarry Smith } 20781cbb95d3SBarry Smith done: 20791cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 20801cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 20811cbb95d3SBarry Smith PetscFunctionReturn(0); 20821cbb95d3SBarry Smith } 20831cbb95d3SBarry Smith EXTERN_C_END 20841cbb95d3SBarry Smith 20859e29f15eSvictorle #undef __FUNCT__ 20869e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 2087ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 20889e29f15eSvictorle { 2089dfbe8321SBarry Smith PetscErrorCode ierr; 20909e29f15eSvictorle PetscFunctionBegin; 20915485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 20929e29f15eSvictorle PetscFunctionReturn(0); 20939e29f15eSvictorle } 20949e29f15eSvictorle 20954a2ae208SSatish Balay #undef __FUNCT__ 20961cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 2097ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 20981cbb95d3SBarry Smith { 20991cbb95d3SBarry Smith PetscErrorCode ierr; 21001cbb95d3SBarry Smith PetscFunctionBegin; 21011cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21021cbb95d3SBarry Smith PetscFunctionReturn(0); 21031cbb95d3SBarry Smith } 21041cbb95d3SBarry Smith 21051cbb95d3SBarry Smith #undef __FUNCT__ 21064a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 2107dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 210817ab2063SBarry Smith { 2109416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 211054f21887SBarry Smith PetscScalar *l,*r,x; 211154f21887SBarry Smith MatScalar *v; 2112dfbe8321SBarry Smith PetscErrorCode ierr; 2113d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 211417ab2063SBarry Smith 21153a40ed3dSBarry Smith PetscFunctionBegin; 211617ab2063SBarry Smith if (ll) { 21173ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21183ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2119e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2120e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21211ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2122416022c9SBarry Smith v = a->a; 212317ab2063SBarry Smith for (i=0; i<m; i++) { 212417ab2063SBarry Smith x = l[i]; 2125416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 212617ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 212717ab2063SBarry Smith } 21281ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2129efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 213017ab2063SBarry Smith } 213117ab2063SBarry Smith if (rr) { 2132e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2133e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21341ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2135416022c9SBarry Smith v = a->a; jj = a->j; 213617ab2063SBarry Smith for (i=0; i<nz; i++) { 2137bfeeae90SHong Zhang (*v++) *= r[*jj++]; 213817ab2063SBarry Smith } 21391ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2140efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 214117ab2063SBarry Smith } 21423a40ed3dSBarry Smith PetscFunctionReturn(0); 214317ab2063SBarry Smith } 214417ab2063SBarry Smith 21454a2ae208SSatish Balay #undef __FUNCT__ 21464a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 214797f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 214817ab2063SBarry Smith { 2149db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 21506849ba73SBarry Smith PetscErrorCode ierr; 2151d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 215297f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 21535d0c19d7SBarry Smith const PetscInt *irow,*icol; 21545d0c19d7SBarry Smith PetscInt nrows,ncols; 215597f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 215654f21887SBarry Smith MatScalar *a_new,*mat_a; 2157416022c9SBarry Smith Mat C; 2158ace3abfcSBarry Smith PetscBool stride,sorted; 215917ab2063SBarry Smith 21603a40ed3dSBarry Smith PetscFunctionBegin; 216114ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 2162e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 216314ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2164e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 216599141d43SSatish Balay 216617ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2167b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2168b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 216917ab2063SBarry Smith 2170fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 21710dbe5b1eSSatish Balay ierr = PetscTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2172fee21e36SBarry Smith if (stride && step == 1) { 217302834360SBarry Smith /* special case of contiguous rows */ 21740e83c824SBarry Smith ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr); 217502834360SBarry Smith /* loop over new rows determining lens and starting points */ 217602834360SBarry Smith for (i=0; i<nrows; i++) { 2177bfeeae90SHong Zhang kstart = ai[irow[i]]; 2178a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 217902834360SBarry Smith for (k=kstart; k<kend; k++) { 2180bfeeae90SHong Zhang if (aj[k] >= first) { 218102834360SBarry Smith starts[i] = k; 218202834360SBarry Smith break; 218302834360SBarry Smith } 218402834360SBarry Smith } 2185a2744918SBarry Smith sum = 0; 218602834360SBarry Smith while (k < kend) { 2187bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2188a2744918SBarry Smith sum++; 218902834360SBarry Smith } 2190a2744918SBarry Smith lens[i] = sum; 219102834360SBarry Smith } 219202834360SBarry Smith /* create submatrix */ 2193cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 219497f1f81fSBarry Smith PetscInt n_cols,n_rows; 219508480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2196e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2197d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 219808480c60SBarry Smith C = *B; 21993a40ed3dSBarry Smith } else { 22007adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 2201f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22027adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2203ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 220408480c60SBarry Smith } 2205db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2206db02288aSLois Curfman McInnes 220702834360SBarry Smith /* loop over rows inserting into submatrix */ 2208db02288aSLois Curfman McInnes a_new = c->a; 2209db02288aSLois Curfman McInnes j_new = c->j; 2210db02288aSLois Curfman McInnes i_new = c->i; 2211bfeeae90SHong Zhang 221202834360SBarry Smith for (i=0; i<nrows; i++) { 2213a2744918SBarry Smith ii = starts[i]; 2214a2744918SBarry Smith lensi = lens[i]; 2215a2744918SBarry Smith for (k=0; k<lensi; k++) { 2216a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 221702834360SBarry Smith } 221887828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2219a2744918SBarry Smith a_new += lensi; 2220a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2221a2744918SBarry Smith c->ilen[i] = lensi; 222202834360SBarry Smith } 22230e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22243a40ed3dSBarry Smith } else { 222502834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22260e83c824SBarry Smith ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr); 222797f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 22280e83c824SBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 222917ab2063SBarry Smith for (i=0; i<ncols; i++) smap[icol[i]] = i+1; 223002834360SBarry Smith /* determine lens of each row */ 223102834360SBarry Smith for (i=0; i<nrows; i++) { 2232bfeeae90SHong Zhang kstart = ai[irow[i]]; 223302834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 223402834360SBarry Smith lens[i] = 0; 223502834360SBarry Smith for (k=kstart; k<kend; k++) { 2236bfeeae90SHong Zhang if (smap[aj[k]]) { 223702834360SBarry Smith lens[i]++; 223802834360SBarry Smith } 223902834360SBarry Smith } 224002834360SBarry Smith } 224117ab2063SBarry Smith /* Create and fill new matrix */ 2242a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2243ace3abfcSBarry Smith PetscBool equal; 22440f5bd95cSBarry Smith 224599141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 2246e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2247d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 22480f5bd95cSBarry Smith if (!equal) { 2249e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 225099141d43SSatish Balay } 2251d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 225208480c60SBarry Smith C = *B; 22533a40ed3dSBarry Smith } else { 22547adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 2255f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22567adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2257ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 225808480c60SBarry Smith } 225999141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 226017ab2063SBarry Smith for (i=0; i<nrows; i++) { 226199141d43SSatish Balay row = irow[i]; 2262bfeeae90SHong Zhang kstart = ai[row]; 226399141d43SSatish Balay kend = kstart + a->ilen[row]; 2264bfeeae90SHong Zhang mat_i = c->i[i]; 226599141d43SSatish Balay mat_j = c->j + mat_i; 226699141d43SSatish Balay mat_a = c->a + mat_i; 226799141d43SSatish Balay mat_ilen = c->ilen + i; 226817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2269bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2270ed480e8bSBarry Smith *mat_j++ = tcol - 1; 227199141d43SSatish Balay *mat_a++ = a->a[k]; 227299141d43SSatish Balay (*mat_ilen)++; 227399141d43SSatish Balay 227417ab2063SBarry Smith } 227517ab2063SBarry Smith } 227617ab2063SBarry Smith } 227702834360SBarry Smith /* Free work space */ 227802834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2279606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2280606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 228102834360SBarry Smith } 22826d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 22836d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 228417ab2063SBarry Smith 228517ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2286416022c9SBarry Smith *B = C; 22873a40ed3dSBarry Smith PetscFunctionReturn(0); 228817ab2063SBarry Smith } 228917ab2063SBarry Smith 22901df811f5SHong Zhang #undef __FUNCT__ 229182d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 229282d44351SHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,Mat* subMat) 229382d44351SHong Zhang { 229482d44351SHong Zhang PetscErrorCode ierr; 229582d44351SHong Zhang Mat B; 229682d44351SHong Zhang 229782d44351SHong Zhang PetscFunctionBegin; 229882d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 229982d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 230082d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 230182d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 230282d44351SHong Zhang *subMat = B; 230382d44351SHong Zhang PetscFunctionReturn(0); 230482d44351SHong Zhang } 230582d44351SHong Zhang 230682d44351SHong Zhang #undef __FUNCT__ 23074a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 23080481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2309a871dcd8SBarry Smith { 231063b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2311dfbe8321SBarry Smith PetscErrorCode ierr; 231263b91edcSBarry Smith Mat outA; 2313ace3abfcSBarry Smith PetscBool row_identity,col_identity; 231463b91edcSBarry Smith 23153a40ed3dSBarry Smith PetscFunctionBegin; 2316e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23171df811f5SHong Zhang 2318b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2319b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2320a871dcd8SBarry Smith 232163b91edcSBarry Smith outA = inA; 2322d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2323c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 23246bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 2325c3122656SLisandro Dalcin a->row = row; 2326c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 23276bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 2328c3122656SLisandro Dalcin a->col = col; 232963b91edcSBarry Smith 233036db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 23316bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 23324c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 233352e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 2334f0ec6fceSSatish Balay 233594a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2336d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 2337d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 233894a9d846SBarry Smith } 233963b91edcSBarry Smith 2340f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2341137fb511SHong Zhang if (row_identity && col_identity) { 2342ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2343137fb511SHong Zhang } else { 2344719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2345137fb511SHong Zhang } 23463a40ed3dSBarry Smith PetscFunctionReturn(0); 2347a871dcd8SBarry Smith } 2348a871dcd8SBarry Smith 23494a2ae208SSatish Balay #undef __FUNCT__ 23504a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2351f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2352f0b747eeSBarry Smith { 2353f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2354f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2355efee365bSSatish Balay PetscErrorCode ierr; 23560805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(a->nz); 23573a40ed3dSBarry Smith 23583a40ed3dSBarry Smith PetscFunctionBegin; 2359f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 2360efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 23613a40ed3dSBarry Smith PetscFunctionReturn(0); 2362f0b747eeSBarry Smith } 2363f0b747eeSBarry Smith 23644a2ae208SSatish Balay #undef __FUNCT__ 23654a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 236697f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2367cddf8d76SBarry Smith { 2368dfbe8321SBarry Smith PetscErrorCode ierr; 236997f1f81fSBarry Smith PetscInt i; 2370cddf8d76SBarry Smith 23713a40ed3dSBarry Smith PetscFunctionBegin; 2372cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2373b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 2374cddf8d76SBarry Smith } 2375cddf8d76SBarry Smith 2376cddf8d76SBarry Smith for (i=0; i<n; i++) { 23776a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2378cddf8d76SBarry Smith } 23793a40ed3dSBarry Smith PetscFunctionReturn(0); 2380cddf8d76SBarry Smith } 2381cddf8d76SBarry Smith 23824a2ae208SSatish Balay #undef __FUNCT__ 23834a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 238497f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 23854dcbc457SBarry Smith { 2386e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23876849ba73SBarry Smith PetscErrorCode ierr; 23885d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 23895d0c19d7SBarry Smith const PetscInt *idx; 239097f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2391f1af5d2fSBarry Smith PetscBT table; 2392bbd702dbSSatish Balay 23933a40ed3dSBarry Smith PetscFunctionBegin; 2394d0f46423SBarry Smith m = A->rmap->n; 2395e4d965acSSatish Balay ai = a->i; 2396bfeeae90SHong Zhang aj = a->j; 23978a047759SSatish Balay 2398e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 239906763907SSatish Balay 240097f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 24016831982aSBarry Smith ierr = PetscBTCreate(m,table);CHKERRQ(ierr); 240206763907SSatish Balay 2403e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2404b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2405e4d965acSSatish Balay isz = 0; 24066831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2407e4d965acSSatish Balay 2408e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 24094dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2410b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2411e4d965acSSatish Balay 2412dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2413e4d965acSSatish Balay for (j=0; j<n ; ++j){ 2414f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 24154dcbc457SBarry Smith } 241606763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 24176bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2418e4d965acSSatish Balay 241904a348a9SBarry Smith k = 0; 242004a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 242104a348a9SBarry Smith n = isz; 242206763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 2423e4d965acSSatish Balay row = nidx[k]; 2424e4d965acSSatish Balay start = ai[row]; 2425e4d965acSSatish Balay end = ai[row+1]; 242604a348a9SBarry Smith for (l = start; l<end ; l++){ 2427efb16452SHong Zhang val = aj[l] ; 2428f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 2429e4d965acSSatish Balay } 2430e4d965acSSatish Balay } 2431e4d965acSSatish Balay } 243270b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2433e4d965acSSatish Balay } 24346831982aSBarry Smith ierr = PetscBTDestroy(table);CHKERRQ(ierr); 2435606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 24363a40ed3dSBarry Smith PetscFunctionReturn(0); 24374dcbc457SBarry Smith } 243817ab2063SBarry Smith 24390513a670SBarry Smith /* -------------------------------------------------------------- */ 24404a2ae208SSatish Balay #undef __FUNCT__ 24414a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2442dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 24430513a670SBarry Smith { 24440513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 24456849ba73SBarry Smith PetscErrorCode ierr; 24463b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 24475d0c19d7SBarry Smith const PetscInt *row,*col; 24485d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 244956cd22aeSBarry Smith IS icolp,irowp; 24503b98c0a2SBarry Smith PetscInt *cwork = PETSC_NULL; 24513b98c0a2SBarry Smith PetscScalar *vwork = PETSC_NULL; 24520513a670SBarry Smith 24533a40ed3dSBarry Smith PetscFunctionBegin; 24544c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 245556cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 24564c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 245756cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 24580513a670SBarry Smith 24590513a670SBarry Smith /* determine lengths of permuted rows */ 246097f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 24610513a670SBarry Smith for (i=0; i<m; i++) { 24620513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 24630513a670SBarry Smith } 24647adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 2465f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 24667adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2467ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2468606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 24690513a670SBarry Smith 247097f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 24710513a670SBarry Smith for (i=0; i<m; i++) { 247232ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 24730513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 2474cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 247532ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 24760513a670SBarry Smith } 2477606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 24783c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 24790513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24800513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 248156cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 248256cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 24836bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 24846bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 24853a40ed3dSBarry Smith PetscFunctionReturn(0); 24860513a670SBarry Smith } 24870513a670SBarry Smith 24884a2ae208SSatish Balay #undef __FUNCT__ 24894a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2490dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2491cb5b572fSBarry Smith { 2492dfbe8321SBarry Smith PetscErrorCode ierr; 2493cb5b572fSBarry Smith 2494cb5b572fSBarry Smith PetscFunctionBegin; 249533f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 249633f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2497be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2498be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2499be6bf707SBarry Smith 2500700c5bfcSBarry 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"); 2501d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2502cb5b572fSBarry Smith } else { 2503cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2504cb5b572fSBarry Smith } 2505cb5b572fSBarry Smith PetscFunctionReturn(0); 2506cb5b572fSBarry Smith } 2507cb5b572fSBarry Smith 25084a2ae208SSatish Balay #undef __FUNCT__ 25094a2ae208SSatish Balay #define __FUNCT__ "MatSetUpPreallocation_SeqAIJ" 2510dfbe8321SBarry Smith PetscErrorCode MatSetUpPreallocation_SeqAIJ(Mat A) 2511273d9f13SBarry Smith { 2512dfbe8321SBarry Smith PetscErrorCode ierr; 2513273d9f13SBarry Smith 2514273d9f13SBarry Smith PetscFunctionBegin; 2515ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2516273d9f13SBarry Smith PetscFunctionReturn(0); 2517273d9f13SBarry Smith } 2518273d9f13SBarry Smith 25194a2ae208SSatish Balay #undef __FUNCT__ 25204a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 2521a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 25226c0721eeSBarry Smith { 25236c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25246c0721eeSBarry Smith PetscFunctionBegin; 25256c0721eeSBarry Smith *array = a->a; 25266c0721eeSBarry Smith PetscFunctionReturn(0); 25276c0721eeSBarry Smith } 25286c0721eeSBarry Smith 25294a2ae208SSatish Balay #undef __FUNCT__ 25304a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 2531dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 25326c0721eeSBarry Smith { 25336c0721eeSBarry Smith PetscFunctionBegin; 25346c0721eeSBarry Smith PetscFunctionReturn(0); 25356c0721eeSBarry Smith } 2536273d9f13SBarry Smith 2537ee4f033dSBarry Smith #undef __FUNCT__ 2538ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2539dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2540ee4f033dSBarry Smith { 25416849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 25426849ba73SBarry Smith PetscErrorCode ierr; 254397f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 2544efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 254587828ca2SBarry Smith PetscScalar *vscale_array; 2546ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2547ee4f033dSBarry Smith Vec w1,w2,w3; 2548ee4f033dSBarry Smith void *fctx = coloring->fctx; 2549ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2550ee4f033dSBarry Smith 2551ee4f033dSBarry Smith PetscFunctionBegin; 2552ee4f033dSBarry Smith if (!coloring->w1) { 2553ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 255452e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 2555ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 255652e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 2557ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 255852e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 2559ee4f033dSBarry Smith } 2560ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2561ee4f033dSBarry Smith 2562ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2563acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr); 2564ee4f033dSBarry Smith if (flg) { 2565ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2566ee4f033dSBarry Smith } else { 2567ace3abfcSBarry Smith PetscBool assembled; 25680b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 25690b9b6f31SBarry Smith if (assembled) { 2570ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2571ee4f033dSBarry Smith } 25720b9b6f31SBarry Smith } 2573ee4f033dSBarry Smith 2574ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2575ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2576ee4f033dSBarry Smith 2577ee4f033dSBarry Smith /* 2578ee4f033dSBarry Smith This is a horrible, horrible, hack. See DMMGComputeJacobian_Multigrid() it inproperly sets 2579ee4f033dSBarry Smith coloring->F for the coarser grids from the finest 2580ee4f033dSBarry Smith */ 2581ee4f033dSBarry Smith if (coloring->F) { 2582ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2583ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2584ee4f033dSBarry Smith if (m1 != m2) { 2585ee4f033dSBarry Smith coloring->F = 0; 2586ee4f033dSBarry Smith } 2587ee4f033dSBarry Smith } 2588ee4f033dSBarry Smith 2589ee4f033dSBarry Smith if (coloring->F) { 2590ee4f033dSBarry Smith w1 = coloring->F; 2591ee4f033dSBarry Smith coloring->F = 0; 2592ee4f033dSBarry Smith } else { 259366f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2594ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 259566f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2596ee4f033dSBarry Smith } 2597ee4f033dSBarry Smith 2598ee4f033dSBarry Smith /* 2599ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2600ee4f033dSBarry Smith */ 26011ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 26021ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2603ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2604ee4f033dSBarry Smith /* 2605ee4f033dSBarry Smith Loop over each column associated with color adding the 2606ee4f033dSBarry Smith perturbation to the vector w3. 2607ee4f033dSBarry Smith */ 2608ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2609ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2610ee4f033dSBarry Smith dx = xx[col]; 2611ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2612ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2613ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2614ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2615ee4f033dSBarry Smith #else 2616ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2617ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2618ee4f033dSBarry Smith #endif 2619ee4f033dSBarry Smith dx *= epsilon; 2620ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2621ee4f033dSBarry Smith } 2622ee4f033dSBarry Smith } 26231ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2624ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2625ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2626ee4f033dSBarry Smith 2627ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2628ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2629ee4f033dSBarry Smith 2630ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2631ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2632ee4f033dSBarry Smith 26331ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2634ee4f033dSBarry Smith /* 2635ee4f033dSBarry Smith Loop over each color 2636ee4f033dSBarry Smith */ 2637ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 263849b058dcSBarry Smith coloring->currentcolor = k; 2639ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 26401ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2641ee4f033dSBarry Smith /* 2642ee4f033dSBarry Smith Loop over each column associated with color adding the 2643ee4f033dSBarry Smith perturbation to the vector w3. 2644ee4f033dSBarry Smith */ 2645ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2646ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2647ee4f033dSBarry Smith dx = xx[col]; 26485b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2649ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2650ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2651ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2652ee4f033dSBarry Smith #else 2653ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2654ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2655ee4f033dSBarry Smith #endif 2656ee4f033dSBarry Smith dx *= epsilon; 2657e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2658ee4f033dSBarry Smith w3_array[col] += dx; 2659ee4f033dSBarry Smith } 26601ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2661ee4f033dSBarry Smith 2662ee4f033dSBarry Smith /* 2663ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2664ee4f033dSBarry Smith */ 2665ee4f033dSBarry Smith 266666f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2667ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 266866f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2669efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2670ee4f033dSBarry Smith 2671ee4f033dSBarry Smith /* 2672ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2673ee4f033dSBarry Smith */ 26741ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2675ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2676ee4f033dSBarry Smith row = coloring->rows[k][l]; 2677ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2678ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2679ee4f033dSBarry Smith srow = row + start; 2680ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2681ee4f033dSBarry Smith } 26821ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2683ee4f033dSBarry Smith } 268449b058dcSBarry Smith coloring->currentcolor = k; 26851ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 26861ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2687ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2688ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2689ee4f033dSBarry Smith PetscFunctionReturn(0); 2690ee4f033dSBarry Smith } 2691ee4f033dSBarry Smith 26928229c054SShri Abhyankar /* 26938229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26948229c054SShri Abhyankar have different nonzero structure. 26958229c054SShri Abhyankar */ 2696ac90fabeSBarry Smith #undef __FUNCT__ 26978229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 26988229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz) 2699ec7775f6SShri Abhyankar { 27008229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 2701ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2702ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2703ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 2704ec7775f6SShri Abhyankar 2705ec7775f6SShri Abhyankar PetscFunctionBegin; 2706ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2707ec7775f6SShri Abhyankar for(i=0; i<m; i++) { 27088af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 27098af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 27108af7cee1SJed Brown nnz[i] = 0; 27118af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 27128af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 27138af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 27148af7cee1SJed Brown nnz[i]++; 27158af7cee1SJed Brown } 27168af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2717ec7775f6SShri Abhyankar } 2718ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2719ec7775f6SShri Abhyankar } 2720ec7775f6SShri Abhyankar 2721ec7775f6SShri Abhyankar #undef __FUNCT__ 2722ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2723f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2724ac90fabeSBarry Smith { 2725dfbe8321SBarry Smith PetscErrorCode ierr; 272697f1f81fSBarry Smith PetscInt i; 2727ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 27280805154bSBarry Smith PetscBLASInt one=1,bnz = PetscBLASIntCast(x->nz); 2729ac90fabeSBarry Smith 2730ac90fabeSBarry Smith PetscFunctionBegin; 2731ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2732f4df32b1SMatthew Knepley PetscScalar alpha = a; 2733f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 2734c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2735a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2736a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 27376bf464f9SBarry Smith ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr); 2738a30b2313SHong Zhang } 2739a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 2740d0f46423SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2741a30b2313SHong Zhang y->XtoY = X; 2742407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2743c537a176SHong Zhang } 2744f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 27451e2582c4SBarry 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); 2746ac90fabeSBarry Smith } else { 27478229c054SShri Abhyankar Mat B; 27488229c054SShri Abhyankar PetscInt *nnz; 274916b2e9dcSShri Abhyankar ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 2750ec7775f6SShri Abhyankar ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr); 2751bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 27524aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 2753ec7775f6SShri Abhyankar ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 27548229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 27558229c054SShri Abhyankar ierr = MatSeqAIJSetPreallocation(B,PETSC_NULL,nnz);CHKERRQ(ierr); 2756ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2757ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 27588229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2759ac90fabeSBarry Smith } 2760ac90fabeSBarry Smith PetscFunctionReturn(0); 2761ac90fabeSBarry Smith } 2762ac90fabeSBarry Smith 2763521d7252SBarry Smith #undef __FUNCT__ 2764521d7252SBarry Smith #define __FUNCT__ "MatSetBlockSize_SeqAIJ" 2765521d7252SBarry Smith PetscErrorCode MatSetBlockSize_SeqAIJ(Mat A,PetscInt bs) 2766521d7252SBarry Smith { 276741c166b1SJed Brown PetscErrorCode ierr; 276841c166b1SJed Brown 2769521d7252SBarry Smith PetscFunctionBegin; 277041c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->rmap,bs);CHKERRQ(ierr); 277141c166b1SJed Brown ierr = PetscLayoutSetBlockSize(A->cmap,bs);CHKERRQ(ierr); 2772521d7252SBarry Smith PetscFunctionReturn(0); 2773521d7252SBarry Smith } 2774521d7252SBarry Smith 2775354c94deSBarry Smith #undef __FUNCT__ 2776354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 27777087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2778354c94deSBarry Smith { 2779354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2780354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2781354c94deSBarry Smith PetscInt i,nz; 2782354c94deSBarry Smith PetscScalar *a; 2783354c94deSBarry Smith 2784354c94deSBarry Smith PetscFunctionBegin; 2785354c94deSBarry Smith nz = aij->nz; 2786354c94deSBarry Smith a = aij->a; 2787354c94deSBarry Smith for (i=0; i<nz; i++) { 2788354c94deSBarry Smith a[i] = PetscConj(a[i]); 2789354c94deSBarry Smith } 2790354c94deSBarry Smith #else 2791354c94deSBarry Smith PetscFunctionBegin; 2792354c94deSBarry Smith #endif 2793354c94deSBarry Smith PetscFunctionReturn(0); 2794354c94deSBarry Smith } 2795354c94deSBarry Smith 2796e34fafa9SBarry Smith #undef __FUNCT__ 2797985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2798985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2799e34fafa9SBarry Smith { 2800e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2801e34fafa9SBarry Smith PetscErrorCode ierr; 2802d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2803e34fafa9SBarry Smith PetscReal atmp; 2804985db425SBarry Smith PetscScalar *x; 2805e34fafa9SBarry Smith MatScalar *aa; 2806e34fafa9SBarry Smith 2807e34fafa9SBarry Smith PetscFunctionBegin; 2808e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2809e34fafa9SBarry Smith aa = a->a; 2810e34fafa9SBarry Smith ai = a->i; 2811e34fafa9SBarry Smith aj = a->j; 2812e34fafa9SBarry Smith 2813985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2814e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2815e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2816e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2817e34fafa9SBarry Smith for (i=0; i<m; i++) { 2818e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 28199189402eSHong Zhang x[i] = 0.0; 2820e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2821985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2822985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2823985db425SBarry Smith aa++; aj++; 2824985db425SBarry Smith } 2825985db425SBarry Smith } 2826985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2827985db425SBarry Smith PetscFunctionReturn(0); 2828985db425SBarry Smith } 2829985db425SBarry Smith 2830985db425SBarry Smith #undef __FUNCT__ 2831985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2832985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2833985db425SBarry Smith { 2834985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2835985db425SBarry Smith PetscErrorCode ierr; 2836d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2837985db425SBarry Smith PetscScalar *x; 2838985db425SBarry Smith MatScalar *aa; 2839985db425SBarry Smith 2840985db425SBarry Smith PetscFunctionBegin; 2841e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2842985db425SBarry Smith aa = a->a; 2843985db425SBarry Smith ai = a->i; 2844985db425SBarry Smith aj = a->j; 2845985db425SBarry Smith 2846985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2847985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2848985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2849e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2850985db425SBarry Smith for (i=0; i<m; i++) { 2851985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2852d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2853985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2854985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2855985db425SBarry Smith x[i] = 0.0; 2856985db425SBarry Smith if (idx) { 2857985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2858985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2859985db425SBarry Smith if (aj[j] > j) { 2860985db425SBarry Smith idx[i] = j; 2861985db425SBarry Smith break; 2862985db425SBarry Smith } 2863985db425SBarry Smith } 2864985db425SBarry Smith } 2865985db425SBarry Smith } 2866985db425SBarry Smith for (j=0; j<ncols; j++){ 2867985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2868985db425SBarry Smith aa++; aj++; 2869985db425SBarry Smith } 2870985db425SBarry Smith } 2871985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2872985db425SBarry Smith PetscFunctionReturn(0); 2873985db425SBarry Smith } 2874985db425SBarry Smith 2875985db425SBarry Smith #undef __FUNCT__ 2876c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 2877c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2878c87e5d42SMatthew Knepley { 2879c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2880c87e5d42SMatthew Knepley PetscErrorCode ierr; 2881c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2882c87e5d42SMatthew Knepley PetscReal atmp; 2883c87e5d42SMatthew Knepley PetscScalar *x; 2884c87e5d42SMatthew Knepley MatScalar *aa; 2885c87e5d42SMatthew Knepley 2886c87e5d42SMatthew Knepley PetscFunctionBegin; 2887e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2888c87e5d42SMatthew Knepley aa = a->a; 2889c87e5d42SMatthew Knepley ai = a->i; 2890c87e5d42SMatthew Knepley aj = a->j; 2891c87e5d42SMatthew Knepley 2892c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2893c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2894c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2895e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2896c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2897c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2898289a08f5SMatthew Knepley if (ncols) { 2899289a08f5SMatthew Knepley /* Get first nonzero */ 2900289a08f5SMatthew Knepley for(j = 0; j < ncols; j++) { 2901289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 2902289a08f5SMatthew Knepley if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;} 2903289a08f5SMatthew Knepley } 2904289a08f5SMatthew Knepley if (j == ncols) {x[i] = *aa; if (idx) idx[i] = *aj;} 2905289a08f5SMatthew Knepley } else { 2906289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2907289a08f5SMatthew Knepley } 2908c87e5d42SMatthew Knepley for(j = 0; j < ncols; j++) { 2909c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2910289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2911c87e5d42SMatthew Knepley aa++; aj++; 2912c87e5d42SMatthew Knepley } 2913c87e5d42SMatthew Knepley } 2914c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2915c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2916c87e5d42SMatthew Knepley } 2917c87e5d42SMatthew Knepley 2918c87e5d42SMatthew Knepley #undef __FUNCT__ 2919985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 2920985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2921985db425SBarry Smith { 2922985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2923985db425SBarry Smith PetscErrorCode ierr; 2924d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2925985db425SBarry Smith PetscScalar *x; 2926985db425SBarry Smith MatScalar *aa; 2927985db425SBarry Smith 2928985db425SBarry Smith PetscFunctionBegin; 2929e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2930985db425SBarry Smith aa = a->a; 2931985db425SBarry Smith ai = a->i; 2932985db425SBarry Smith aj = a->j; 2933985db425SBarry Smith 2934985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2935985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2936985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2937e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2938985db425SBarry Smith for (i=0; i<m; i++) { 2939985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2940d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2941985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2942985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2943985db425SBarry Smith x[i] = 0.0; 2944985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2945985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2946985db425SBarry Smith for (j=0;j<ncols;j++) { 2947985db425SBarry Smith if (aj[j] > j) { 2948985db425SBarry Smith idx[i] = j; 2949985db425SBarry Smith break; 2950985db425SBarry Smith } 2951985db425SBarry Smith } 2952985db425SBarry Smith } 2953985db425SBarry Smith } 2954985db425SBarry Smith for (j=0; j<ncols; j++){ 2955985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2956985db425SBarry Smith aa++; aj++; 2957e34fafa9SBarry Smith } 2958e34fafa9SBarry Smith } 2959e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2960e34fafa9SBarry Smith PetscFunctionReturn(0); 2961e34fafa9SBarry Smith } 29627087cfbeSBarry Smith extern PetscErrorCode MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*); 2963682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 29640a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2965cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2966cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2967cb5b572fSBarry Smith MatMult_SeqAIJ, 296897304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 29697c922b88SBarry Smith MatMultTranspose_SeqAIJ, 29707c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2971db4efbfdSBarry Smith 0, 2972db4efbfdSBarry Smith 0, 2973db4efbfdSBarry Smith 0, 2974db4efbfdSBarry Smith /*10*/ 0, 2975cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2976cb5b572fSBarry Smith 0, 297741f059aeSBarry Smith MatSOR_SeqAIJ, 297817ab2063SBarry Smith MatTranspose_SeqAIJ, 297997304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2980cb5b572fSBarry Smith MatEqual_SeqAIJ, 2981cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2982cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2983cb5b572fSBarry Smith MatNorm_SeqAIJ, 298497304618SKris Buschelman /*20*/ 0, 2985cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 2986cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2987cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2988d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ, 2989db4efbfdSBarry Smith 0, 2990db4efbfdSBarry Smith 0, 2991db4efbfdSBarry Smith 0, 2992db4efbfdSBarry Smith 0, 2993d519adbfSMatthew Knepley /*29*/ MatSetUpPreallocation_SeqAIJ, 2994db4efbfdSBarry Smith 0, 2995db4efbfdSBarry Smith 0, 29966c0721eeSBarry Smith MatGetArray_SeqAIJ, 29976c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2998d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ, 2999cb5b572fSBarry Smith 0, 3000cb5b572fSBarry Smith 0, 3001cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3002cb5b572fSBarry Smith 0, 3003d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ, 3004cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 3005cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3006cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3007cb5b572fSBarry Smith MatCopy_SeqAIJ, 3008d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ, 3009cb5b572fSBarry Smith MatScale_SeqAIJ, 3010cb5b572fSBarry Smith 0, 301179299369SBarry Smith MatDiagonalSet_SeqAIJ, 30126e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 3013d519adbfSMatthew Knepley /*49*/ MatSetBlockSize_SeqAIJ, 30143b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 30153b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 30163b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3017a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 3018d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ, 3019b9617806SBarry Smith 0, 30200513a670SBarry Smith 0, 3021cda55fadSBarry Smith MatPermute_SeqAIJ, 3022cda55fadSBarry Smith 0, 3023d519adbfSMatthew Knepley /*59*/ 0, 3024b9b97703SBarry Smith MatDestroy_SeqAIJ, 3025b9b97703SBarry Smith MatView_SeqAIJ, 3026357abbc8SBarry Smith 0, 3027ee4f033dSBarry Smith 0, 3028d519adbfSMatthew Knepley /*64*/ 0, 3029ee4f033dSBarry Smith 0, 3030ee4f033dSBarry Smith 0, 3031ee4f033dSBarry Smith 0, 3032ee4f033dSBarry Smith 0, 3033d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ, 3034c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3035ee4f033dSBarry Smith 0, 3036ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 3037dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 3038ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 3039dcf5cc72SBarry Smith #else 3040dcf5cc72SBarry Smith 0, 3041dcf5cc72SBarry Smith #endif 3042d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ, 30433acb8795SBarry Smith MatFDColoringApply_AIJ, 304497304618SKris Buschelman 0, 304597304618SKris Buschelman 0, 304697304618SKris Buschelman 0, 30476ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ, 304897304618SKris Buschelman 0, 304997304618SKris Buschelman 0, 305097304618SKris Buschelman 0, 3051bc011b1eSHong Zhang MatLoad_SeqAIJ, 3052d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ, 30531cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 30546284ec50SHong Zhang 0, 30556284ec50SHong Zhang 0, 3056bc011b1eSHong Zhang 0, 3057d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ, 305826be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 305926be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3060d439da42SKris Buschelman MatPtAP_Basic, 30617ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 3062d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ, 3063bc011b1eSHong Zhang MatMatMultTranspose_SeqAIJ_SeqAIJ, 3064bc011b1eSHong Zhang MatMatMultTransposeSymbolic_SeqAIJ_SeqAIJ, 3065bc011b1eSHong Zhang MatMatMultTransposeNumeric_SeqAIJ_SeqAIJ, 30667ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 3067d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 3068609c6c4dSKris Buschelman 0, 3069609c6c4dSKris Buschelman 0, 307087d4246cSBarry Smith MatConjugate_SeqAIJ, 307187d4246cSBarry Smith 0, 3072d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ, 307399cafbc1SBarry Smith MatRealPart_SeqAIJ, 3074f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3075f5edf698SHong Zhang 0, 30762bebee5dSHong Zhang 0, 3077cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ, 3078985db425SBarry Smith 0, 30792af78befSBarry Smith MatGetRowMin_SeqAIJ, 30802af78befSBarry Smith 0, 3081599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3082d519adbfSMatthew Knepley /*114*/0, 3083599ef60dSHong Zhang 0, 30843c2a7987SHong Zhang 0, 3085fe97e370SBarry Smith 0, 3086fbdbba38SShri Abhyankar 0, 3087fbdbba38SShri Abhyankar /*119*/0, 3088fbdbba38SShri Abhyankar 0, 3089fbdbba38SShri Abhyankar 0, 309082d44351SHong Zhang 0, 3091b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 30920716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ, 30930716a85fSBarry Smith MatGetColumnNorms_SeqAIJ 30949e29f15eSvictorle }; 309517ab2063SBarry Smith 3096fb2e594dSBarry Smith EXTERN_C_BEGIN 30974a2ae208SSatish Balay #undef __FUNCT__ 30984a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 30997087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3100bef8e0ddSBarry Smith { 3101bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 310297f1f81fSBarry Smith PetscInt i,nz,n; 3103bef8e0ddSBarry Smith 3104bef8e0ddSBarry Smith PetscFunctionBegin; 3105bef8e0ddSBarry Smith 3106bef8e0ddSBarry Smith nz = aij->maxnz; 3107d0f46423SBarry Smith n = mat->rmap->n; 3108bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3109bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3110bef8e0ddSBarry Smith } 3111bef8e0ddSBarry Smith aij->nz = nz; 3112bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3113bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3114bef8e0ddSBarry Smith } 3115bef8e0ddSBarry Smith 3116bef8e0ddSBarry Smith PetscFunctionReturn(0); 3117bef8e0ddSBarry Smith } 3118fb2e594dSBarry Smith EXTERN_C_END 3119bef8e0ddSBarry Smith 31204a2ae208SSatish Balay #undef __FUNCT__ 31214a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3122bef8e0ddSBarry Smith /*@ 3123bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3124bef8e0ddSBarry Smith in the matrix. 3125bef8e0ddSBarry Smith 3126bef8e0ddSBarry Smith Input Parameters: 3127bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3128bef8e0ddSBarry Smith - indices - the column indices 3129bef8e0ddSBarry Smith 313015091d37SBarry Smith Level: advanced 313115091d37SBarry Smith 3132bef8e0ddSBarry Smith Notes: 3133bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3134bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3135bef8e0ddSBarry Smith of the MatSetValues() operation. 3136bef8e0ddSBarry Smith 3137bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3138d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3139bef8e0ddSBarry Smith 3140bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3141bef8e0ddSBarry Smith 3142b9617806SBarry Smith The indices should start with zero, not one. 3143b9617806SBarry Smith 3144bef8e0ddSBarry Smith @*/ 31457087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3146bef8e0ddSBarry Smith { 31474ac538c5SBarry Smith PetscErrorCode ierr; 3148bef8e0ddSBarry Smith 3149bef8e0ddSBarry Smith PetscFunctionBegin; 31500700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 31514482741eSBarry Smith PetscValidPointer(indices,2); 31524ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr); 3153bef8e0ddSBarry Smith PetscFunctionReturn(0); 3154bef8e0ddSBarry Smith } 3155bef8e0ddSBarry Smith 3156be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3157be6bf707SBarry Smith 3158fb2e594dSBarry Smith EXTERN_C_BEGIN 31594a2ae208SSatish Balay #undef __FUNCT__ 31604a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 31617087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3162be6bf707SBarry Smith { 3163be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 31646849ba73SBarry Smith PetscErrorCode ierr; 3165d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3166be6bf707SBarry Smith 3167be6bf707SBarry Smith PetscFunctionBegin; 3168be6bf707SBarry Smith if (aij->nonew != 1) { 3169e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3170be6bf707SBarry Smith } 3171be6bf707SBarry Smith 3172be6bf707SBarry Smith /* allocate space for values if not already there */ 3173be6bf707SBarry Smith if (!aij->saved_values) { 317487828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 31759518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3176be6bf707SBarry Smith } 3177be6bf707SBarry Smith 3178be6bf707SBarry Smith /* copy values over */ 317987828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3180be6bf707SBarry Smith PetscFunctionReturn(0); 3181be6bf707SBarry Smith } 3182fb2e594dSBarry Smith EXTERN_C_END 3183be6bf707SBarry Smith 31844a2ae208SSatish Balay #undef __FUNCT__ 3185b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3186be6bf707SBarry Smith /*@ 3187be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3188be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3189be6bf707SBarry Smith nonlinear portion. 3190be6bf707SBarry Smith 3191be6bf707SBarry Smith Collect on Mat 3192be6bf707SBarry Smith 3193be6bf707SBarry Smith Input Parameters: 31940e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3195be6bf707SBarry Smith 319615091d37SBarry Smith Level: advanced 319715091d37SBarry Smith 3198be6bf707SBarry Smith Common Usage, with SNESSolve(): 3199be6bf707SBarry Smith $ Create Jacobian matrix 3200be6bf707SBarry Smith $ Set linear terms into matrix 3201be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3202be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3203be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3204512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3205be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3206be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3207be6bf707SBarry Smith $ In your Jacobian routine 3208be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3209be6bf707SBarry Smith $ Set nonlinear terms in matrix 3210be6bf707SBarry Smith 3211be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3212be6bf707SBarry Smith $ // build linear portion of Jacobian 3213512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3214be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3215be6bf707SBarry Smith $ loop over nonlinear iterations 3216be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3217be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3218be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3219be6bf707SBarry Smith $ Solve linear system with Jacobian 3220be6bf707SBarry Smith $ endloop 3221be6bf707SBarry Smith 3222be6bf707SBarry Smith Notes: 3223be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3224512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3225be6bf707SBarry Smith calling this routine. 3226be6bf707SBarry Smith 32270c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 32280c468ba9SBarry Smith and does not allocated additional space. 32290c468ba9SBarry Smith 3230be6bf707SBarry Smith .seealso: MatRetrieveValues() 3231be6bf707SBarry Smith 3232be6bf707SBarry Smith @*/ 32337087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3234be6bf707SBarry Smith { 32354ac538c5SBarry Smith PetscErrorCode ierr; 3236be6bf707SBarry Smith 3237be6bf707SBarry Smith PetscFunctionBegin; 32380700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3239e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3240e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32414ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3242be6bf707SBarry Smith PetscFunctionReturn(0); 3243be6bf707SBarry Smith } 3244be6bf707SBarry Smith 3245fb2e594dSBarry Smith EXTERN_C_BEGIN 32464a2ae208SSatish Balay #undef __FUNCT__ 32474a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 32487087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3249be6bf707SBarry Smith { 3250be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 32516849ba73SBarry Smith PetscErrorCode ierr; 3252d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3253be6bf707SBarry Smith 3254be6bf707SBarry Smith PetscFunctionBegin; 3255be6bf707SBarry Smith if (aij->nonew != 1) { 3256e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3257be6bf707SBarry Smith } 3258be6bf707SBarry Smith if (!aij->saved_values) { 3259e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3260be6bf707SBarry Smith } 3261be6bf707SBarry Smith /* copy values over */ 326287828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3263be6bf707SBarry Smith PetscFunctionReturn(0); 3264be6bf707SBarry Smith } 3265fb2e594dSBarry Smith EXTERN_C_END 3266be6bf707SBarry Smith 32674a2ae208SSatish Balay #undef __FUNCT__ 32684a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3269be6bf707SBarry Smith /*@ 3270be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3271be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3272be6bf707SBarry Smith nonlinear portion. 3273be6bf707SBarry Smith 3274be6bf707SBarry Smith Collect on Mat 3275be6bf707SBarry Smith 3276be6bf707SBarry Smith Input Parameters: 3277be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3278be6bf707SBarry Smith 327915091d37SBarry Smith Level: advanced 328015091d37SBarry Smith 3281be6bf707SBarry Smith .seealso: MatStoreValues() 3282be6bf707SBarry Smith 3283be6bf707SBarry Smith @*/ 32847087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3285be6bf707SBarry Smith { 32864ac538c5SBarry Smith PetscErrorCode ierr; 3287be6bf707SBarry Smith 3288be6bf707SBarry Smith PetscFunctionBegin; 32890700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3290e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3291e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32924ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3293be6bf707SBarry Smith PetscFunctionReturn(0); 3294be6bf707SBarry Smith } 3295be6bf707SBarry Smith 3296f83d6046SBarry Smith 3297be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 32984a2ae208SSatish Balay #undef __FUNCT__ 32994a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 330017ab2063SBarry Smith /*@C 3301682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 33020d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 33036e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 330451c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 33052bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 330617ab2063SBarry Smith 3307db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3308db81eaa0SLois Curfman McInnes 330917ab2063SBarry Smith Input Parameters: 3310db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 331117ab2063SBarry Smith . m - number of rows 331217ab2063SBarry Smith . n - number of columns 331317ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 331451c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 33152bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 331617ab2063SBarry Smith 331717ab2063SBarry Smith Output Parameter: 3318416022c9SBarry Smith . A - the matrix 331917ab2063SBarry Smith 3320175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3321ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3322175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3323175b88e8SBarry Smith 3324b259b22eSLois Curfman McInnes Notes: 332549a6f317SBarry Smith If nnz is given then nz is ignored 332649a6f317SBarry Smith 332717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 332817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 33290002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 333044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 333117ab2063SBarry Smith 333217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3333a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 33343d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 33356da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 333617ab2063SBarry Smith 3337682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 33384fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3339682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 33406c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 33416c7ebb05SLois Curfman McInnes 33426c7ebb05SLois Curfman McInnes Options Database Keys: 3343698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 33449db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 334517ab2063SBarry Smith 3346027ccd11SLois Curfman McInnes Level: intermediate 3347027ccd11SLois Curfman McInnes 334836db0b34SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 334936db0b34SBarry Smith 335017ab2063SBarry Smith @*/ 33517087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 335217ab2063SBarry Smith { 3353dfbe8321SBarry Smith PetscErrorCode ierr; 33546945ee14SBarry Smith 33553a40ed3dSBarry Smith PetscFunctionBegin; 3356f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3357117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3358c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3359d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3360273d9f13SBarry Smith PetscFunctionReturn(0); 3361273d9f13SBarry Smith } 3362273d9f13SBarry Smith 33634a2ae208SSatish Balay #undef __FUNCT__ 33644a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3365273d9f13SBarry Smith /*@C 3366273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3367273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3368273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3369273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3370273d9f13SBarry Smith 3371273d9f13SBarry Smith Collective on MPI_Comm 3372273d9f13SBarry Smith 3373273d9f13SBarry Smith Input Parameters: 3374117016b1SBarry Smith + B - The matrix-free 3375273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3376273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 3377273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 3378273d9f13SBarry Smith 3379273d9f13SBarry Smith Notes: 338049a6f317SBarry Smith If nnz is given then nz is ignored 338149a6f317SBarry Smith 3382273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3383273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3384273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3385273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3386273d9f13SBarry Smith 3387273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3388273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 3389273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3390273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3391273d9f13SBarry Smith 3392aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3393aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3394aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3395aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3396aa95bbe8SBarry Smith 3397a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3398a96a251dSBarry Smith entries or columns indices 3399a96a251dSBarry Smith 3400273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3401273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3402273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3403273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3404273d9f13SBarry Smith 3405273d9f13SBarry Smith Options Database Keys: 3406698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3407698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3408273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3409273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3410273d9f13SBarry Smith the user still MUST index entries starting at 0! 3411273d9f13SBarry Smith 3412273d9f13SBarry Smith Level: intermediate 3413273d9f13SBarry Smith 3414aa95bbe8SBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3415273d9f13SBarry Smith 3416273d9f13SBarry Smith @*/ 34177087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3418273d9f13SBarry Smith { 34194ac538c5SBarry Smith PetscErrorCode ierr; 3420a23d5eceSKris Buschelman 3421a23d5eceSKris Buschelman PetscFunctionBegin; 34224ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3423a23d5eceSKris Buschelman PetscFunctionReturn(0); 3424a23d5eceSKris Buschelman } 3425a23d5eceSKris Buschelman 3426a23d5eceSKris Buschelman EXTERN_C_BEGIN 3427a23d5eceSKris Buschelman #undef __FUNCT__ 3428a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 34297087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3430a23d5eceSKris Buschelman { 3431273d9f13SBarry Smith Mat_SeqAIJ *b; 3432ace3abfcSBarry Smith PetscBool skipallocation = PETSC_FALSE; 34336849ba73SBarry Smith PetscErrorCode ierr; 343497f1f81fSBarry Smith PetscInt i; 3435273d9f13SBarry Smith 3436273d9f13SBarry Smith PetscFunctionBegin; 3437d5d45c9bSBarry Smith 3438a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3439c461c341SBarry Smith skipallocation = PETSC_TRUE; 3440c461c341SBarry Smith nz = 0; 3441c461c341SBarry Smith } 3442c461c341SBarry Smith 344326283091SBarry Smith ierr = PetscLayoutSetBlockSize(B->rmap,1);CHKERRQ(ierr); 344426283091SBarry Smith ierr = PetscLayoutSetBlockSize(B->cmap,1);CHKERRQ(ierr); 344526283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 344626283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3447899cda47SBarry Smith 3448435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3449e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3450b73539f3SBarry Smith if (nnz) { 3451d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3452e32f2f54SBarry 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]); 3453e32f2f54SBarry 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); 3454b73539f3SBarry Smith } 3455b73539f3SBarry Smith } 3456b73539f3SBarry Smith 3457273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3458273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3459273d9f13SBarry Smith 3460ab93d7beSBarry Smith if (!skipallocation) { 34612ee49352SLisandro Dalcin if (!b->imax) { 3462d0f46423SBarry Smith ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr); 3463d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 34642ee49352SLisandro Dalcin } 3465273d9f13SBarry Smith if (!nnz) { 3466435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3467c62bd62aSJed Brown else if (nz < 0) nz = 1; 3468d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3469d0f46423SBarry Smith nz = nz*B->rmap->n; 3470273d9f13SBarry Smith } else { 3471273d9f13SBarry Smith nz = 0; 3472d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3473273d9f13SBarry Smith } 3474ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3475d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; } 3476ab93d7beSBarry Smith 3477273d9f13SBarry Smith /* allocate the matrix space */ 34782ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3479d0f46423SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr); 3480d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3481bfeeae90SHong Zhang b->i[0] = 0; 3482d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 34835da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 34845da197adSKris Buschelman } 3485273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3486e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3487e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3488c461c341SBarry Smith } else { 3489e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3490e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3491c461c341SBarry Smith } 3492273d9f13SBarry Smith 3493273d9f13SBarry Smith b->nz = 0; 3494273d9f13SBarry Smith b->maxnz = nz; 3495273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 3496273d9f13SBarry Smith PetscFunctionReturn(0); 3497273d9f13SBarry Smith } 3498a23d5eceSKris Buschelman EXTERN_C_END 3499273d9f13SBarry Smith 3500a1661176SMatthew Knepley #undef __FUNCT__ 3501a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 350258d36128SBarry Smith /*@ 3503a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3504a1661176SMatthew Knepley 3505a1661176SMatthew Knepley Input Parameters: 3506a1661176SMatthew Knepley + B - the matrix 3507a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3508a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3509a1661176SMatthew Knepley - v - optional values in the matrix 3510a1661176SMatthew Knepley 3511a1661176SMatthew Knepley Level: developer 3512a1661176SMatthew Knepley 351358d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 351458d36128SBarry Smith 3515a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3516a1661176SMatthew Knepley 3517a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3518a1661176SMatthew Knepley @*/ 3519a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3520a1661176SMatthew Knepley { 3521a1661176SMatthew Knepley PetscErrorCode ierr; 3522a1661176SMatthew Knepley 3523a1661176SMatthew Knepley PetscFunctionBegin; 35240700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35254ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3526a1661176SMatthew Knepley PetscFunctionReturn(0); 3527a1661176SMatthew Knepley } 3528a1661176SMatthew Knepley 3529a1661176SMatthew Knepley EXTERN_C_BEGIN 3530a1661176SMatthew Knepley #undef __FUNCT__ 3531a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 35327087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3533a1661176SMatthew Knepley { 3534a1661176SMatthew Knepley PetscInt i; 3535a1661176SMatthew Knepley PetscInt m,n; 3536a1661176SMatthew Knepley PetscInt nz; 3537a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3538a1661176SMatthew Knepley PetscScalar *values; 3539a1661176SMatthew Knepley PetscErrorCode ierr; 3540a1661176SMatthew Knepley 3541a1661176SMatthew Knepley PetscFunctionBegin; 3542a1661176SMatthew Knepley ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3543a1661176SMatthew Knepley 354465e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3545a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 3546a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3547b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3548a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 354965e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3550a1661176SMatthew Knepley nnz[i] = nz; 3551a1661176SMatthew Knepley } 3552a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3553a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3554a1661176SMatthew Knepley 3555a1661176SMatthew Knepley if (v) { 3556a1661176SMatthew Knepley values = (PetscScalar*) v; 3557a1661176SMatthew Knepley } else { 35580e83c824SBarry Smith ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr); 3559a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 3560a1661176SMatthew Knepley } 3561a1661176SMatthew Knepley 3562a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3563b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3564b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3565a1661176SMatthew Knepley } 3566a1661176SMatthew Knepley 3567a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3568a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3569a1661176SMatthew Knepley 3570a1661176SMatthew Knepley if (!v) { 3571a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3572a1661176SMatthew Knepley } 3573a1661176SMatthew Knepley PetscFunctionReturn(0); 3574a1661176SMatthew Knepley } 3575a1661176SMatthew Knepley EXTERN_C_END 3576a1661176SMatthew Knepley 3577c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3578c6db04a5SJed Brown #include <private/petscaxpy.h> 3579170fe5c8SBarry Smith 3580170fe5c8SBarry Smith #undef __FUNCT__ 3581170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 3582170fe5c8SBarry Smith /* 3583170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3584170fe5c8SBarry Smith 3585170fe5c8SBarry Smith n p p 3586170fe5c8SBarry Smith ( ) ( ) ( ) 3587170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3588170fe5c8SBarry Smith ( ) ( ) ( ) 3589170fe5c8SBarry Smith 3590170fe5c8SBarry Smith */ 3591170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3592170fe5c8SBarry Smith { 3593170fe5c8SBarry Smith PetscErrorCode ierr; 3594170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3595170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3596170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 35971de00fd4SBarry Smith PetscInt i,n,m,q,p; 3598170fe5c8SBarry Smith const PetscInt *ii,*idx; 3599170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3600170fe5c8SBarry Smith PetscScalar *c,*c_q; 3601170fe5c8SBarry Smith 3602170fe5c8SBarry Smith PetscFunctionBegin; 3603d0f46423SBarry Smith m = A->rmap->n; 3604d0f46423SBarry Smith n = A->cmap->n; 3605d0f46423SBarry Smith p = B->cmap->n; 3606170fe5c8SBarry Smith a = sub_a->v; 3607170fe5c8SBarry Smith b = sub_b->a; 3608170fe5c8SBarry Smith c = sub_c->v; 3609170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3610170fe5c8SBarry Smith 3611170fe5c8SBarry Smith ii = sub_b->i; 3612170fe5c8SBarry Smith idx = sub_b->j; 3613170fe5c8SBarry Smith for (i=0; i<n; i++) { 3614170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3615170fe5c8SBarry Smith while (q-->0) { 3616170fe5c8SBarry Smith c_q = c + m*(*idx); 3617170fe5c8SBarry Smith a_q = a + m*i; 3618be7314b0SBarry Smith PetscAXPY(c_q,*b,a_q,m); 3619170fe5c8SBarry Smith idx++; 3620170fe5c8SBarry Smith b++; 3621170fe5c8SBarry Smith } 3622170fe5c8SBarry Smith } 3623170fe5c8SBarry Smith PetscFunctionReturn(0); 3624170fe5c8SBarry Smith } 3625170fe5c8SBarry Smith 3626170fe5c8SBarry Smith #undef __FUNCT__ 3627170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 3628170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3629170fe5c8SBarry Smith { 3630170fe5c8SBarry Smith PetscErrorCode ierr; 3631d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3632170fe5c8SBarry Smith Mat Cmat; 3633170fe5c8SBarry Smith 3634170fe5c8SBarry Smith PetscFunctionBegin; 3635e32f2f54SBarry 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); 363639804f7cSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr); 3637170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 3638170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 3639170fe5c8SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr); 3640170fe5c8SBarry Smith Cmat->assembled = PETSC_TRUE; 3641170fe5c8SBarry Smith *C = Cmat; 3642170fe5c8SBarry Smith PetscFunctionReturn(0); 3643170fe5c8SBarry Smith } 3644170fe5c8SBarry Smith 3645170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3646170fe5c8SBarry Smith #undef __FUNCT__ 3647170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 3648170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3649170fe5c8SBarry Smith { 3650170fe5c8SBarry Smith PetscErrorCode ierr; 3651170fe5c8SBarry Smith 3652170fe5c8SBarry Smith PetscFunctionBegin; 3653170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX){ 3654170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 3655170fe5c8SBarry Smith } 3656170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 3657170fe5c8SBarry Smith PetscFunctionReturn(0); 3658170fe5c8SBarry Smith } 3659170fe5c8SBarry Smith 3660170fe5c8SBarry Smith 36610bad9183SKris Buschelman /*MC 3662fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 36630bad9183SKris Buschelman based on compressed sparse row format. 36640bad9183SKris Buschelman 36650bad9183SKris Buschelman Options Database Keys: 36660bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 36670bad9183SKris Buschelman 36680bad9183SKris Buschelman Level: beginner 36690bad9183SKris Buschelman 3670f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 36710bad9183SKris Buschelman M*/ 36720bad9183SKris Buschelman 3673a6175056SHong Zhang EXTERN_C_BEGIN 3674b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3675b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 3676b5e56a35SBarry Smith #endif 3677ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 3678af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *); 3679af1023dbSSatish Balay #endif 36807087cfbeSBarry Smith extern PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 36817087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 36827087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 36837087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool *); 3684611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 36857087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 3686611f576cSBarry Smith #endif 3687611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 36887087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 3689611f576cSBarry Smith #endif 3690f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3691f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 3692f3c0ef26SHong Zhang #endif 3693611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 36947087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*); 3695611f576cSBarry Smith #endif 3696eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 36977087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 3698eb3b5408SSatish Balay #endif 3699586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 37007087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 3701586621ddSJed Brown #endif 3702719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 37037087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 3704719d5645SBarry Smith #endif 3705b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 37067087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 37077087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 37087087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3709b3866ffcSBarry Smith #endif 371017667f90SBarry Smith EXTERN_C_END 371117667f90SBarry Smith 371217667f90SBarry Smith EXTERN_C_BEGIN 37134a2ae208SSatish Balay #undef __FUNCT__ 37144a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 37157087cfbeSBarry Smith PetscErrorCode MatCreate_SeqAIJ(Mat B) 3716273d9f13SBarry Smith { 3717273d9f13SBarry Smith Mat_SeqAIJ *b; 3718dfbe8321SBarry Smith PetscErrorCode ierr; 371938baddfdSBarry Smith PetscMPIInt size; 3720273d9f13SBarry Smith 3721273d9f13SBarry Smith PetscFunctionBegin; 37227adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 3723e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3724273d9f13SBarry Smith 372538f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr); 3726b0a32e0cSBarry Smith B->data = (void*)b; 3727549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 3728416022c9SBarry Smith b->row = 0; 3729416022c9SBarry Smith b->col = 0; 373082bf6240SBarry Smith b->icol = 0; 3731b810aeb4SBarry Smith b->reallocs = 0; 373236db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3733f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3734416022c9SBarry Smith b->nonew = 0; 3735416022c9SBarry Smith b->diag = 0; 3736416022c9SBarry Smith b->solve_work = 0; 37372a1b7f2aSHong Zhang B->spptr = 0; 3738be6bf707SBarry Smith b->saved_values = 0; 3739d7f994e1SBarry Smith b->idiag = 0; 374071f1c65dSBarry Smith b->mdiag = 0; 374171f1c65dSBarry Smith b->ssor_work = 0; 374271f1c65dSBarry Smith b->omega = 1.0; 374371f1c65dSBarry Smith b->fshift = 0.0; 374471f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3745a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 3746a30b2313SHong Zhang b->xtoy = 0; 3747a30b2313SHong Zhang b->XtoY = 0; 374888e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 374917ab2063SBarry Smith 375035d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3751b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3752700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 3753b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3754b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3755b3866ffcSBarry Smith #endif 3756b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3757700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 3758b5e56a35SBarry Smith #endif 3759ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 3760700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 3761719d5645SBarry Smith #endif 3762611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 3763700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 3764611f576cSBarry Smith #endif 3765f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3766700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 3767f3c0ef26SHong Zhang #endif 3768611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 3769700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr); 3770611f576cSBarry Smith #endif 3771611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 3772700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr); 3773611f576cSBarry Smith #endif 3774eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 3775700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 3776eb3b5408SSatish Balay #endif 3777586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 3778700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 3779586621ddSJed Brown #endif 3780719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 3781700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 3782719d5645SBarry Smith #endif 3783700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 3784700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 3785700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 3786700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3787700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3788700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3789700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3790700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3791700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3792700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3793700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3794700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3795700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3796700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3797700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3798700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3799700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3800700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 38014108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 380217667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 38033a40ed3dSBarry Smith PetscFunctionReturn(0); 380417ab2063SBarry Smith } 3805273d9f13SBarry Smith EXTERN_C_END 380617ab2063SBarry Smith 3807*ba61063dSBarry Smith #if defined(PETSC_USE_PTHREAD_CLASSES) 380851d315f7SKerry Stevens EXTERN_C_BEGIN 380951d315f7SKerry Stevens #undef __FUNCT__ 381051d315f7SKerry Stevens #define __FUNCT__ "MatCreate_SeqPThreadAIJ" 381151d315f7SKerry Stevens PetscErrorCode MatCreate_SeqPThreadAIJ(Mat B) 381251d315f7SKerry Stevens { 381351d315f7SKerry Stevens PetscErrorCode ierr; 381451d315f7SKerry Stevens 381551d315f7SKerry Stevens PetscFunctionBegin; 381651d315f7SKerry Stevens ierr = MatCreate_SeqAIJ(B); 381751d315f7SKerry Stevens ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 381851d315f7SKerry Stevens B->ops->mult = MatMult_SeqPThreadAIJ; 381951d315f7SKerry Stevens ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQPTHREADAIJ);CHKERRQ(ierr); 382051d315f7SKerry Stevens PetscFunctionReturn(0); 382151d315f7SKerry Stevens } 382251d315f7SKerry Stevens EXTERN_C_END 3823*ba61063dSBarry Smith #endif 382451d315f7SKerry Stevens 38254a2ae208SSatish Balay #undef __FUNCT__ 3826b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 3827b24902e0SBarry Smith /* 3828b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3829b24902e0SBarry Smith */ 3830ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 383117ab2063SBarry Smith { 3832416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 38336849ba73SBarry Smith PetscErrorCode ierr; 3834d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 383517ab2063SBarry Smith 38363a40ed3dSBarry Smith PetscFunctionBegin; 3837273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3838273d9f13SBarry Smith 3839d5f3da31SBarry Smith C->factortype = A->factortype; 3840416022c9SBarry Smith c->row = 0; 3841416022c9SBarry Smith c->col = 0; 384282bf6240SBarry Smith c->icol = 0; 38436ad4291fSHong Zhang c->reallocs = 0; 384417ab2063SBarry Smith 38456ad4291fSHong Zhang C->assembled = PETSC_TRUE; 384617ab2063SBarry Smith 3847aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3848aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3849eec197d1SBarry Smith 385033b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 38519518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 385217ab2063SBarry Smith for (i=0; i<m; i++) { 3853416022c9SBarry Smith c->imax[i] = a->imax[i]; 3854416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 385517ab2063SBarry Smith } 385617ab2063SBarry Smith 385717ab2063SBarry Smith /* allocate the matrix space */ 3858f77e22a1SHong Zhang if (mallocmatspace){ 3859a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 38609518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 3861f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 386297f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 386317ab2063SBarry Smith if (m > 0) { 386497f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3865be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3866bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3867be6bf707SBarry Smith } else { 3868bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 386917ab2063SBarry Smith } 387008480c60SBarry Smith } 3871f77e22a1SHong Zhang } 387217ab2063SBarry Smith 38736ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3874416022c9SBarry Smith c->roworiented = a->roworiented; 3875416022c9SBarry Smith c->nonew = a->nonew; 3876416022c9SBarry Smith if (a->diag) { 387797f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 387852e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 387917ab2063SBarry Smith for (i=0; i<m; i++) { 3880416022c9SBarry Smith c->diag[i] = a->diag[i]; 388117ab2063SBarry Smith } 38823a40ed3dSBarry Smith } else c->diag = 0; 38836ad4291fSHong Zhang c->solve_work = 0; 38846ad4291fSHong Zhang c->saved_values = 0; 38856ad4291fSHong Zhang c->idiag = 0; 388671f1c65dSBarry Smith c->ssor_work = 0; 3887a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 3888e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3889e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 38906ad4291fSHong Zhang c->xtoy = 0; 38916ad4291fSHong Zhang c->XtoY = 0; 38926ad4291fSHong Zhang 3893416022c9SBarry Smith c->nz = a->nz; 38948ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 3895273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 3896754ec7b1SSatish Balay 38976ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 38986ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 3899cd6b891eSBarry Smith c->compressedrow.check = a->compressedrow.check; 3900cd6b891eSBarry Smith if (a->compressedrow.use){ 39016ad4291fSHong Zhang i = a->compressedrow.nrows; 39020e83c824SBarry Smith ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr); 39036ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 39046ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 390527ea64f8SHong Zhang } else { 390627ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 390727ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 390827ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 39096ad4291fSHong Zhang } 391088e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 39114108e4d5SBarry Smith ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 39124846f1f5SKris Buschelman 39137adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 39143a40ed3dSBarry Smith PetscFunctionReturn(0); 391517ab2063SBarry Smith } 391617ab2063SBarry Smith 39174a2ae208SSatish Balay #undef __FUNCT__ 3918b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 3919b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 3920b24902e0SBarry Smith { 3921b24902e0SBarry Smith PetscErrorCode ierr; 3922b24902e0SBarry Smith 3923b24902e0SBarry Smith PetscFunctionBegin; 3924b24902e0SBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 39254b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 3926b24902e0SBarry Smith ierr = MatSetType(*B,MATSEQAIJ);CHKERRQ(ierr); 3927f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 3928b24902e0SBarry Smith PetscFunctionReturn(0); 3929b24902e0SBarry Smith } 3930b24902e0SBarry Smith 3931b24902e0SBarry Smith #undef __FUNCT__ 39324a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 3933112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 3934fbdbba38SShri Abhyankar { 3935fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 3936fbdbba38SShri Abhyankar PetscErrorCode ierr; 3937fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 3938fbdbba38SShri Abhyankar int fd; 3939fbdbba38SShri Abhyankar PetscMPIInt size; 3940fbdbba38SShri Abhyankar MPI_Comm comm; 3941fbdbba38SShri Abhyankar 3942fbdbba38SShri Abhyankar PetscFunctionBegin; 3943fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 3944fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3945fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 3946fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 3947fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 3948fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 3949fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 3950fbdbba38SShri Abhyankar 3951fbdbba38SShri Abhyankar if (nz < 0) { 3952fbdbba38SShri Abhyankar SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 3953fbdbba38SShri Abhyankar } 3954fbdbba38SShri Abhyankar 3955fbdbba38SShri Abhyankar /* read in row lengths */ 3956fbdbba38SShri Abhyankar ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 3957fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 3958fbdbba38SShri Abhyankar 3959fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 3960fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 3961fbdbba38SShri 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); 3962fbdbba38SShri Abhyankar 3963fbdbba38SShri Abhyankar /* set global size if not set already*/ 3964f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 3965fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3966aabbc4fbSShri Abhyankar } else { 3967fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 3968fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 3969f501eaabSShri 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); 3970aabbc4fbSShri Abhyankar } 3971fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 3972fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 3973fbdbba38SShri Abhyankar 3974fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 3975fbdbba38SShri Abhyankar 3976fbdbba38SShri Abhyankar /* read in nonzero values */ 3977fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 3978fbdbba38SShri Abhyankar 3979fbdbba38SShri Abhyankar /* set matrix "i" values */ 3980fbdbba38SShri Abhyankar a->i[0] = 0; 3981fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 3982fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 3983fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 3984fbdbba38SShri Abhyankar } 3985fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 3986fbdbba38SShri Abhyankar 3987fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3988fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3989fbdbba38SShri Abhyankar PetscFunctionReturn(0); 3990fbdbba38SShri Abhyankar } 3991fbdbba38SShri Abhyankar 3992fbdbba38SShri Abhyankar #undef __FUNCT__ 3993b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3994ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 39957264ac53SSatish Balay { 39967264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3997dfbe8321SBarry Smith PetscErrorCode ierr; 3998eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 3999eeffb40dSHong Zhang PetscInt k; 4000eeffb40dSHong Zhang #endif 40017264ac53SSatish Balay 40023a40ed3dSBarry Smith PetscFunctionBegin; 4003bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4004d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4005ca44d042SBarry Smith *flg = PETSC_FALSE; 4006ca44d042SBarry Smith PetscFunctionReturn(0); 4007bcd2baecSBarry Smith } 40087264ac53SSatish Balay 40097264ac53SSatish Balay /* if the a->i are the same */ 4010d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4011abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 40127264ac53SSatish Balay 40137264ac53SSatish Balay /* if a->j are the same */ 401497f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4015abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4016bcd2baecSBarry Smith 4017bcd2baecSBarry Smith /* if a->a are the same */ 4018eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4019eeffb40dSHong Zhang for (k=0; k<a->nz; k++){ 4020eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){ 4021eeffb40dSHong Zhang *flg = PETSC_FALSE; 40223a40ed3dSBarry Smith PetscFunctionReturn(0); 4023eeffb40dSHong Zhang } 4024eeffb40dSHong Zhang } 4025eeffb40dSHong Zhang #else 4026eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4027eeffb40dSHong Zhang #endif 4028eeffb40dSHong Zhang PetscFunctionReturn(0); 40297264ac53SSatish Balay } 403036db0b34SBarry Smith 40314a2ae208SSatish Balay #undef __FUNCT__ 40324a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 403305869f15SSatish Balay /*@ 403436db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 403536db0b34SBarry Smith provided by the user. 403636db0b34SBarry Smith 4037c75a6043SHong Zhang Collective on MPI_Comm 403836db0b34SBarry Smith 403936db0b34SBarry Smith Input Parameters: 404036db0b34SBarry Smith + comm - must be an MPI communicator of size 1 404136db0b34SBarry Smith . m - number of rows 404236db0b34SBarry Smith . n - number of columns 404336db0b34SBarry Smith . i - row indices 404436db0b34SBarry Smith . j - column indices 404536db0b34SBarry Smith - a - matrix values 404636db0b34SBarry Smith 404736db0b34SBarry Smith Output Parameter: 404836db0b34SBarry Smith . mat - the matrix 404936db0b34SBarry Smith 405036db0b34SBarry Smith Level: intermediate 405136db0b34SBarry Smith 405236db0b34SBarry Smith Notes: 40530551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4054292fb18eSBarry Smith once the matrix is destroyed and not before 405536db0b34SBarry Smith 405636db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 405736db0b34SBarry Smith 4058bfeeae90SHong Zhang The i and j indices are 0 based 405936db0b34SBarry Smith 4060a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4061a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4062a4552177SSatish Balay as shown: 4063a4552177SSatish Balay 4064a4552177SSatish Balay 1 0 0 4065a4552177SSatish Balay 2 0 3 4066a4552177SSatish Balay 4 5 6 4067a4552177SSatish Balay 4068a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 40699985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4070a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4071a4552177SSatish Balay 40729985e31cSBarry Smith 40732fb0ec9aSBarry Smith .seealso: MatCreate(), MatCreateMPIAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 407436db0b34SBarry Smith 407536db0b34SBarry Smith @*/ 40767087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 407736db0b34SBarry Smith { 4078dfbe8321SBarry Smith PetscErrorCode ierr; 4079cbcfb4deSHong Zhang PetscInt ii; 408036db0b34SBarry Smith Mat_SeqAIJ *aij; 4081cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4082cbcfb4deSHong Zhang PetscInt jj; 4083cbcfb4deSHong Zhang #endif 408436db0b34SBarry Smith 408536db0b34SBarry Smith PetscFunctionBegin; 4086a96a251dSBarry Smith if (i[0]) { 4087e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 408836db0b34SBarry Smith } 4089f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4090f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4091ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4092ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4093ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4094ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 4095ab93d7beSBarry Smith 409636db0b34SBarry Smith aij->i = i; 409736db0b34SBarry Smith aij->j = j; 409836db0b34SBarry Smith aij->a = a; 409936db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 410036db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4101e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4102e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 410336db0b34SBarry Smith 410436db0b34SBarry Smith for (ii=0; ii<m; ii++) { 410536db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 41062515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 4107e32f2f54SBarry 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]); 41089985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4109e32f2f54SBarry 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); 4110e32f2f54SBarry 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); 41119985e31cSBarry Smith } 411236db0b34SBarry Smith #endif 411336db0b34SBarry Smith } 41142515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 411536db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 4116e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 4117e32f2f54SBarry 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]); 411836db0b34SBarry Smith } 411936db0b34SBarry Smith #endif 412036db0b34SBarry Smith 4121b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4122b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 412336db0b34SBarry Smith PetscFunctionReturn(0); 412436db0b34SBarry Smith } 412536db0b34SBarry Smith 4126cc8ba8e1SBarry Smith #undef __FUNCT__ 4127ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4128dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4129cc8ba8e1SBarry Smith { 4130dfbe8321SBarry Smith PetscErrorCode ierr; 4131cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 413236db0b34SBarry Smith 4133cc8ba8e1SBarry Smith PetscFunctionBegin; 41348ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4135cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4136cc8ba8e1SBarry Smith a->coloring = coloring; 413712c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 413897f1f81fSBarry Smith PetscInt i,*larray; 413912c595b3SBarry Smith ISColoring ocoloring; 414008b6dcc0SBarry Smith ISColoringValue *colors; 414112c595b3SBarry Smith 414212c595b3SBarry Smith /* set coloring for diagonal portion */ 41430e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr); 4144d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 414512c595b3SBarry Smith larray[i] = i; 414612c595b3SBarry Smith } 4147992144d0SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 41480e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 4149d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 415012c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 415112c595b3SBarry Smith } 415212c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4153d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 415412c595b3SBarry Smith a->coloring = ocoloring; 415512c595b3SBarry Smith } 4156cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4157cc8ba8e1SBarry Smith } 4158cc8ba8e1SBarry Smith 4159dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 4160ee4f033dSBarry Smith EXTERN_C_BEGIN 4161c6db04a5SJed Brown #include <adic/ad_utils.h> 4162ee4f033dSBarry Smith EXTERN_C_END 4163cc8ba8e1SBarry Smith 4164cc8ba8e1SBarry Smith #undef __FUNCT__ 4165ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 4166dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 4167cc8ba8e1SBarry Smith { 4168cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4169d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen; 41704440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 417108b6dcc0SBarry Smith ISColoringValue *color; 4172cc8ba8e1SBarry Smith 4173cc8ba8e1SBarry Smith PetscFunctionBegin; 4174e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 41754440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 4176cc8ba8e1SBarry Smith color = a->coloring->colors; 4177cc8ba8e1SBarry Smith /* loop over rows */ 4178cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 4179cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 4180cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 4181cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 4182cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 4183cc8ba8e1SBarry Smith } 41844440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 4185ee4f033dSBarry Smith } 4186ee4f033dSBarry Smith PetscFunctionReturn(0); 4187ee4f033dSBarry Smith } 4188ee4f033dSBarry Smith #endif 4189ee4f033dSBarry Smith 4190ee4f033dSBarry Smith #undef __FUNCT__ 4191ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 419297f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4193ee4f033dSBarry Smith { 4194ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4195d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 419654f21887SBarry Smith MatScalar *v = a->a; 419754f21887SBarry Smith PetscScalar *values = (PetscScalar *)advalues; 419808b6dcc0SBarry Smith ISColoringValue *color; 4199ee4f033dSBarry Smith 4200ee4f033dSBarry Smith PetscFunctionBegin; 4201e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4202ee4f033dSBarry Smith color = a->coloring->colors; 4203ee4f033dSBarry Smith /* loop over rows */ 4204ee4f033dSBarry Smith for (i=0; i<m; i++) { 4205ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4206ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 4207ee4f033dSBarry Smith for (j=0; j<nz; j++) { 4208ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 4209ee4f033dSBarry Smith } 4210ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4211cc8ba8e1SBarry Smith } 4212cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4213cc8ba8e1SBarry Smith } 421436db0b34SBarry Smith 421581824310SBarry Smith /* 421681824310SBarry Smith Special version for direct calls from Fortran 421781824310SBarry Smith */ 4218c6db04a5SJed Brown #include <private/fortranimpl.h> 421981824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 422081824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 422181824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 422281824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 422381824310SBarry Smith #endif 422481824310SBarry Smith 422581824310SBarry Smith /* Change these macros so can be used in void function */ 422681824310SBarry Smith #undef CHKERRQ 42277adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr) 422881824310SBarry Smith #undef SETERRQ2 4229e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 423081824310SBarry Smith 423181824310SBarry Smith EXTERN_C_BEGIN 423281824310SBarry Smith #undef __FUNCT__ 423381824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 42341f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 423581824310SBarry Smith { 423681824310SBarry Smith Mat A = *AA; 423781824310SBarry Smith PetscInt m = *mm, n = *nn; 423881824310SBarry Smith InsertMode is = *isis; 423981824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 424081824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 424181824310SBarry Smith PetscInt *imax,*ai,*ailen; 424281824310SBarry Smith PetscErrorCode ierr; 424381824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 424454f21887SBarry Smith MatScalar *ap,value,*aa; 4245ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4246ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 424781824310SBarry Smith 424881824310SBarry Smith PetscFunctionBegin; 4249d9e2c085SLisandro Dalcin ierr = MatPreallocated(A);CHKERRQ(ierr); 425081824310SBarry Smith imax = a->imax; 425181824310SBarry Smith ai = a->i; 425281824310SBarry Smith ailen = a->ilen; 425381824310SBarry Smith aj = a->j; 425481824310SBarry Smith aa = a->a; 425581824310SBarry Smith 425681824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 425781824310SBarry Smith row = im[k]; 425881824310SBarry Smith if (row < 0) continue; 425981824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4260d0f46423SBarry Smith if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 426181824310SBarry Smith #endif 426281824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 426381824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 426481824310SBarry Smith low = 0; 426581824310SBarry Smith high = nrow; 426681824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 426781824310SBarry Smith if (in[l] < 0) continue; 426881824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4269d0f46423SBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 427081824310SBarry Smith #endif 427181824310SBarry Smith col = in[l]; 427281824310SBarry Smith if (roworiented) { 427381824310SBarry Smith value = v[l + k*n]; 427481824310SBarry Smith } else { 427581824310SBarry Smith value = v[k + l*m]; 427681824310SBarry Smith } 427781824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 427881824310SBarry Smith 427981824310SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 428081824310SBarry Smith lastcol = col; 428181824310SBarry Smith while (high-low > 5) { 428281824310SBarry Smith t = (low+high)/2; 428381824310SBarry Smith if (rp[t] > col) high = t; 428481824310SBarry Smith else low = t; 428581824310SBarry Smith } 428681824310SBarry Smith for (i=low; i<high; i++) { 428781824310SBarry Smith if (rp[i] > col) break; 428881824310SBarry Smith if (rp[i] == col) { 428981824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 429081824310SBarry Smith else ap[i] = value; 429181824310SBarry Smith goto noinsert; 429281824310SBarry Smith } 429381824310SBarry Smith } 429481824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 429581824310SBarry Smith if (nonew == 1) goto noinsert; 42967adad957SLisandro Dalcin if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4297fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 429881824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 429981824310SBarry Smith /* shift up all the later entries in this row */ 430081824310SBarry Smith for (ii=N; ii>=i; ii--) { 430181824310SBarry Smith rp[ii+1] = rp[ii]; 430281824310SBarry Smith ap[ii+1] = ap[ii]; 430381824310SBarry Smith } 430481824310SBarry Smith rp[i] = col; 430581824310SBarry Smith ap[i] = value; 430681824310SBarry Smith noinsert:; 430781824310SBarry Smith low = i + 1; 430881824310SBarry Smith } 430981824310SBarry Smith ailen[row] = nrow; 431081824310SBarry Smith } 431181824310SBarry Smith A->same_nonzero = PETSC_FALSE; 431281824310SBarry Smith PetscFunctionReturnVoid(); 431381824310SBarry Smith } 431481824310SBarry Smith EXTERN_C_END 431562298a1eSBarry Smith 4316