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> 11d441b888SJed Brown #include <../src/mat/blocktranspose.h> 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) { 398f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 400716a85fSBarry Smith } 410716a85fSBarry Smith PetscFunctionReturn(0); 420716a85fSBarry Smith } 430716a85fSBarry Smith 444a2ae208SSatish Balay #undef __FUNCT__ 45f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ_Private" 46f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **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 } 70f1f41ecbSJed Brown *nrows = cnt; 71f1f41ecbSJed Brown *zrows = rows; 72f1f41ecbSJed Brown PetscFunctionReturn(0); 73f1f41ecbSJed Brown } 74f1f41ecbSJed Brown 75f1f41ecbSJed Brown #undef __FUNCT__ 76f1f41ecbSJed Brown #define __FUNCT__ "MatFindZeroDiagonals_SeqAIJ" 77f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 78f1f41ecbSJed Brown { 79f1f41ecbSJed Brown PetscInt nrows,*rows; 80f1f41ecbSJed Brown PetscErrorCode ierr; 81f1f41ecbSJed Brown 82f1f41ecbSJed Brown PetscFunctionBegin; 83f1f41ecbSJed Brown *zrows = PETSC_NULL; 84f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 85f1f41ecbSJed Brown ierr = ISCreateGeneral(((PetscObject)A)->comm,nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 866ce1633cSBarry Smith PetscFunctionReturn(0); 876ce1633cSBarry Smith } 886ce1633cSBarry Smith 896ce1633cSBarry Smith #undef __FUNCT__ 90b3a44c85SBarry Smith #define __FUNCT__ "MatFindNonzeroRows_SeqAIJ" 91b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 92b3a44c85SBarry Smith { 93b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 94b3a44c85SBarry Smith const MatScalar *aa; 95b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 96b3a44c85SBarry Smith const PetscInt *ii; 97b3a44c85SBarry Smith PetscInt n,i,j,*rows; 98b3a44c85SBarry Smith PetscErrorCode ierr; 99b3a44c85SBarry Smith 100b3a44c85SBarry Smith PetscFunctionBegin; 101b3a44c85SBarry Smith *keptrows = 0; 102b3a44c85SBarry Smith ii = a->i; 103b3a44c85SBarry Smith for (i=0; i<m; i++) { 104b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 105b3a44c85SBarry Smith if (!n) { 106b3a44c85SBarry Smith cnt++; 107b3a44c85SBarry Smith goto ok1; 108b3a44c85SBarry Smith } 109b3a44c85SBarry Smith aa = a->a + ii[i]; 110b3a44c85SBarry Smith for (j=0; j<n; j++) { 111b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 112b3a44c85SBarry Smith } 113b3a44c85SBarry Smith cnt++; 114b3a44c85SBarry Smith ok1:; 115b3a44c85SBarry Smith } 116b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 117b3a44c85SBarry Smith ierr = PetscMalloc((A->rmap->n-cnt)*sizeof(PetscInt),&rows);CHKERRQ(ierr); 118b3a44c85SBarry Smith cnt = 0; 119b3a44c85SBarry Smith for (i=0; i<m; i++) { 120b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 121b3a44c85SBarry Smith if (!n) continue; 122b3a44c85SBarry Smith aa = a->a + ii[i]; 123b3a44c85SBarry Smith for (j=0; j<n; j++) { 124b3a44c85SBarry Smith if (aa[j] != 0.0) { 125b3a44c85SBarry Smith rows[cnt++] = i; 126b3a44c85SBarry Smith break; 127b3a44c85SBarry Smith } 128b3a44c85SBarry Smith } 129b3a44c85SBarry Smith } 130b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 131b3a44c85SBarry Smith PetscFunctionReturn(0); 132b3a44c85SBarry Smith } 133b3a44c85SBarry Smith 134b3a44c85SBarry Smith #undef __FUNCT__ 13579299369SBarry Smith #define __FUNCT__ "MatDiagonalSet_SeqAIJ" 1367087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 13779299369SBarry Smith { 13879299369SBarry Smith PetscErrorCode ierr; 13979299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 140d0f46423SBarry Smith PetscInt i,*diag, m = Y->rmap->n; 14154f21887SBarry Smith MatScalar *aa = aij->a; 14254f21887SBarry Smith PetscScalar *v; 143ace3abfcSBarry Smith PetscBool missing; 14479299369SBarry Smith 14579299369SBarry Smith PetscFunctionBegin; 14609f38230SBarry Smith if (Y->assembled) { 14709f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,PETSC_NULL);CHKERRQ(ierr); 14809f38230SBarry Smith if (!missing) { 14979299369SBarry Smith diag = aij->diag; 15079299369SBarry Smith ierr = VecGetArray(D,&v);CHKERRQ(ierr); 15179299369SBarry Smith if (is == INSERT_VALUES) { 15279299369SBarry Smith for (i=0; i<m; i++) { 15379299369SBarry Smith aa[diag[i]] = v[i]; 15479299369SBarry Smith } 15579299369SBarry Smith } else { 15679299369SBarry Smith for (i=0; i<m; i++) { 15779299369SBarry Smith aa[diag[i]] += v[i]; 15879299369SBarry Smith } 15979299369SBarry Smith } 16079299369SBarry Smith ierr = VecRestoreArray(D,&v);CHKERRQ(ierr); 16179299369SBarry Smith PetscFunctionReturn(0); 16279299369SBarry Smith } 1630847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 16409f38230SBarry Smith } 16509f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 16609f38230SBarry Smith PetscFunctionReturn(0); 16709f38230SBarry Smith } 16879299369SBarry Smith 16979299369SBarry Smith #undef __FUNCT__ 1704a2ae208SSatish Balay #define __FUNCT__ "MatGetRowIJ_SeqAIJ" 171ace3abfcSBarry Smith PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 17217ab2063SBarry Smith { 173416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 174dfbe8321SBarry Smith PetscErrorCode ierr; 17597f1f81fSBarry Smith PetscInt i,ishift; 17617ab2063SBarry Smith 1773a40ed3dSBarry Smith PetscFunctionBegin; 178d0f46423SBarry Smith *m = A->rmap->n; 1793a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 180bfeeae90SHong Zhang ishift = 0; 18153e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 182d0f46423SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,ishift,oshift,ia,ja);CHKERRQ(ierr); 183bfeeae90SHong Zhang } else if (oshift == 1) { 184d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 1853b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 186d0f46423SBarry Smith ierr = PetscMalloc((A->rmap->n+1)*sizeof(PetscInt),ia);CHKERRQ(ierr); 187d0f46423SBarry Smith for (i=0; i<A->rmap->n+1; i++) (*ia)[i] = a->i[i] + 1; 188ecc77c7aSBarry Smith if (ja) { 18997f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),ja);CHKERRQ(ierr); 1903b2fbd54SBarry Smith for (i=0; i<nz; i++) (*ja)[i] = a->j[i] + 1; 191ecc77c7aSBarry Smith } 1926945ee14SBarry Smith } else { 193ecc77c7aSBarry Smith *ia = a->i; 194ecc77c7aSBarry Smith if (ja) *ja = a->j; 195a2ce50c7SBarry Smith } 1963a40ed3dSBarry Smith PetscFunctionReturn(0); 197a2744918SBarry Smith } 198a2744918SBarry Smith 1994a2ae208SSatish Balay #undef __FUNCT__ 2004a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRowIJ_SeqAIJ" 201ace3abfcSBarry Smith PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 2026945ee14SBarry Smith { 203dfbe8321SBarry Smith PetscErrorCode ierr; 2046945ee14SBarry Smith 2053a40ed3dSBarry Smith PetscFunctionBegin; 2063a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 207bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 208606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 209ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 210bcd2baecSBarry Smith } 2113a40ed3dSBarry Smith PetscFunctionReturn(0); 21217ab2063SBarry Smith } 21317ab2063SBarry Smith 2144a2ae208SSatish Balay #undef __FUNCT__ 2154a2ae208SSatish Balay #define __FUNCT__ "MatGetColumnIJ_SeqAIJ" 216ace3abfcSBarry Smith PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 2173b2fbd54SBarry Smith { 2183b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 219dfbe8321SBarry Smith PetscErrorCode ierr; 220d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 22197f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2223b2fbd54SBarry Smith 2233a40ed3dSBarry Smith PetscFunctionBegin; 224899cda47SBarry Smith *nn = n; 2253a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2263b2fbd54SBarry Smith if (symmetric) { 227d0f46423SBarry Smith ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,ia,ja);CHKERRQ(ierr); 2283b2fbd54SBarry Smith } else { 22997f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 23097f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 23197f1f81fSBarry Smith ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 23297f1f81fSBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 2333b2fbd54SBarry Smith jj = a->j; 2343b2fbd54SBarry Smith for (i=0; i<nz; i++) { 235bfeeae90SHong Zhang collengths[jj[i]]++; 2363b2fbd54SBarry Smith } 2373b2fbd54SBarry Smith cia[0] = oshift; 2383b2fbd54SBarry Smith for (i=0; i<n; i++) { 2393b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2403b2fbd54SBarry Smith } 24197f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2423b2fbd54SBarry Smith jj = a->j; 243a93ec695SBarry Smith for (row=0; row<m; row++) { 244a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 245a93ec695SBarry Smith for (i=0; i<mr; i++) { 246bfeeae90SHong Zhang col = *jj++; 2473b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2483b2fbd54SBarry Smith } 2493b2fbd54SBarry Smith } 250606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2513b2fbd54SBarry Smith *ia = cia; *ja = cja; 2523b2fbd54SBarry Smith } 2533a40ed3dSBarry Smith PetscFunctionReturn(0); 2543b2fbd54SBarry Smith } 2553b2fbd54SBarry Smith 2564a2ae208SSatish Balay #undef __FUNCT__ 2574a2ae208SSatish Balay #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ" 258ace3abfcSBarry Smith PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,PetscInt *ia[],PetscInt *ja[],PetscBool *done) 2593b2fbd54SBarry Smith { 260dfbe8321SBarry Smith PetscErrorCode ierr; 261606d414cSSatish Balay 2623a40ed3dSBarry Smith PetscFunctionBegin; 2633a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2643b2fbd54SBarry Smith 265606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 266606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2673b2fbd54SBarry Smith 2683a40ed3dSBarry Smith PetscFunctionReturn(0); 2693b2fbd54SBarry Smith } 2703b2fbd54SBarry Smith 27187d4246cSBarry Smith #undef __FUNCT__ 27287d4246cSBarry Smith #define __FUNCT__ "MatSetValuesRow_SeqAIJ" 27387d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 27487d4246cSBarry Smith { 27587d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 27687d4246cSBarry Smith PetscInt *ai = a->i; 27787d4246cSBarry Smith PetscErrorCode ierr; 27887d4246cSBarry Smith 27987d4246cSBarry Smith PetscFunctionBegin; 28087d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 28187d4246cSBarry Smith PetscFunctionReturn(0); 28287d4246cSBarry Smith } 28387d4246cSBarry Smith 2844a2ae208SSatish Balay #undef __FUNCT__ 2854a2ae208SSatish Balay #define __FUNCT__ "MatSetValues_SeqAIJ" 28697f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 28717ab2063SBarry Smith { 288416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 289e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 29097f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 2916849ba73SBarry Smith PetscErrorCode ierr; 292e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 29354f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 294ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 295ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 29617ab2063SBarry Smith 2973a40ed3dSBarry Smith PetscFunctionBegin; 29871fd2e92SBarry Smith if (v) PetscValidScalarPointer(v,6); 29917ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 300416022c9SBarry Smith row = im[k]; 3015ef9f2a5SBarry Smith if (row < 0) continue; 3022515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 303e32f2f54SBarry 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); 3043b2fbd54SBarry Smith #endif 305bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 30617ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 307416022c9SBarry Smith low = 0; 308c71e6ed7SBarry Smith high = nrow; 30917ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 3105ef9f2a5SBarry Smith if (in[l] < 0) continue; 3112515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 312e32f2f54SBarry 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); 3133b2fbd54SBarry Smith #endif 314bfeeae90SHong Zhang col = in[l]; 31516371a99SBarry Smith if (v) { 3164b0e389bSBarry Smith if (roworiented) { 3175ef9f2a5SBarry Smith value = v[l + k*n]; 318bef8e0ddSBarry Smith } else { 3194b0e389bSBarry Smith value = v[k + l*m]; 3204b0e389bSBarry Smith } 32116371a99SBarry Smith } else { 32275567043SBarry Smith value = 0.; 32316371a99SBarry Smith } 324abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 32536db0b34SBarry Smith 3267cd84e04SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 327e2ee6c50SBarry Smith lastcol = col; 328416022c9SBarry Smith while (high-low > 5) { 329416022c9SBarry Smith t = (low+high)/2; 330416022c9SBarry Smith if (rp[t] > col) high = t; 331416022c9SBarry Smith else low = t; 33217ab2063SBarry Smith } 333416022c9SBarry Smith for (i=low; i<high; i++) { 33417ab2063SBarry Smith if (rp[i] > col) break; 33517ab2063SBarry Smith if (rp[i] == col) { 336416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 33717ab2063SBarry Smith else ap[i] = value; 338e44c0bd4SBarry Smith low = i + 1; 33917ab2063SBarry Smith goto noinsert; 34017ab2063SBarry Smith } 34117ab2063SBarry Smith } 342abc0a331SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 343c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 344e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 345fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 346c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 347416022c9SBarry Smith /* shift up all the later entries in this row */ 348416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 34917ab2063SBarry Smith rp[ii+1] = rp[ii]; 35017ab2063SBarry Smith ap[ii+1] = ap[ii]; 35117ab2063SBarry Smith } 35217ab2063SBarry Smith rp[i] = col; 35317ab2063SBarry Smith ap[i] = value; 354416022c9SBarry Smith low = i + 1; 355e44c0bd4SBarry Smith noinsert:; 35617ab2063SBarry Smith } 35717ab2063SBarry Smith ailen[row] = nrow; 35817ab2063SBarry Smith } 35988e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 3603a40ed3dSBarry Smith PetscFunctionReturn(0); 36117ab2063SBarry Smith } 36217ab2063SBarry Smith 36381824310SBarry Smith 3644a2ae208SSatish Balay #undef __FUNCT__ 3654a2ae208SSatish Balay #define __FUNCT__ "MatGetValues_SeqAIJ" 366a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 3677eb43aa7SLois Curfman McInnes { 3687eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 36997f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 37097f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 37154f21887SBarry Smith MatScalar *ap,*aa = a->a; 3727eb43aa7SLois Curfman McInnes 3733a40ed3dSBarry Smith PetscFunctionBegin; 3747eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 3757eb43aa7SLois Curfman McInnes row = im[k]; 376e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 377e32f2f54SBarry 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); 378bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 3797eb43aa7SLois Curfman McInnes nrow = ailen[row]; 3807eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 381e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 382e32f2f54SBarry 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); 383bfeeae90SHong Zhang col = in[l] ; 3847eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 3857eb43aa7SLois Curfman McInnes while (high-low > 5) { 3867eb43aa7SLois Curfman McInnes t = (low+high)/2; 3877eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 3887eb43aa7SLois Curfman McInnes else low = t; 3897eb43aa7SLois Curfman McInnes } 3907eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 3917eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 3927eb43aa7SLois Curfman McInnes if (rp[i] == col) { 393b49de8d1SLois Curfman McInnes *v++ = ap[i]; 3947eb43aa7SLois Curfman McInnes goto finished; 3957eb43aa7SLois Curfman McInnes } 3967eb43aa7SLois Curfman McInnes } 39797e567efSBarry Smith *v++ = 0.0; 3987eb43aa7SLois Curfman McInnes finished:; 3997eb43aa7SLois Curfman McInnes } 4007eb43aa7SLois Curfman McInnes } 4013a40ed3dSBarry Smith PetscFunctionReturn(0); 4027eb43aa7SLois Curfman McInnes } 4037eb43aa7SLois Curfman McInnes 40417ab2063SBarry Smith 4054a2ae208SSatish Balay #undef __FUNCT__ 4064a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Binary" 407dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 40817ab2063SBarry Smith { 409416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4106849ba73SBarry Smith PetscErrorCode ierr; 4116f69ff64SBarry Smith PetscInt i,*col_lens; 4126f69ff64SBarry Smith int fd; 41317ab2063SBarry Smith 4143a40ed3dSBarry Smith PetscFunctionBegin; 415b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 416d0f46423SBarry Smith ierr = PetscMalloc((4+A->rmap->n)*sizeof(PetscInt),&col_lens);CHKERRQ(ierr); 4170700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 418d0f46423SBarry Smith col_lens[1] = A->rmap->n; 419d0f46423SBarry Smith col_lens[2] = A->cmap->n; 420416022c9SBarry Smith col_lens[3] = a->nz; 421416022c9SBarry Smith 422416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 423d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 424416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 42517ab2063SBarry Smith } 426d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 427606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 428416022c9SBarry Smith 429416022c9SBarry Smith /* store column indices (zero start index) */ 4306f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 431416022c9SBarry Smith 432416022c9SBarry Smith /* store nonzero values */ 4336f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 4343a40ed3dSBarry Smith PetscFunctionReturn(0); 43517ab2063SBarry Smith } 436416022c9SBarry Smith 43709573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 438cd155464SBarry Smith 4394a2ae208SSatish Balay #undef __FUNCT__ 4404a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_ASCII" 441dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 442416022c9SBarry Smith { 443416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 444dfbe8321SBarry Smith PetscErrorCode ierr; 445d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,shift=0; 446e060cb09SBarry Smith const char *name; 447f3ef73ceSBarry Smith PetscViewerFormat format; 44817ab2063SBarry Smith 4493a40ed3dSBarry Smith PetscFunctionBegin; 450b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 45171c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 45297f1f81fSBarry Smith PetscInt nofinalvalue = 0; 453d0f46423SBarry Smith if ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-!shift)) { 454d00d2cf4SBarry Smith nofinalvalue = 1; 455d00d2cf4SBarry Smith } 456d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 457d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 45877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 45977431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 460b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 46117ab2063SBarry Smith 46217ab2063SBarry Smith for (i=0; i<m; i++) { 463416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 464aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 46577431f27SBarry 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); 46617ab2063SBarry Smith #else 46777431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+!shift,a->a[j]);CHKERRQ(ierr); 46817ab2063SBarry Smith #endif 46917ab2063SBarry Smith } 47017ab2063SBarry Smith } 471d00d2cf4SBarry Smith if (nofinalvalue) { 472d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 473d00d2cf4SBarry Smith } 474317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 475fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 476d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 47768369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 478cd155464SBarry Smith PetscFunctionReturn(0); 479fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 480d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 4817566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 48244cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 48377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 48444cd7ae7SLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 485aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 48636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 487a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 48836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 489a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 49036db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 491a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 4926831982aSBarry Smith } 49344cd7ae7SLois Curfman McInnes #else 494a83599f4SBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr);} 49544cd7ae7SLois Curfman McInnes #endif 49644cd7ae7SLois Curfman McInnes } 497b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 49844cd7ae7SLois Curfman McInnes } 499d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 500fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 50197f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 502d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5037566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 50497f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&sptr);CHKERRQ(ierr); 505496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 506496be53dSLois Curfman McInnes sptr[i] = nzd+1; 507496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 508496be53dSLois Curfman McInnes if (a->j[j] >= i) { 509aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 51036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 511496be53dSLois Curfman McInnes #else 512496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 513496be53dSLois Curfman McInnes #endif 514496be53dSLois Curfman McInnes } 515496be53dSLois Curfman McInnes } 516496be53dSLois Curfman McInnes } 5172e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 51877431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 5192e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 52077431f27SBarry 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);} 52177431f27SBarry 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);} 52277431f27SBarry 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);} 52377431f27SBarry Smith else if (i+1<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr);} 52477431f27SBarry Smith else if (i<m) {ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr);} 52577431f27SBarry Smith else {ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr);} 526496be53dSLois Curfman McInnes } 527b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 528606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 529496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 530496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 53177431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 532496be53dSLois Curfman McInnes } 533b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 534496be53dSLois Curfman McInnes } 535b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 536496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 537496be53dSLois Curfman McInnes for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 538496be53dSLois Curfman McInnes if (a->j[j] >= i) { 539aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 54036db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 541b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 5426831982aSBarry Smith } 543496be53dSLois Curfman McInnes #else 544b0a32e0cSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",a->a[j]);CHKERRQ(ierr);} 545496be53dSLois Curfman McInnes #endif 546496be53dSLois Curfman McInnes } 547496be53dSLois Curfman McInnes } 548b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 549496be53dSLois Curfman McInnes } 550d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 551fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 55297f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 55387828ca2SBarry Smith PetscScalar value; 55402594712SBarry Smith 555d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5567566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 55702594712SBarry Smith for (i=0; i<m; i++) { 55802594712SBarry Smith jcnt = 0; 559d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 560e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 56102594712SBarry Smith value = a->a[cnt++]; 562e24b481bSBarry Smith jcnt++; 56302594712SBarry Smith } else { 56402594712SBarry Smith value = 0.0; 56502594712SBarry Smith } 566aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 567b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",PetscRealPart(value),PetscImaginaryPart(value));CHKERRQ(ierr); 56802594712SBarry Smith #else 569b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",value);CHKERRQ(ierr); 57002594712SBarry Smith #endif 57102594712SBarry Smith } 572b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 57302594712SBarry Smith } 574d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 5753c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 576d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 5777566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 5783c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 5793c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix complex general\n");CHKERRQ(ierr); 5803c215bfdSMatthew Knepley #else 5813c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%%matrix real general\n");CHKERRQ(ierr); 5823c215bfdSMatthew Knepley #endif 583d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 5843c215bfdSMatthew Knepley for (i=0; i<m; i++) { 5853c215bfdSMatthew Knepley for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 5863c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 5873c215bfdSMatthew Knepley if (PetscImaginaryPart(a->a[j]) > 0.0) { 5883c215bfdSMatthew 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); 5893c215bfdSMatthew Knepley } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 5903c215bfdSMatthew 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); 5913c215bfdSMatthew Knepley } else { 5923c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D, %G\n", i+shift,a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 5933c215bfdSMatthew Knepley } 5943c215bfdSMatthew Knepley #else 5953c215bfdSMatthew Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %G\n", i+shift, a->j[j]+shift, a->a[j]);CHKERRQ(ierr); 5963c215bfdSMatthew Knepley #endif 5973c215bfdSMatthew Knepley } 5983c215bfdSMatthew Knepley } 599d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 6003a40ed3dSBarry Smith } else { 601d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 6027566de4bSShri Abhyankar ierr = PetscObjectPrintClassNamePrefixType((PetscObject)A,viewer,"Matrix Object");CHKERRQ(ierr); 603d5f3da31SBarry Smith if (A->factortype){ 60416cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 60516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 60616cd7e1dSShri Abhyankar /* L part */ 60716cd7e1dSShri Abhyankar for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 60816cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 60916cd7e1dSShri Abhyankar 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 if (PetscImaginaryPart(a->a[j]) < 0.0) { 61216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 61316cd7e1dSShri Abhyankar } else { 61416cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 61516cd7e1dSShri Abhyankar } 61616cd7e1dSShri Abhyankar #else 61716cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 61816cd7e1dSShri Abhyankar #endif 61916cd7e1dSShri Abhyankar } 62016cd7e1dSShri Abhyankar /* diagonal */ 62116cd7e1dSShri Abhyankar j = a->diag[i]; 62216cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 62316cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 6242c990fa1SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 62516cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 6262c990fa1SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(1.0/a->a[j]),-PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 62716cd7e1dSShri Abhyankar } else { 6282c990fa1SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 62916cd7e1dSShri Abhyankar } 63016cd7e1dSShri Abhyankar #else 6312c990fa1SHong Zhang ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,1.0/a->a[j]);CHKERRQ(ierr); 63216cd7e1dSShri Abhyankar #endif 63316cd7e1dSShri Abhyankar 63416cd7e1dSShri Abhyankar /* U part */ 63516cd7e1dSShri Abhyankar for (j=a->diag[i+1]+1+shift; j<a->diag[i]+shift; j++) { 63616cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 63716cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 63816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 63916cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 64016cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 64116cd7e1dSShri Abhyankar } else { 64216cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 64316cd7e1dSShri Abhyankar } 64416cd7e1dSShri Abhyankar #else 64516cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 64616cd7e1dSShri Abhyankar #endif 64716cd7e1dSShri Abhyankar } 64816cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 64916cd7e1dSShri Abhyankar } 65016cd7e1dSShri Abhyankar } else { 65117ab2063SBarry Smith for (i=0; i<m; i++) { 65277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 653416022c9SBarry Smith for (j=a->i[i]+shift; j<a->i[i+1]+shift; j++) { 654aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 65536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 656a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G + %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 65736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 658a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G - %G i)",a->j[j]+shift,PetscRealPart(a->a[j]),-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6593a40ed3dSBarry Smith } else { 660a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,PetscRealPart(a->a[j]));CHKERRQ(ierr); 66117ab2063SBarry Smith } 66217ab2063SBarry Smith #else 663a83599f4SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %G) ",a->j[j]+shift,a->a[j]);CHKERRQ(ierr); 66417ab2063SBarry Smith #endif 66517ab2063SBarry Smith } 666b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 66717ab2063SBarry Smith } 66816cd7e1dSShri Abhyankar } 669d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 67017ab2063SBarry Smith } 671b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 6723a40ed3dSBarry Smith PetscFunctionReturn(0); 673416022c9SBarry Smith } 674416022c9SBarry Smith 6754a2ae208SSatish Balay #undef __FUNCT__ 6764a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw_Zoom" 677dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 678416022c9SBarry Smith { 679480ef9eaSBarry Smith Mat A = (Mat) Aa; 680416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 681dfbe8321SBarry Smith PetscErrorCode ierr; 682d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,color; 68336db0b34SBarry Smith PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r,maxv = 0.0; 684b0a32e0cSBarry Smith PetscViewer viewer; 685f3ef73ceSBarry Smith PetscViewerFormat format; 686cddf8d76SBarry Smith 6873a40ed3dSBarry Smith PetscFunctionBegin; 688480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 689b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 69019bcc07fSBarry Smith 691b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 692416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 6930513a670SBarry Smith 694fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 6950513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 696b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 697416022c9SBarry Smith for (i=0; i<m; i++) { 698cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 699bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 700bfeeae90SHong Zhang x_l = a->j[j] ; x_r = x_l + 1.0; 701aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 70236db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 703cddf8d76SBarry Smith #else 704cddf8d76SBarry Smith if (a->a[j] >= 0.) continue; 705cddf8d76SBarry Smith #endif 706b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 707cddf8d76SBarry Smith } 708cddf8d76SBarry Smith } 709b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 710cddf8d76SBarry Smith for (i=0; i<m; i++) { 711cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 712bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 713bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 714cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 715b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 716cddf8d76SBarry Smith } 717cddf8d76SBarry Smith } 718b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 719cddf8d76SBarry Smith for (i=0; i<m; i++) { 720cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 721bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 722bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 723aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 72436db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 725cddf8d76SBarry Smith #else 726cddf8d76SBarry Smith if (a->a[j] <= 0.) continue; 727cddf8d76SBarry Smith #endif 728b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 729416022c9SBarry Smith } 730416022c9SBarry Smith } 7310513a670SBarry Smith } else { 7320513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 7330513a670SBarry Smith /* first determine max of all nonzero values */ 73497f1f81fSBarry Smith PetscInt nz = a->nz,count; 735b0a32e0cSBarry Smith PetscDraw popup; 73636db0b34SBarry Smith PetscReal scale; 7370513a670SBarry Smith 7380513a670SBarry Smith for (i=0; i<nz; i++) { 7390513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 7400513a670SBarry Smith } 741b0a32e0cSBarry Smith scale = (245.0 - PETSC_DRAW_BASIC_COLORS)/maxv; 742b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 743b0a32e0cSBarry Smith if (popup) {ierr = PetscDrawScalePopup(popup,0.0,maxv);CHKERRQ(ierr);} 7440513a670SBarry Smith count = 0; 7450513a670SBarry Smith for (i=0; i<m; i++) { 7460513a670SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 747bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 748bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 74997f1f81fSBarry Smith color = PETSC_DRAW_BASIC_COLORS + (PetscInt)(scale*PetscAbsScalar(a->a[count])); 750b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 7510513a670SBarry Smith count++; 7520513a670SBarry Smith } 7530513a670SBarry Smith } 7540513a670SBarry Smith } 755480ef9eaSBarry Smith PetscFunctionReturn(0); 756480ef9eaSBarry Smith } 757cddf8d76SBarry Smith 7584a2ae208SSatish Balay #undef __FUNCT__ 7594a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ_Draw" 760dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 761480ef9eaSBarry Smith { 762dfbe8321SBarry Smith PetscErrorCode ierr; 763b0a32e0cSBarry Smith PetscDraw draw; 76436db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 765ace3abfcSBarry Smith PetscBool isnull; 766480ef9eaSBarry Smith 767480ef9eaSBarry Smith PetscFunctionBegin; 768b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 769b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 770480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 771480ef9eaSBarry Smith 772480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 773d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 774480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 775b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 776b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 777480ef9eaSBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",PETSC_NULL);CHKERRQ(ierr); 7783a40ed3dSBarry Smith PetscFunctionReturn(0); 779416022c9SBarry Smith } 780416022c9SBarry Smith 7814a2ae208SSatish Balay #undef __FUNCT__ 7824a2ae208SSatish Balay #define __FUNCT__ "MatView_SeqAIJ" 783dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 784416022c9SBarry Smith { 785dfbe8321SBarry Smith PetscErrorCode ierr; 786ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 787416022c9SBarry Smith 7883a40ed3dSBarry Smith PetscFunctionBegin; 789251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 790251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 791251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 792c45a1595SBarry Smith if (iascii) { 7933a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 7940f5bd95cSBarry Smith } else if (isbinary) { 7953a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 7960f5bd95cSBarry Smith } else if (isdraw) { 7973a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 798913ac41fSBarry Smith } else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported by SeqAIJ matrices",((PetscObject)viewer)->type_name); 7994108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 8003a40ed3dSBarry Smith PetscFunctionReturn(0); 80117ab2063SBarry Smith } 80219bcc07fSBarry Smith 8034a2ae208SSatish Balay #undef __FUNCT__ 8044a2ae208SSatish Balay #define __FUNCT__ "MatAssemblyEnd_SeqAIJ" 805dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 80617ab2063SBarry Smith { 807416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 8086849ba73SBarry Smith PetscErrorCode ierr; 80997f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 810d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 81154f21887SBarry Smith MatScalar *aa = a->a,*ap; 8123447b6efSHong Zhang PetscReal ratio=0.6; 81317ab2063SBarry Smith 8143a40ed3dSBarry Smith PetscFunctionBegin; 8153a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 81617ab2063SBarry Smith 81743ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 81817ab2063SBarry Smith for (i=1; i<m; i++) { 819416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 82017ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 82194a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 82217ab2063SBarry Smith if (fshift) { 823bfeeae90SHong Zhang ip = aj + ai[i] ; 824bfeeae90SHong Zhang ap = aa + ai[i] ; 82517ab2063SBarry Smith N = ailen[i]; 82617ab2063SBarry Smith for (j=0; j<N; j++) { 82717ab2063SBarry Smith ip[j-fshift] = ip[j]; 82817ab2063SBarry Smith ap[j-fshift] = ap[j]; 82917ab2063SBarry Smith } 83017ab2063SBarry Smith } 83117ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 83217ab2063SBarry Smith } 83317ab2063SBarry Smith if (m) { 83417ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 83517ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 83617ab2063SBarry Smith } 83717ab2063SBarry Smith /* reset ilen and imax for each row */ 83817ab2063SBarry Smith for (i=0; i<m; i++) { 83917ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 84017ab2063SBarry Smith } 841bfeeae90SHong Zhang a->nz = ai[m]; 84265e19b50SBarry 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); 84317ab2063SBarry Smith 84409f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 845d0f46423SBarry 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); 846ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 847ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 8488e58a170SBarry Smith A->info.mallocs += a->reallocs; 849dd5f02e7SSatish Balay a->reallocs = 0; 8504e220ebcSLois Curfman McInnes A->info.nz_unneeded = (double)fshift; 85136db0b34SBarry Smith a->rmax = rmax; 8524e220ebcSLois Curfman McInnes 853cd6b891eSBarry Smith ierr = MatCheckCompressedRow(A,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 85488e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 85571c2f376SKris Buschelman 8564108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 85771f1c65dSBarry Smith 8580847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 8593a40ed3dSBarry Smith PetscFunctionReturn(0); 86017ab2063SBarry Smith } 86117ab2063SBarry Smith 8624a2ae208SSatish Balay #undef __FUNCT__ 86399cafbc1SBarry Smith #define __FUNCT__ "MatRealPart_SeqAIJ" 86499cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 86599cafbc1SBarry Smith { 86699cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 86799cafbc1SBarry Smith PetscInt i,nz = a->nz; 86854f21887SBarry Smith MatScalar *aa = a->a; 8690847f33cSJed Brown PetscErrorCode ierr; 87099cafbc1SBarry Smith 87199cafbc1SBarry Smith PetscFunctionBegin; 87299cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 8730847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 87499cafbc1SBarry Smith PetscFunctionReturn(0); 87599cafbc1SBarry Smith } 87699cafbc1SBarry Smith 87799cafbc1SBarry Smith #undef __FUNCT__ 87899cafbc1SBarry Smith #define __FUNCT__ "MatImaginaryPart_SeqAIJ" 87999cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 88099cafbc1SBarry Smith { 88199cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 88299cafbc1SBarry Smith PetscInt i,nz = a->nz; 88354f21887SBarry Smith MatScalar *aa = a->a; 8840847f33cSJed Brown PetscErrorCode ierr; 88599cafbc1SBarry Smith 88699cafbc1SBarry Smith PetscFunctionBegin; 88799cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 8880847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 88999cafbc1SBarry Smith PetscFunctionReturn(0); 89099cafbc1SBarry Smith } 89199cafbc1SBarry Smith 89299cafbc1SBarry Smith #undef __FUNCT__ 8934a2ae208SSatish Balay #define __FUNCT__ "MatZeroEntries_SeqAIJ" 894dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 89517ab2063SBarry Smith { 896416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 897dfbe8321SBarry Smith PetscErrorCode ierr; 8983a40ed3dSBarry Smith 8993a40ed3dSBarry Smith PetscFunctionBegin; 900d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 9010847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 9023a40ed3dSBarry Smith PetscFunctionReturn(0); 90317ab2063SBarry Smith } 904416022c9SBarry Smith 9054a2ae208SSatish Balay #undef __FUNCT__ 9064a2ae208SSatish Balay #define __FUNCT__ "MatDestroy_SeqAIJ" 907dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 90817ab2063SBarry Smith { 909416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 910dfbe8321SBarry Smith PetscErrorCode ierr; 911d5d45c9bSBarry Smith 9123a40ed3dSBarry Smith PetscFunctionBegin; 913aa482453SBarry Smith #if defined(PETSC_USE_LOG) 914d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 91517ab2063SBarry Smith #endif 916e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 9176bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 9186bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 91905b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 920d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 92105b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 92271f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 92305b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 9246bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 92505b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 9266bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 92705b42c5fSBarry Smith ierr = PetscFree(a->xtoy);CHKERRQ(ierr); 9286bf464f9SBarry Smith ierr = MatDestroy(&a->XtoY);CHKERRQ(ierr); 929cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 9300b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 931a30b2313SHong Zhang 9324108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 933bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 934901853e0SKris Buschelman 935dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 936901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetColumnIndices_C","",PETSC_NULL);CHKERRQ(ierr); 937901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatStoreValues_C","",PETSC_NULL);CHKERRQ(ierr); 938901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatRetrieveValues_C","",PETSC_NULL);CHKERRQ(ierr); 939901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqsbaij_C","",PETSC_NULL);CHKERRQ(ierr); 940901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqbaij_C","",PETSC_NULL);CHKERRQ(ierr); 9415a11e1b2SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatConvert_seqaij_seqaijperm_C","",PETSC_NULL);CHKERRQ(ierr); 942901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatIsTranspose_C","",PETSC_NULL);CHKERRQ(ierr); 943901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocation_C","",PETSC_NULL);CHKERRQ(ierr); 944a1661176SMatthew Knepley ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C","",PETSC_NULL);CHKERRQ(ierr); 945901853e0SKris Buschelman ierr = PetscObjectComposeFunctionDynamic((PetscObject)A,"MatReorderForNonzeroDiagonal_C","",PETSC_NULL);CHKERRQ(ierr); 9463a40ed3dSBarry Smith PetscFunctionReturn(0); 94717ab2063SBarry Smith } 94817ab2063SBarry Smith 9494a2ae208SSatish Balay #undef __FUNCT__ 9504a2ae208SSatish Balay #define __FUNCT__ "MatSetOption_SeqAIJ" 951ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 95217ab2063SBarry Smith { 953416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9544846f1f5SKris Buschelman PetscErrorCode ierr; 9553a40ed3dSBarry Smith 9563a40ed3dSBarry Smith PetscFunctionBegin; 957a65d3064SKris Buschelman switch (op) { 958a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 9594e0d8c25SBarry Smith a->roworiented = flg; 960a65d3064SKris Buschelman break; 961a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 962a9817697SBarry Smith a->keepnonzeropattern = flg; 963a65d3064SKris Buschelman break; 964512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 965512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 966a65d3064SKris Buschelman break; 967a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 9684e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 969a65d3064SKris Buschelman break; 970a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 9714e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 972a65d3064SKris Buschelman break; 97328b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 97428b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 97528b2fa4aSMatthew Knepley break; 976a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 9774e0d8c25SBarry Smith a->ignorezeroentries = flg; 9780df259c2SBarry Smith break; 979cd6b891eSBarry Smith case MAT_CHECK_COMPRESSED_ROW: 980cd6b891eSBarry Smith a->compressedrow.check = flg; 981d487561eSHong Zhang break; 9823d472b54SHong Zhang case MAT_SPD: 9833d472b54SHong Zhang A->spd_set = PETSC_TRUE; 9843d472b54SHong Zhang A->spd = flg; 9853d472b54SHong Zhang if (flg) { 9863d472b54SHong Zhang A->symmetric = PETSC_TRUE; 9873d472b54SHong Zhang A->structurally_symmetric = PETSC_TRUE; 9883d472b54SHong Zhang A->symmetric_set = PETSC_TRUE; 9893d472b54SHong Zhang A->structurally_symmetric_set = PETSC_TRUE; 9903d472b54SHong Zhang } 9913d472b54SHong Zhang break; 992b1646e73SJed Brown case MAT_SYMMETRIC: 993b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 994b1646e73SJed Brown case MAT_HERMITIAN: 995b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 9964e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 997a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 998a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 999290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1000a65d3064SKris Buschelman break; 1001b87ac2d8SJed Brown case MAT_USE_INODES: 1002b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1003b87ac2d8SJed Brown break; 1004a65d3064SKris Buschelman default: 1005e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1006a65d3064SKris Buschelman } 10074108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 10083a40ed3dSBarry Smith PetscFunctionReturn(0); 100917ab2063SBarry Smith } 101017ab2063SBarry Smith 10114a2ae208SSatish Balay #undef __FUNCT__ 10124a2ae208SSatish Balay #define __FUNCT__ "MatGetDiagonal_SeqAIJ" 1013dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 101417ab2063SBarry Smith { 1015416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10166849ba73SBarry Smith PetscErrorCode ierr; 1017d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 101835e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 101917ab2063SBarry Smith 10203a40ed3dSBarry Smith PetscFunctionBegin; 1021d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1022e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 102335e7444dSHong Zhang 1024d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU){ 1025d3e70bfaSHong Zhang PetscInt *diag=a->diag; 102635e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 10272c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 102835e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 102935e7444dSHong Zhang PetscFunctionReturn(0); 103035e7444dSHong Zhang } 103135e7444dSHong Zhang 10322dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 10331ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 103435e7444dSHong Zhang for (i=0; i<n; i++) { 103535e7444dSHong Zhang nz = ai[i+1] - ai[i]; 10362f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 103735e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++){ 103835e7444dSHong Zhang if (aj[j] == i) { 103935e7444dSHong Zhang x[i] = aa[j]; 104017ab2063SBarry Smith break; 104117ab2063SBarry Smith } 104217ab2063SBarry Smith } 104317ab2063SBarry Smith } 10441ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 10453a40ed3dSBarry Smith PetscFunctionReturn(0); 104617ab2063SBarry Smith } 104717ab2063SBarry Smith 1048c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 10494a2ae208SSatish Balay #undef __FUNCT__ 10504a2ae208SSatish Balay #define __FUNCT__ "MatMultTransposeAdd_SeqAIJ" 1051dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 105217ab2063SBarry Smith { 1053416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10545c897100SBarry Smith PetscScalar *x,*y; 1055dfbe8321SBarry Smith PetscErrorCode ierr; 1056d0f46423SBarry Smith PetscInt m = A->rmap->n; 10575c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1058a77337e4SBarry Smith MatScalar *v; 1059a77337e4SBarry Smith PetscScalar alpha; 106004fbf559SBarry Smith PetscInt n,i,j,*idx,*ii,*ridx=PETSC_NULL; 10613447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1062ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 10635c897100SBarry Smith #endif 106417ab2063SBarry Smith 10653a40ed3dSBarry Smith PetscFunctionBegin; 10662e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 10671ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 10681ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 10695c897100SBarry Smith 10705c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1071bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 10725c897100SBarry Smith #else 10733447b6efSHong Zhang if (usecprow){ 10743447b6efSHong Zhang m = cprow.nrows; 10753447b6efSHong Zhang ii = cprow.i; 10767b2bb3b9SHong Zhang ridx = cprow.rindex; 10773447b6efSHong Zhang } else { 10783447b6efSHong Zhang ii = a->i; 10793447b6efSHong Zhang } 108017ab2063SBarry Smith for (i=0; i<m; i++) { 10813447b6efSHong Zhang idx = a->j + ii[i] ; 10823447b6efSHong Zhang v = a->a + ii[i] ; 10833447b6efSHong Zhang n = ii[i+1] - ii[i]; 10843447b6efSHong Zhang if (usecprow){ 10857b2bb3b9SHong Zhang alpha = x[ridx[i]]; 10863447b6efSHong Zhang } else { 108717ab2063SBarry Smith alpha = x[i]; 10883447b6efSHong Zhang } 108904fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 109017ab2063SBarry Smith } 10915c897100SBarry Smith #endif 1092dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 10931ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 10941ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 10953a40ed3dSBarry Smith PetscFunctionReturn(0); 109617ab2063SBarry Smith } 109717ab2063SBarry Smith 10984a2ae208SSatish Balay #undef __FUNCT__ 10995c897100SBarry Smith #define __FUNCT__ "MatMultTranspose_SeqAIJ" 1100dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 11015c897100SBarry Smith { 1102dfbe8321SBarry Smith PetscErrorCode ierr; 11035c897100SBarry Smith 11045c897100SBarry Smith PetscFunctionBegin; 1105170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 11065c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 11075c897100SBarry Smith PetscFunctionReturn(0); 11085c897100SBarry Smith } 11095c897100SBarry Smith 1110c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 11115c897100SBarry Smith #undef __FUNCT__ 11124a2ae208SSatish Balay #define __FUNCT__ "MatMult_SeqAIJ" 1113dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 111417ab2063SBarry Smith { 1115416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1116d9fead3dSBarry Smith PetscScalar *y; 111754f21887SBarry Smith const PetscScalar *x; 111854f21887SBarry Smith const MatScalar *aa; 1119dfbe8321SBarry Smith PetscErrorCode ierr; 1120003131ecSBarry Smith PetscInt m=A->rmap->n; 1121003131ecSBarry Smith const PetscInt *aj,*ii,*ridx=PETSC_NULL; 11228aee2decSHong Zhang PetscInt n,i,nonzerorow=0; 1123362ced78SSatish Balay PetscScalar sum; 1124ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 112517ab2063SBarry Smith 1126b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 112797952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1128fee21e36SBarry Smith #endif 1129fee21e36SBarry Smith 11303a40ed3dSBarry Smith PetscFunctionBegin; 11313649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 11321ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 113397952fefSHong Zhang aj = a->j; 113497952fefSHong Zhang aa = a->a; 1135416022c9SBarry Smith ii = a->i; 11364eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 113797952fefSHong Zhang m = a->compressedrow.nrows; 113897952fefSHong Zhang ii = a->compressedrow.i; 113997952fefSHong Zhang ridx = a->compressedrow.rindex; 114097952fefSHong Zhang for (i=0; i<m; i++){ 114197952fefSHong Zhang n = ii[i+1] - ii[i]; 114297952fefSHong Zhang aj = a->j + ii[i]; 114397952fefSHong Zhang aa = a->a + ii[i]; 114497952fefSHong Zhang sum = 0.0; 1145a46b3154SVictor Eijkhout nonzerorow += (n>0); 1146003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1147003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 114897952fefSHong Zhang y[*ridx++] = sum; 114997952fefSHong Zhang } 115097952fefSHong Zhang } else { /* do not use compressed row format */ 1151b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 1152b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1153b05257ddSBarry Smith #else 115417ab2063SBarry Smith for (i=0; i<m; i++) { 1155003131ecSBarry Smith n = ii[i+1] - ii[i]; 1156003131ecSBarry Smith aj = a->j + ii[i]; 1157003131ecSBarry Smith aa = a->a + ii[i]; 115817ab2063SBarry Smith sum = 0.0; 1159a46b3154SVictor Eijkhout nonzerorow += (n>0); 1160003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 116117ab2063SBarry Smith y[i] = sum; 116217ab2063SBarry Smith } 11638d195f9aSBarry Smith #endif 1164b05257ddSBarry Smith } 1165dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 11663649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 11671ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 11683a40ed3dSBarry Smith PetscFunctionReturn(0); 116917ab2063SBarry Smith } 117017ab2063SBarry Smith 1171c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 11724a2ae208SSatish Balay #undef __FUNCT__ 11734a2ae208SSatish Balay #define __FUNCT__ "MatMultAdd_SeqAIJ" 1174dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 117517ab2063SBarry Smith { 1176416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1177f15663dcSBarry Smith PetscScalar *y,*z; 1178f15663dcSBarry Smith const PetscScalar *x; 117954f21887SBarry Smith const MatScalar *aa; 1180dfbe8321SBarry Smith PetscErrorCode ierr; 1181d0f46423SBarry Smith PetscInt m = A->rmap->n,*aj,*ii; 1182f15663dcSBarry Smith PetscInt n,i,*ridx=PETSC_NULL; 1183362ced78SSatish Balay PetscScalar sum; 1184ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 11859ea0dfa2SSatish Balay 11863a40ed3dSBarry Smith PetscFunctionBegin; 1187f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 11881ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 11892e8a6d31SBarry Smith if (zz != yy) { 11901ebc52fbSHong Zhang ierr = VecGetArray(zz,&z);CHKERRQ(ierr); 11912e8a6d31SBarry Smith } else { 11922e8a6d31SBarry Smith z = y; 11932e8a6d31SBarry Smith } 1194bfeeae90SHong Zhang 119597952fefSHong Zhang aj = a->j; 119697952fefSHong Zhang aa = a->a; 1197cddf8d76SBarry Smith ii = a->i; 11984eb6d288SHong Zhang if (usecprow){ /* use compressed row format */ 11994eb6d288SHong Zhang if (zz != yy){ 12004eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 12014eb6d288SHong Zhang } 120297952fefSHong Zhang m = a->compressedrow.nrows; 120397952fefSHong Zhang ii = a->compressedrow.i; 120497952fefSHong Zhang ridx = a->compressedrow.rindex; 120597952fefSHong Zhang for (i=0; i<m; i++){ 120697952fefSHong Zhang n = ii[i+1] - ii[i]; 120797952fefSHong Zhang aj = a->j + ii[i]; 120897952fefSHong Zhang aa = a->a + ii[i]; 120997952fefSHong Zhang sum = y[*ridx]; 1210f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 121197952fefSHong Zhang z[*ridx++] = sum; 121297952fefSHong Zhang } 121397952fefSHong Zhang } else { /* do not use compressed row format */ 1214f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 1215f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1216f15663dcSBarry Smith #else 121717ab2063SBarry Smith for (i=0; i<m; i++) { 1218f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1219f15663dcSBarry Smith aj = a->j + ii[i]; 1220f15663dcSBarry Smith aa = a->a + ii[i]; 122117ab2063SBarry Smith sum = y[i]; 1222f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 122317ab2063SBarry Smith z[i] = sum; 122417ab2063SBarry Smith } 122502ab625aSSatish Balay #endif 1226f15663dcSBarry Smith } 1227dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1228f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12291ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12302e8a6d31SBarry Smith if (zz != yy) { 12311ebc52fbSHong Zhang ierr = VecRestoreArray(zz,&z);CHKERRQ(ierr); 12322e8a6d31SBarry Smith } 12338154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 12346b375ea7SVictor Minden /* 1235918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1236918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1237918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 12386b375ea7SVictor Minden */ 1239918e98c3SVictor Minden #endif 12403a40ed3dSBarry Smith PetscFunctionReturn(0); 124117ab2063SBarry Smith } 124217ab2063SBarry Smith 124317ab2063SBarry Smith /* 124417ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 124517ab2063SBarry Smith */ 12464a2ae208SSatish Balay #undef __FUNCT__ 12474a2ae208SSatish Balay #define __FUNCT__ "MatMarkDiagonal_SeqAIJ" 1248dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 124917ab2063SBarry Smith { 1250416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12516849ba73SBarry Smith PetscErrorCode ierr; 1252d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 125317ab2063SBarry Smith 12543a40ed3dSBarry Smith PetscFunctionBegin; 125509f38230SBarry Smith if (!a->diag) { 125609f38230SBarry Smith ierr = PetscMalloc(m*sizeof(PetscInt),&a->diag);CHKERRQ(ierr); 12579518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(A, m*sizeof(PetscInt));CHKERRQ(ierr); 125809f38230SBarry Smith } 1259d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 126009f38230SBarry Smith a->diag[i] = a->i[i+1]; 1261bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1262bfeeae90SHong Zhang if (a->j[j] == i) { 126309f38230SBarry Smith a->diag[i] = j; 126417ab2063SBarry Smith break; 126517ab2063SBarry Smith } 126617ab2063SBarry Smith } 126717ab2063SBarry Smith } 12683a40ed3dSBarry Smith PetscFunctionReturn(0); 126917ab2063SBarry Smith } 127017ab2063SBarry Smith 1271be5855fcSBarry Smith /* 1272be5855fcSBarry Smith Checks for missing diagonals 1273be5855fcSBarry Smith */ 12744a2ae208SSatish Balay #undef __FUNCT__ 12754a2ae208SSatish Balay #define __FUNCT__ "MatMissingDiagonal_SeqAIJ" 1276ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1277be5855fcSBarry Smith { 1278be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 127997f1f81fSBarry Smith PetscInt *diag,*jj = a->j,i; 1280be5855fcSBarry Smith 1281be5855fcSBarry Smith PetscFunctionBegin; 128209f38230SBarry Smith *missing = PETSC_FALSE; 1283d0f46423SBarry Smith if (A->rmap->n > 0 && !jj) { 128409f38230SBarry Smith *missing = PETSC_TRUE; 128509f38230SBarry Smith if (d) *d = 0; 1286358d2f5dSShri Abhyankar PetscInfo(A,"Matrix has no entries therefore is missing diagonal"); 128709f38230SBarry Smith } else { 1288f1e2ffcdSBarry Smith diag = a->diag; 1289d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1290bfeeae90SHong Zhang if (jj[diag[i]] != i) { 129109f38230SBarry Smith *missing = PETSC_TRUE; 129209f38230SBarry Smith if (d) *d = i; 129309f38230SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D",i); 1294358d2f5dSShri Abhyankar break; 129509f38230SBarry Smith } 1296be5855fcSBarry Smith } 1297be5855fcSBarry Smith } 1298be5855fcSBarry Smith PetscFunctionReturn(0); 1299be5855fcSBarry Smith } 1300be5855fcSBarry Smith 130171f1c65dSBarry Smith EXTERN_C_BEGIN 130271f1c65dSBarry Smith #undef __FUNCT__ 130371f1c65dSBarry Smith #define __FUNCT__ "MatInvertDiagonal_SeqAIJ" 13047087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 130571f1c65dSBarry Smith { 130671f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 130771f1c65dSBarry Smith PetscErrorCode ierr; 1308d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 130954f21887SBarry Smith MatScalar *v = a->a; 131054f21887SBarry Smith PetscScalar *idiag,*mdiag; 131171f1c65dSBarry Smith 131271f1c65dSBarry Smith PetscFunctionBegin; 131371f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 131471f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 131571f1c65dSBarry Smith diag = a->diag; 131671f1c65dSBarry Smith if (!a->idiag) { 131771f1c65dSBarry Smith ierr = PetscMalloc3(m,PetscScalar,&a->idiag,m,PetscScalar,&a->mdiag,m,PetscScalar,&a->ssor_work);CHKERRQ(ierr); 131871f1c65dSBarry Smith ierr = PetscLogObjectMemory(A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 131971f1c65dSBarry Smith v = a->a; 132071f1c65dSBarry Smith } 132171f1c65dSBarry Smith mdiag = a->mdiag; 132271f1c65dSBarry Smith idiag = a->idiag; 132371f1c65dSBarry Smith 1324028cd4eaSSatish Balay if (omega == 1.0 && !PetscAbsScalar(fshift)) { 132571f1c65dSBarry Smith for (i=0; i<m; i++) { 132671f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1327e32f2f54SBarry Smith if (!PetscAbsScalar(mdiag[i])) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 132871f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 132971f1c65dSBarry Smith } 133071f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 133171f1c65dSBarry Smith } else { 133271f1c65dSBarry Smith for (i=0; i<m; i++) { 133371f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 133471f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 133571f1c65dSBarry Smith } 1336dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 133771f1c65dSBarry Smith } 133871f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 133971f1c65dSBarry Smith PetscFunctionReturn(0); 134071f1c65dSBarry Smith } 13415a9745a3SMatthew Knepley EXTERN_C_END 134271f1c65dSBarry Smith 1343c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 13444a2ae208SSatish Balay #undef __FUNCT__ 134541f059aeSBarry Smith #define __FUNCT__ "MatSOR_SeqAIJ" 134641f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 134717ab2063SBarry Smith { 1348416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1349e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 1350e6d1f457SBarry Smith const MatScalar *v = a->a,*idiag=0,*mdiag; 135154f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1352dfbe8321SBarry Smith PetscErrorCode ierr; 1353d0f46423SBarry Smith PetscInt n = A->cmap->n,m = A->rmap->n,i; 135497f1f81fSBarry Smith const PetscInt *idx,*diag; 135517ab2063SBarry Smith 13563a40ed3dSBarry Smith PetscFunctionBegin; 1357b965ef7fSBarry Smith its = its*lits; 135891723122SBarry Smith 135971f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 136071f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 136171f1c65dSBarry Smith a->fshift = fshift; 136271f1c65dSBarry Smith a->omega = omega; 1363ed480e8bSBarry Smith 136471f1c65dSBarry Smith diag = a->diag; 136571f1c65dSBarry Smith t = a->ssor_work; 1366ed480e8bSBarry Smith idiag = a->idiag; 136771f1c65dSBarry Smith mdiag = a->mdiag; 1368ed480e8bSBarry Smith 13691ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 13703649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 137171f1c65dSBarry Smith CHKMEMQ; 1372ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 137317ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 137417ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1375ed480e8bSBarry Smith bs = b; 137617ab2063SBarry Smith for (i=0; i<m; i++) { 137771f1c65dSBarry Smith d = fshift + mdiag[i]; 1378416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1379ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1380ed480e8bSBarry Smith v = a->a + diag[i] + 1; 138117ab2063SBarry Smith sum = b[i]*d/omega; 1382003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 138317ab2063SBarry Smith x[i] = sum; 138417ab2063SBarry Smith } 13851ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 13863649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1387efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 13883a40ed3dSBarry Smith PetscFunctionReturn(0); 138917ab2063SBarry Smith } 1390c783ea89SBarry Smith 139148af12d7SBarry Smith if (flag == SOR_APPLY_LOWER) { 1392e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 13933a40ed3dSBarry Smith } else if (flag & SOR_EISENSTAT) { 139417ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1395887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 139617ab2063SBarry Smith 139717ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 139817ab2063SBarry Smith 1399887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 140017ab2063SBarry Smith */ 140117ab2063SBarry Smith scale = (2.0/omega) - 1.0; 140217ab2063SBarry Smith 140317ab2063SBarry Smith /* x = (E + U)^{-1} b */ 140417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1405416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1406ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1407ed480e8bSBarry Smith v = a->a + diag[i] + 1; 140817ab2063SBarry Smith sum = b[i]; 1409e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1410ed480e8bSBarry Smith x[i] = sum*idiag[i]; 141117ab2063SBarry Smith } 141217ab2063SBarry Smith 141317ab2063SBarry Smith /* t = b - (2*E - D)x */ 1414416022c9SBarry Smith v = a->a; 1415ed480e8bSBarry Smith for (i=0; i<m; i++) { t[i] = b[i] - scale*(v[*diag++])*x[i]; } 141617ab2063SBarry Smith 141717ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1418ed480e8bSBarry Smith ts = t; 1419416022c9SBarry Smith diag = a->diag; 142017ab2063SBarry Smith for (i=0; i<m; i++) { 1421416022c9SBarry Smith n = diag[i] - a->i[i]; 1422ed480e8bSBarry Smith idx = a->j + a->i[i]; 1423ed480e8bSBarry Smith v = a->a + a->i[i]; 142417ab2063SBarry Smith sum = t[i]; 1425003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1426ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1427733d66baSBarry Smith /* x = x + t */ 1428733d66baSBarry Smith x[i] += t[i]; 142917ab2063SBarry Smith } 143017ab2063SBarry Smith 1431dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 14321ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 14333649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 14343a40ed3dSBarry Smith PetscFunctionReturn(0); 143517ab2063SBarry Smith } 143617ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 143717ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 143817ab2063SBarry Smith for (i=0; i<m; i++) { 1439416022c9SBarry Smith n = diag[i] - a->i[i]; 1440ed480e8bSBarry Smith idx = a->j + a->i[i]; 1441ed480e8bSBarry Smith v = a->a + a->i[i]; 144217ab2063SBarry Smith sum = b[i]; 1443e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 14445c99c7daSBarry Smith t[i] = sum; 1445ed480e8bSBarry Smith x[i] = sum*idiag[i]; 144617ab2063SBarry Smith } 14475c99c7daSBarry Smith xb = t; 1448efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 14493a40ed3dSBarry Smith } else xb = b; 145017ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 145117ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1452416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1453ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1454ed480e8bSBarry Smith v = a->a + diag[i] + 1; 145517ab2063SBarry Smith sum = xb[i]; 1456e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 14575c99c7daSBarry Smith if (xb == b) { 1458ed480e8bSBarry Smith x[i] = sum*idiag[i]; 14595c99c7daSBarry Smith } else { 14605c99c7daSBarry Smith x[i] = (1-omega)*x[i] + sum*idiag[i]; 146117ab2063SBarry Smith } 14625c99c7daSBarry Smith } 1463efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 146417ab2063SBarry Smith } 146517ab2063SBarry Smith its--; 146617ab2063SBarry Smith } 146717ab2063SBarry Smith while (its--) { 146817ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP){ 146917ab2063SBarry Smith for (i=0; i<m; i++) { 1470416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1471ed480e8bSBarry Smith idx = a->j + a->i[i]; 1472ed480e8bSBarry Smith v = a->a + a->i[i]; 147317ab2063SBarry Smith sum = b[i]; 1474e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1475ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 147617ab2063SBarry Smith } 14779f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 147817ab2063SBarry Smith } 147917ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP){ 148017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1481416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1482ed480e8bSBarry Smith idx = a->j + a->i[i]; 1483ed480e8bSBarry Smith v = a->a + a->i[i]; 148417ab2063SBarry Smith sum = b[i]; 1485e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1486ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 148717ab2063SBarry Smith } 14889f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 148917ab2063SBarry Smith } 149017ab2063SBarry Smith } 14911ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 14923649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 149371f1c65dSBarry Smith CHKMEMQ; PetscFunctionReturn(0); 149417ab2063SBarry Smith } 149517ab2063SBarry Smith 14962af78befSBarry Smith 14974a2ae208SSatish Balay #undef __FUNCT__ 14984a2ae208SSatish Balay #define __FUNCT__ "MatGetInfo_SeqAIJ" 1499dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 150017ab2063SBarry Smith { 1501416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15024e220ebcSLois Curfman McInnes 15033a40ed3dSBarry Smith PetscFunctionBegin; 15044e220ebcSLois Curfman McInnes info->block_size = 1.0; 15054e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 15064e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 15074e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 15084e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 15098e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 15107adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1511d5f3da31SBarry Smith if (A->factortype) { 15124e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 15134e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 15144e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 15154e220ebcSLois Curfman McInnes } else { 15164e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 15174e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 15184e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 15194e220ebcSLois Curfman McInnes } 15203a40ed3dSBarry Smith PetscFunctionReturn(0); 152117ab2063SBarry Smith } 152217ab2063SBarry Smith 15234a2ae208SSatish Balay #undef __FUNCT__ 15244a2ae208SSatish Balay #define __FUNCT__ "MatZeroRows_SeqAIJ" 15252b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 152617ab2063SBarry Smith { 1527416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15283b98c0a2SBarry Smith PetscInt i,m = A->rmap->n - 1,d = 0; 15296849ba73SBarry Smith PetscErrorCode ierr; 153097b48c8fSBarry Smith const PetscScalar *xx; 153197b48c8fSBarry Smith PetscScalar *bb; 1532ace3abfcSBarry Smith PetscBool missing; 153317ab2063SBarry Smith 15343a40ed3dSBarry Smith PetscFunctionBegin; 153597b48c8fSBarry Smith if (x && b) { 153697b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 153797b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 153897b48c8fSBarry Smith for (i=0; i<N; i++) { 153997b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 154097b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 154197b48c8fSBarry Smith } 154297b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 154397b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 154497b48c8fSBarry Smith } 154597b48c8fSBarry Smith 1546a9817697SBarry Smith if (a->keepnonzeropattern) { 1547f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1548e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1549bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1550f1e2ffcdSBarry Smith } 1551f4df32b1SMatthew Knepley if (diag != 0.0) { 155209f38230SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 1553e32f2f54SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 1554f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1555f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1556f1e2ffcdSBarry Smith } 1557f1e2ffcdSBarry Smith } 155888e51ccdSHong Zhang A->same_nonzero = PETSC_TRUE; 1559f1e2ffcdSBarry Smith } else { 1560f4df32b1SMatthew Knepley if (diag != 0.0) { 156117ab2063SBarry Smith for (i=0; i<N; i++) { 1562e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 15637ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1564416022c9SBarry Smith a->ilen[rows[i]] = 1; 1565f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1566bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 15677ae801bdSBarry Smith } else { /* in case row was completely empty */ 1568f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 156917ab2063SBarry Smith } 157017ab2063SBarry Smith } 15713a40ed3dSBarry Smith } else { 157217ab2063SBarry Smith for (i=0; i<N; i++) { 1573e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1574416022c9SBarry Smith a->ilen[rows[i]] = 0; 157517ab2063SBarry Smith } 157617ab2063SBarry Smith } 157788e51ccdSHong Zhang A->same_nonzero = PETSC_FALSE; 1578f1e2ffcdSBarry Smith } 157943a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 15803a40ed3dSBarry Smith PetscFunctionReturn(0); 158117ab2063SBarry Smith } 158217ab2063SBarry Smith 15834a2ae208SSatish Balay #undef __FUNCT__ 15846e169961SBarry Smith #define __FUNCT__ "MatZeroRowsColumns_SeqAIJ" 15856e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 15866e169961SBarry Smith { 15876e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 15886e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 15896e169961SBarry Smith PetscErrorCode ierr; 15902b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 15916e169961SBarry Smith const PetscScalar *xx; 15926e169961SBarry Smith PetscScalar *bb; 15936e169961SBarry Smith 15946e169961SBarry Smith PetscFunctionBegin; 15956e169961SBarry Smith if (x && b) { 15966e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 15976e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 15982b40b63fSBarry Smith vecs = PETSC_TRUE; 15996e169961SBarry Smith } 16006e169961SBarry Smith ierr = PetscMalloc(A->rmap->n*sizeof(PetscBool),&zeroed);CHKERRQ(ierr); 16016e169961SBarry Smith ierr = PetscMemzero(zeroed,A->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 16026e169961SBarry Smith for (i=0; i<N; i++) { 16036e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 16046e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 16056e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 16066e169961SBarry Smith } 16076e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 16086e169961SBarry Smith if (!zeroed[i]) { 16096e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 16106e169961SBarry Smith if (zeroed[a->j[j]]) { 16112b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 16126e169961SBarry Smith a->a[j] = 0.0; 16136e169961SBarry Smith } 16146e169961SBarry Smith } 16152b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 16166e169961SBarry Smith } 16176e169961SBarry Smith if (x && b) { 16186e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 16196e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 16206e169961SBarry Smith } 16216e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 16226e169961SBarry Smith if (diag != 0.0) { 16236e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 16246e169961SBarry Smith if (missing) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 16256e169961SBarry Smith for (i=0; i<N; i++) { 16266e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 16276e169961SBarry Smith } 16286e169961SBarry Smith } 16296e169961SBarry Smith A->same_nonzero = PETSC_TRUE; 16306e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 16316e169961SBarry Smith PetscFunctionReturn(0); 16326e169961SBarry Smith } 16336e169961SBarry Smith 16346e169961SBarry Smith #undef __FUNCT__ 16354a2ae208SSatish Balay #define __FUNCT__ "MatGetRow_SeqAIJ" 1636a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 163717ab2063SBarry Smith { 1638416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 163997f1f81fSBarry Smith PetscInt *itmp; 164017ab2063SBarry Smith 16413a40ed3dSBarry Smith PetscFunctionBegin; 1642e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 164317ab2063SBarry Smith 1644416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1645bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 164617ab2063SBarry Smith if (idx) { 1647bfeeae90SHong Zhang itmp = a->j + a->i[row]; 1648bfeeae90SHong Zhang if (*nz) { 16494e093b46SBarry Smith *idx = itmp; 165017ab2063SBarry Smith } 165117ab2063SBarry Smith else *idx = 0; 165217ab2063SBarry Smith } 16533a40ed3dSBarry Smith PetscFunctionReturn(0); 165417ab2063SBarry Smith } 165517ab2063SBarry Smith 1656bfeeae90SHong Zhang /* remove this function? */ 16574a2ae208SSatish Balay #undef __FUNCT__ 16584a2ae208SSatish Balay #define __FUNCT__ "MatRestoreRow_SeqAIJ" 1659a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 166017ab2063SBarry Smith { 16613a40ed3dSBarry Smith PetscFunctionBegin; 16623a40ed3dSBarry Smith PetscFunctionReturn(0); 166317ab2063SBarry Smith } 166417ab2063SBarry Smith 16654a2ae208SSatish Balay #undef __FUNCT__ 16664a2ae208SSatish Balay #define __FUNCT__ "MatNorm_SeqAIJ" 1667dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 166817ab2063SBarry Smith { 1669416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 167054f21887SBarry Smith MatScalar *v = a->a; 167136db0b34SBarry Smith PetscReal sum = 0.0; 16726849ba73SBarry Smith PetscErrorCode ierr; 167397f1f81fSBarry Smith PetscInt i,j; 167417ab2063SBarry Smith 16753a40ed3dSBarry Smith PetscFunctionBegin; 167617ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1677416022c9SBarry Smith for (i=0; i<a->nz; i++) { 1678aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 167936db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 168017ab2063SBarry Smith #else 168117ab2063SBarry Smith sum += (*v)*(*v); v++; 168217ab2063SBarry Smith #endif 168317ab2063SBarry Smith } 16848f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 16853a40ed3dSBarry Smith } else if (type == NORM_1) { 168636db0b34SBarry Smith PetscReal *tmp; 168797f1f81fSBarry Smith PetscInt *jj = a->j; 1688d0f46423SBarry Smith ierr = PetscMalloc((A->cmap->n+1)*sizeof(PetscReal),&tmp);CHKERRQ(ierr); 1689d0f46423SBarry Smith ierr = PetscMemzero(tmp,A->cmap->n*sizeof(PetscReal));CHKERRQ(ierr); 1690064f8208SBarry Smith *nrm = 0.0; 1691416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1692bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 169317ab2063SBarry Smith } 1694d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1695064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 169617ab2063SBarry Smith } 1697606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 16983a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1699064f8208SBarry Smith *nrm = 0.0; 1700d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1701bfeeae90SHong Zhang v = a->a + a->i[j]; 170217ab2063SBarry Smith sum = 0.0; 1703416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1704cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 170517ab2063SBarry Smith } 1706064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 170717ab2063SBarry Smith } 17083a40ed3dSBarry Smith } else { 1709e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 171017ab2063SBarry Smith } 17113a40ed3dSBarry Smith PetscFunctionReturn(0); 171217ab2063SBarry Smith } 171317ab2063SBarry Smith 17144e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 17154e938277SHong Zhang #undef __FUNCT__ 17164e938277SHong Zhang #define __FUNCT__ "MatTransposeSymbolic_SeqAIJ" 17174e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 17184e938277SHong Zhang { 17194e938277SHong Zhang PetscErrorCode ierr; 17204e938277SHong Zhang PetscInt i,j,anzj; 17214e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ *)A->data,*b; 17224e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 17234e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 17244e938277SHong Zhang 17254e938277SHong Zhang PetscFunctionBegin; 17264e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 17274e938277SHong Zhang ierr = PetscMalloc((an+1)*sizeof(PetscInt),&ati);CHKERRQ(ierr); 17284e938277SHong Zhang ierr = PetscMalloc(ai[am]*sizeof(PetscInt),&atj);CHKERRQ(ierr); 17294e938277SHong Zhang ierr = PetscMalloc(an*sizeof(PetscInt),&atfill);CHKERRQ(ierr); 17304e938277SHong Zhang ierr = PetscMemzero(ati,(an+1)*sizeof(PetscInt));CHKERRQ(ierr); 17314e938277SHong Zhang 17324e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 17334e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 17344e938277SHong Zhang for (i=0;i<ai[am];i++) { 17354e938277SHong Zhang ati[aj[i]+1] += 1; 17364e938277SHong Zhang } 17374e938277SHong Zhang /* Form ati for csr format of A^T. */ 17384e938277SHong Zhang for (i=0;i<an;i++) { 17394e938277SHong Zhang ati[i+1] += ati[i]; 17404e938277SHong Zhang } 17414e938277SHong Zhang 17424e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 17434e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 17444e938277SHong Zhang 17454e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 17464e938277SHong Zhang for (i=0;i<am;i++) { 17474e938277SHong Zhang anzj = ai[i+1] - ai[i]; 17484e938277SHong Zhang for (j=0;j<anzj;j++) { 17494e938277SHong Zhang atj[atfill[*aj]] = i; 17504e938277SHong Zhang atfill[*aj++] += 1; 17514e938277SHong Zhang } 17524e938277SHong Zhang } 17534e938277SHong Zhang 17544e938277SHong Zhang /* Clean up temporary space and complete requests. */ 17554e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 17564e938277SHong Zhang ierr = MatCreateSeqAIJWithArrays(((PetscObject)A)->comm,an,am,ati,atj,PETSC_NULL,B);CHKERRQ(ierr); 1757a2f3521dSMark F. Adams (*B)->rmap->bs = A->cmap->bs; 1758a2f3521dSMark F. Adams (*B)->cmap->bs = A->rmap->bs; 1759a2f3521dSMark F. Adams 17604e938277SHong Zhang b = (Mat_SeqAIJ *)((*B)->data); 17614e938277SHong Zhang b->free_a = PETSC_FALSE; 17624e938277SHong Zhang b->free_ij = PETSC_TRUE; 17634e938277SHong Zhang b->nonew = 0; 17644e938277SHong Zhang PetscFunctionReturn(0); 17654e938277SHong Zhang } 17664e938277SHong Zhang 17674a2ae208SSatish Balay #undef __FUNCT__ 17684a2ae208SSatish Balay #define __FUNCT__ "MatTranspose_SeqAIJ" 1769fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 177017ab2063SBarry Smith { 1771416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1772416022c9SBarry Smith Mat C; 17736849ba73SBarry Smith PetscErrorCode ierr; 1774d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 177554f21887SBarry Smith MatScalar *array = a->a; 177617ab2063SBarry Smith 17773a40ed3dSBarry Smith PetscFunctionBegin; 1778e32f2f54SBarry 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"); 1779fc4dec0aSBarry Smith 1780fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B == A) { 1781d0f46423SBarry Smith ierr = PetscMalloc((1+A->cmap->n)*sizeof(PetscInt),&col);CHKERRQ(ierr); 1782d0f46423SBarry Smith ierr = PetscMemzero(col,(1+A->cmap->n)*sizeof(PetscInt));CHKERRQ(ierr); 1783bfeeae90SHong Zhang 1784bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 17857adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 1786d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 1787a2f3521dSMark F. Adams ierr = MatSetBlockSizes(C,A->cmap->bs,A->rmap->bs);CHKERRQ(ierr); 17887adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 1789ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 1790606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 1791a541d17aSBarry Smith } else { 1792a541d17aSBarry Smith C = *B; 1793a541d17aSBarry Smith } 1794a541d17aSBarry Smith 179517ab2063SBarry Smith for (i=0; i<m; i++) { 179617ab2063SBarry Smith len = ai[i+1]-ai[i]; 179787d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 1798b9b97703SBarry Smith array += len; 1799b9b97703SBarry Smith aj += len; 180017ab2063SBarry Smith } 18016d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18026d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 180317ab2063SBarry Smith 1804815cbec1SBarry Smith if (reuse == MAT_INITIAL_MATRIX || *B != A) { 1805416022c9SBarry Smith *B = C; 180617ab2063SBarry Smith } else { 1807eb6b5d47SBarry Smith ierr = MatHeaderMerge(A,C);CHKERRQ(ierr); 180817ab2063SBarry Smith } 18093a40ed3dSBarry Smith PetscFunctionReturn(0); 181017ab2063SBarry Smith } 181117ab2063SBarry Smith 1812cd0d46ebSvictorle EXTERN_C_BEGIN 1813cd0d46ebSvictorle #undef __FUNCT__ 18145fbd3699SBarry Smith #define __FUNCT__ "MatIsTranspose_SeqAIJ" 18157087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 1816cd0d46ebSvictorle { 1817cd0d46ebSvictorle Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 181854f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 181954f21887SBarry Smith MatScalar *va,*vb; 18206849ba73SBarry Smith PetscErrorCode ierr; 182197f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 1822cd0d46ebSvictorle 1823cd0d46ebSvictorle PetscFunctionBegin; 1824cd0d46ebSvictorle bij = (Mat_SeqAIJ *) B->data; 1825cd0d46ebSvictorle 1826cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 1827cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 18285485867bSBarry Smith if (ma!=nb || na!=mb){ 18295485867bSBarry Smith *f = PETSC_FALSE; 18305485867bSBarry Smith PetscFunctionReturn(0); 18315485867bSBarry Smith } 1832cd0d46ebSvictorle aii = aij->i; bii = bij->i; 1833cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 1834cd0d46ebSvictorle va = aij->a; vb = bij->a; 183597f1f81fSBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 183697f1f81fSBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 1837cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 1838cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 1839cd0d46ebSvictorle 1840cd0d46ebSvictorle *f = PETSC_TRUE; 1841cd0d46ebSvictorle for (i=0; i<ma; i++) { 1842cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 184397f1f81fSBarry Smith PetscInt idc,idr; 18445485867bSBarry Smith PetscScalar vc,vr; 1845cd0d46ebSvictorle /* column/row index/value */ 18465485867bSBarry Smith idc = adx[aptr[i]]; 18475485867bSBarry Smith idr = bdx[bptr[idc]]; 18485485867bSBarry Smith vc = va[aptr[i]]; 18495485867bSBarry Smith vr = vb[bptr[idc]]; 18505485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 18515485867bSBarry Smith *f = PETSC_FALSE; 18525485867bSBarry Smith goto done; 1853cd0d46ebSvictorle } else { 18545485867bSBarry Smith aptr[i]++; 18555485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 1856cd0d46ebSvictorle } 1857cd0d46ebSvictorle } 1858cd0d46ebSvictorle } 1859cd0d46ebSvictorle done: 1860cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 18613aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 1862cd0d46ebSvictorle PetscFunctionReturn(0); 1863cd0d46ebSvictorle } 1864cd0d46ebSvictorle EXTERN_C_END 1865cd0d46ebSvictorle 18661cbb95d3SBarry Smith EXTERN_C_BEGIN 18671cbb95d3SBarry Smith #undef __FUNCT__ 18681cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitianTranspose_SeqAIJ" 18697087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 18701cbb95d3SBarry Smith { 18711cbb95d3SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *) A->data,*bij = (Mat_SeqAIJ*) A->data; 187254f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 187354f21887SBarry Smith MatScalar *va,*vb; 18741cbb95d3SBarry Smith PetscErrorCode ierr; 18751cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 18761cbb95d3SBarry Smith 18771cbb95d3SBarry Smith PetscFunctionBegin; 18781cbb95d3SBarry Smith bij = (Mat_SeqAIJ *) B->data; 18791cbb95d3SBarry Smith 18801cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 18811cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 18821cbb95d3SBarry Smith if (ma!=nb || na!=mb){ 18831cbb95d3SBarry Smith *f = PETSC_FALSE; 18841cbb95d3SBarry Smith PetscFunctionReturn(0); 18851cbb95d3SBarry Smith } 18861cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 18871cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 18881cbb95d3SBarry Smith va = aij->a; vb = bij->a; 18891cbb95d3SBarry Smith ierr = PetscMalloc(ma*sizeof(PetscInt),&aptr);CHKERRQ(ierr); 18901cbb95d3SBarry Smith ierr = PetscMalloc(mb*sizeof(PetscInt),&bptr);CHKERRQ(ierr); 18911cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 18921cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 18931cbb95d3SBarry Smith 18941cbb95d3SBarry Smith *f = PETSC_TRUE; 18951cbb95d3SBarry Smith for (i=0; i<ma; i++) { 18961cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 18971cbb95d3SBarry Smith PetscInt idc,idr; 18981cbb95d3SBarry Smith PetscScalar vc,vr; 18991cbb95d3SBarry Smith /* column/row index/value */ 19001cbb95d3SBarry Smith idc = adx[aptr[i]]; 19011cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 19021cbb95d3SBarry Smith vc = va[aptr[i]]; 19031cbb95d3SBarry Smith vr = vb[bptr[idc]]; 19041cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 19051cbb95d3SBarry Smith *f = PETSC_FALSE; 19061cbb95d3SBarry Smith goto done; 19071cbb95d3SBarry Smith } else { 19081cbb95d3SBarry Smith aptr[i]++; 19091cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 19101cbb95d3SBarry Smith } 19111cbb95d3SBarry Smith } 19121cbb95d3SBarry Smith } 19131cbb95d3SBarry Smith done: 19141cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 19151cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 19161cbb95d3SBarry Smith PetscFunctionReturn(0); 19171cbb95d3SBarry Smith } 19181cbb95d3SBarry Smith EXTERN_C_END 19191cbb95d3SBarry Smith 19209e29f15eSvictorle #undef __FUNCT__ 19219e29f15eSvictorle #define __FUNCT__ "MatIsSymmetric_SeqAIJ" 1922ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 19239e29f15eSvictorle { 1924dfbe8321SBarry Smith PetscErrorCode ierr; 19259e29f15eSvictorle PetscFunctionBegin; 19265485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 19279e29f15eSvictorle PetscFunctionReturn(0); 19289e29f15eSvictorle } 19299e29f15eSvictorle 19304a2ae208SSatish Balay #undef __FUNCT__ 19311cbb95d3SBarry Smith #define __FUNCT__ "MatIsHermitian_SeqAIJ" 1932ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 19331cbb95d3SBarry Smith { 19341cbb95d3SBarry Smith PetscErrorCode ierr; 19351cbb95d3SBarry Smith PetscFunctionBegin; 19361cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 19371cbb95d3SBarry Smith PetscFunctionReturn(0); 19381cbb95d3SBarry Smith } 19391cbb95d3SBarry Smith 19401cbb95d3SBarry Smith #undef __FUNCT__ 19414a2ae208SSatish Balay #define __FUNCT__ "MatDiagonalScale_SeqAIJ" 1942dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 194317ab2063SBarry Smith { 1944416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 194554f21887SBarry Smith PetscScalar *l,*r,x; 194654f21887SBarry Smith MatScalar *v; 1947dfbe8321SBarry Smith PetscErrorCode ierr; 1948d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 194917ab2063SBarry Smith 19503a40ed3dSBarry Smith PetscFunctionBegin; 195117ab2063SBarry Smith if (ll) { 19523ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 19533ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 1954e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 1955e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 19561ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 1957416022c9SBarry Smith v = a->a; 195817ab2063SBarry Smith for (i=0; i<m; i++) { 195917ab2063SBarry Smith x = l[i]; 1960416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 196117ab2063SBarry Smith for (j=0; j<M; j++) { (*v++) *= x;} 196217ab2063SBarry Smith } 19631ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 1964efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 196517ab2063SBarry Smith } 196617ab2063SBarry Smith if (rr) { 1967e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 1968e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 19691ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 1970416022c9SBarry Smith v = a->a; jj = a->j; 197117ab2063SBarry Smith for (i=0; i<nz; i++) { 1972bfeeae90SHong Zhang (*v++) *= r[*jj++]; 197317ab2063SBarry Smith } 19741ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 1975efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 197617ab2063SBarry Smith } 19770847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 19783a40ed3dSBarry Smith PetscFunctionReturn(0); 197917ab2063SBarry Smith } 198017ab2063SBarry Smith 19814a2ae208SSatish Balay #undef __FUNCT__ 19824a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrix_SeqAIJ" 198397f1f81fSBarry Smith PetscErrorCode MatGetSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 198417ab2063SBarry Smith { 1985db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 19866849ba73SBarry Smith PetscErrorCode ierr; 1987d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 198897f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 19895d0c19d7SBarry Smith const PetscInt *irow,*icol; 19905d0c19d7SBarry Smith PetscInt nrows,ncols; 199197f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 199254f21887SBarry Smith MatScalar *a_new,*mat_a; 1993416022c9SBarry Smith Mat C; 1994ace3abfcSBarry Smith PetscBool stride,sorted; 199517ab2063SBarry Smith 19963a40ed3dSBarry Smith PetscFunctionBegin; 199714ca34e6SBarry Smith ierr = ISSorted(isrow,&sorted);CHKERRQ(ierr); 1998e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"ISrow is not sorted"); 199914ca34e6SBarry Smith ierr = ISSorted(iscol,&sorted);CHKERRQ(ierr); 2000e32f2f54SBarry Smith if (!sorted) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"IScol is not sorted"); 200199141d43SSatish Balay 200217ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2003b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2004b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 200517ab2063SBarry Smith 2006fee21e36SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2007251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2008fee21e36SBarry Smith if (stride && step == 1) { 200902834360SBarry Smith /* special case of contiguous rows */ 20100e83c824SBarry Smith ierr = PetscMalloc2(nrows,PetscInt,&lens,nrows,PetscInt,&starts);CHKERRQ(ierr); 201102834360SBarry Smith /* loop over new rows determining lens and starting points */ 201202834360SBarry Smith for (i=0; i<nrows; i++) { 2013bfeeae90SHong Zhang kstart = ai[irow[i]]; 2014a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 201502834360SBarry Smith for (k=kstart; k<kend; k++) { 2016bfeeae90SHong Zhang if (aj[k] >= first) { 201702834360SBarry Smith starts[i] = k; 201802834360SBarry Smith break; 201902834360SBarry Smith } 202002834360SBarry Smith } 2021a2744918SBarry Smith sum = 0; 202202834360SBarry Smith while (k < kend) { 2023bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2024a2744918SBarry Smith sum++; 202502834360SBarry Smith } 2026a2744918SBarry Smith lens[i] = sum; 202702834360SBarry Smith } 202802834360SBarry Smith /* create submatrix */ 2029cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 203097f1f81fSBarry Smith PetscInt n_cols,n_rows; 203108480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2032e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2033d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 203408480c60SBarry Smith C = *B; 20353a40ed3dSBarry Smith } else { 20363bef6203SJed Brown PetscInt rbs,cbs; 20377adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 2038f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 20393bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 20403bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 20413bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 20427adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2043ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 204408480c60SBarry Smith } 2045db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2046db02288aSLois Curfman McInnes 204702834360SBarry Smith /* loop over rows inserting into submatrix */ 2048db02288aSLois Curfman McInnes a_new = c->a; 2049db02288aSLois Curfman McInnes j_new = c->j; 2050db02288aSLois Curfman McInnes i_new = c->i; 2051bfeeae90SHong Zhang 205202834360SBarry Smith for (i=0; i<nrows; i++) { 2053a2744918SBarry Smith ii = starts[i]; 2054a2744918SBarry Smith lensi = lens[i]; 2055a2744918SBarry Smith for (k=0; k<lensi; k++) { 2056a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 205702834360SBarry Smith } 205887828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2059a2744918SBarry Smith a_new += lensi; 2060a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2061a2744918SBarry Smith c->ilen[i] = lensi; 206202834360SBarry Smith } 20630e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 20643a40ed3dSBarry Smith } else { 206502834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 20660e83c824SBarry Smith ierr = PetscMalloc(oldcols*sizeof(PetscInt),&smap);CHKERRQ(ierr); 206797f1f81fSBarry Smith ierr = PetscMemzero(smap,oldcols*sizeof(PetscInt));CHKERRQ(ierr); 20680e83c824SBarry Smith ierr = PetscMalloc((1+nrows)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 20694dcab191SBarry Smith for (i=0; i<ncols; i++) { 20704dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 20714dcab191SBarry Smith if (icol[i] >= oldcols) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Requesting column beyond largest column icol[%D] %D <= A->cmap->n %D",i,icol[i],oldcols); 20724dcab191SBarry Smith #endif 20734dcab191SBarry Smith smap[icol[i]] = i+1; 20744dcab191SBarry Smith } 20754dcab191SBarry Smith 207602834360SBarry Smith /* determine lens of each row */ 207702834360SBarry Smith for (i=0; i<nrows; i++) { 2078bfeeae90SHong Zhang kstart = ai[irow[i]]; 207902834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 208002834360SBarry Smith lens[i] = 0; 208102834360SBarry Smith for (k=kstart; k<kend; k++) { 2082bfeeae90SHong Zhang if (smap[aj[k]]) { 208302834360SBarry Smith lens[i]++; 208402834360SBarry Smith } 208502834360SBarry Smith } 208602834360SBarry Smith } 208717ab2063SBarry Smith /* Create and fill new matrix */ 2088a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2089ace3abfcSBarry Smith PetscBool equal; 20900f5bd95cSBarry Smith 209199141d43SSatish Balay c = (Mat_SeqAIJ *)((*B)->data); 2092e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2093d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 20940f5bd95cSBarry Smith if (!equal) { 2095e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 209699141d43SSatish Balay } 2097d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 209808480c60SBarry Smith C = *B; 20993a40ed3dSBarry Smith } else { 21003bef6203SJed Brown PetscInt rbs,cbs; 21017adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,&C);CHKERRQ(ierr); 2102f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 21033bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 21043bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 21053bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 21067adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2107ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 210808480c60SBarry Smith } 210999141d43SSatish Balay c = (Mat_SeqAIJ *)(C->data); 211017ab2063SBarry Smith for (i=0; i<nrows; i++) { 211199141d43SSatish Balay row = irow[i]; 2112bfeeae90SHong Zhang kstart = ai[row]; 211399141d43SSatish Balay kend = kstart + a->ilen[row]; 2114bfeeae90SHong Zhang mat_i = c->i[i]; 211599141d43SSatish Balay mat_j = c->j + mat_i; 211699141d43SSatish Balay mat_a = c->a + mat_i; 211799141d43SSatish Balay mat_ilen = c->ilen + i; 211817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2119bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2120ed480e8bSBarry Smith *mat_j++ = tcol - 1; 212199141d43SSatish Balay *mat_a++ = a->a[k]; 212299141d43SSatish Balay (*mat_ilen)++; 212399141d43SSatish Balay 212417ab2063SBarry Smith } 212517ab2063SBarry Smith } 212617ab2063SBarry Smith } 212702834360SBarry Smith /* Free work space */ 212802834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2129606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2130606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 213102834360SBarry Smith } 21326d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 21336d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 213417ab2063SBarry Smith 213517ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2136416022c9SBarry Smith *B = C; 21373a40ed3dSBarry Smith PetscFunctionReturn(0); 213817ab2063SBarry Smith } 213917ab2063SBarry Smith 21401df811f5SHong Zhang #undef __FUNCT__ 214182d44351SHong Zhang #define __FUNCT__ "MatGetMultiProcBlock_SeqAIJ" 2142fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat* subMat) 214382d44351SHong Zhang { 214482d44351SHong Zhang PetscErrorCode ierr; 214582d44351SHong Zhang Mat B; 214682d44351SHong Zhang 214782d44351SHong Zhang PetscFunctionBegin; 214882d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 214982d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 2150a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,mat->rmap->bs,mat->cmap->bs); CHKERRQ(ierr); 215182d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 215282d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 215382d44351SHong Zhang *subMat = B; 215482d44351SHong Zhang PetscFunctionReturn(0); 215582d44351SHong Zhang } 215682d44351SHong Zhang 215782d44351SHong Zhang #undef __FUNCT__ 21584a2ae208SSatish Balay #define __FUNCT__ "MatILUFactor_SeqAIJ" 21590481f469SBarry Smith PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2160a871dcd8SBarry Smith { 216163b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2162dfbe8321SBarry Smith PetscErrorCode ierr; 216363b91edcSBarry Smith Mat outA; 2164ace3abfcSBarry Smith PetscBool row_identity,col_identity; 216563b91edcSBarry Smith 21663a40ed3dSBarry Smith PetscFunctionBegin; 2167e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 21681df811f5SHong Zhang 2169b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2170b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2171a871dcd8SBarry Smith 217263b91edcSBarry Smith outA = inA; 2173d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2174c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 21756bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 2176c3122656SLisandro Dalcin a->row = row; 2177c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 21786bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 2179c3122656SLisandro Dalcin a->col = col; 218063b91edcSBarry Smith 218136db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 21826bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 21834c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 218452e6d16bSBarry Smith ierr = PetscLogObjectParent(inA,a->icol);CHKERRQ(ierr); 2185f0ec6fceSSatish Balay 218694a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2187d0f46423SBarry Smith ierr = PetscMalloc((inA->rmap->n+1)*sizeof(PetscScalar),&a->solve_work);CHKERRQ(ierr); 2188d0f46423SBarry Smith ierr = PetscLogObjectMemory(inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 218994a9d846SBarry Smith } 219063b91edcSBarry Smith 2191f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2192137fb511SHong Zhang if (row_identity && col_identity) { 2193ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2194137fb511SHong Zhang } else { 2195719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2196137fb511SHong Zhang } 21973a40ed3dSBarry Smith PetscFunctionReturn(0); 2198a871dcd8SBarry Smith } 2199a871dcd8SBarry Smith 22004a2ae208SSatish Balay #undef __FUNCT__ 22014a2ae208SSatish Balay #define __FUNCT__ "MatScale_SeqAIJ" 2202f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2203f0b747eeSBarry Smith { 2204f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2205f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2206efee365bSSatish Balay PetscErrorCode ierr; 22070805154bSBarry Smith PetscBLASInt one = 1,bnz = PetscBLASIntCast(a->nz); 22083a40ed3dSBarry Smith 22093a40ed3dSBarry Smith PetscFunctionBegin; 2210f4df32b1SMatthew Knepley BLASscal_(&bnz,&oalpha,a->a,&one); 2211efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 22120847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 22133a40ed3dSBarry Smith PetscFunctionReturn(0); 2214f0b747eeSBarry Smith } 2215f0b747eeSBarry Smith 22164a2ae208SSatish Balay #undef __FUNCT__ 22174a2ae208SSatish Balay #define __FUNCT__ "MatGetSubMatrices_SeqAIJ" 221897f1f81fSBarry Smith PetscErrorCode MatGetSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2219cddf8d76SBarry Smith { 2220dfbe8321SBarry Smith PetscErrorCode ierr; 222197f1f81fSBarry Smith PetscInt i; 2222cddf8d76SBarry Smith 22233a40ed3dSBarry Smith PetscFunctionBegin; 2224cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2225b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(Mat),B);CHKERRQ(ierr); 2226cddf8d76SBarry Smith } 2227cddf8d76SBarry Smith 2228cddf8d76SBarry Smith for (i=0; i<n; i++) { 22296a6a5d1dSBarry Smith ierr = MatGetSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2230cddf8d76SBarry Smith } 22313a40ed3dSBarry Smith PetscFunctionReturn(0); 2232cddf8d76SBarry Smith } 2233cddf8d76SBarry Smith 22344a2ae208SSatish Balay #undef __FUNCT__ 22354a2ae208SSatish Balay #define __FUNCT__ "MatIncreaseOverlap_SeqAIJ" 223697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 22374dcbc457SBarry Smith { 2238e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22396849ba73SBarry Smith PetscErrorCode ierr; 22405d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 22415d0c19d7SBarry Smith const PetscInt *idx; 224297f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2243f1af5d2fSBarry Smith PetscBT table; 2244bbd702dbSSatish Balay 22453a40ed3dSBarry Smith PetscFunctionBegin; 2246d0f46423SBarry Smith m = A->rmap->n; 2247e4d965acSSatish Balay ai = a->i; 2248bfeeae90SHong Zhang aj = a->j; 22498a047759SSatish Balay 2250e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 225106763907SSatish Balay 225297f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&nidx);CHKERRQ(ierr); 225353b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 225406763907SSatish Balay 2255e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2256b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2257e4d965acSSatish Balay isz = 0; 22586831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2259e4d965acSSatish Balay 2260e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 22614dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2262b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2263e4d965acSSatish Balay 2264dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2265e4d965acSSatish Balay for (j=0; j<n ; ++j){ 2266f1af5d2fSBarry Smith if(!PetscBTLookupSet(table,idx[j])) { nidx[isz++] = idx[j];} 22674dcbc457SBarry Smith } 226806763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 22696bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2270e4d965acSSatish Balay 227104a348a9SBarry Smith k = 0; 227204a348a9SBarry Smith for (j=0; j<ov; j++){ /* for each overlap */ 227304a348a9SBarry Smith n = isz; 227406763907SSatish Balay for (; k<n ; k++){ /* do only those rows in nidx[k], which are not done yet */ 2275e4d965acSSatish Balay row = nidx[k]; 2276e4d965acSSatish Balay start = ai[row]; 2277e4d965acSSatish Balay end = ai[row+1]; 227804a348a9SBarry Smith for (l = start; l<end ; l++){ 2279efb16452SHong Zhang val = aj[l] ; 2280f1af5d2fSBarry Smith if (!PetscBTLookupSet(table,val)) {nidx[isz++] = val;} 2281e4d965acSSatish Balay } 2282e4d965acSSatish Balay } 2283e4d965acSSatish Balay } 228470b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2285e4d965acSSatish Balay } 228694bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2287606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 22883a40ed3dSBarry Smith PetscFunctionReturn(0); 22894dcbc457SBarry Smith } 229017ab2063SBarry Smith 22910513a670SBarry Smith /* -------------------------------------------------------------- */ 22924a2ae208SSatish Balay #undef __FUNCT__ 22934a2ae208SSatish Balay #define __FUNCT__ "MatPermute_SeqAIJ" 2294dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 22950513a670SBarry Smith { 22960513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 22976849ba73SBarry Smith PetscErrorCode ierr; 22983b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 22995d0c19d7SBarry Smith const PetscInt *row,*col; 23005d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 230156cd22aeSBarry Smith IS icolp,irowp; 23023b98c0a2SBarry Smith PetscInt *cwork = PETSC_NULL; 23033b98c0a2SBarry Smith PetscScalar *vwork = PETSC_NULL; 23040513a670SBarry Smith 23053a40ed3dSBarry Smith PetscFunctionBegin; 23064c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 230756cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 23084c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 230956cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 23100513a670SBarry Smith 23110513a670SBarry Smith /* determine lengths of permuted rows */ 231297f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&lens);CHKERRQ(ierr); 23130513a670SBarry Smith for (i=0; i<m; i++) { 23140513a670SBarry Smith lens[row[i]] = a->i[i+1] - a->i[i]; 23150513a670SBarry Smith } 23167adad957SLisandro Dalcin ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 2317f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 2318a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 23197adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2320ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2321606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 23220513a670SBarry Smith 232397f1f81fSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&cnew);CHKERRQ(ierr); 23240513a670SBarry Smith for (i=0; i<m; i++) { 232532ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 23260513a670SBarry Smith for (j=0; j<nz; j++) { cnew[j] = col[cwork[j]];} 2327cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 232832ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 23290513a670SBarry Smith } 2330606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 23313c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 23320513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23330513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 233456cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 233556cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 23366bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 23376bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 23383a40ed3dSBarry Smith PetscFunctionReturn(0); 23390513a670SBarry Smith } 23400513a670SBarry Smith 23414a2ae208SSatish Balay #undef __FUNCT__ 23424a2ae208SSatish Balay #define __FUNCT__ "MatCopy_SeqAIJ" 2343dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2344cb5b572fSBarry Smith { 2345dfbe8321SBarry Smith PetscErrorCode ierr; 2346cb5b572fSBarry Smith 2347cb5b572fSBarry Smith PetscFunctionBegin; 234833f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 234933f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2350be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2351be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2352be6bf707SBarry Smith 2353700c5bfcSBarry 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"); 2354d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2355cb5b572fSBarry Smith } else { 2356cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2357cb5b572fSBarry Smith } 2358cb5b572fSBarry Smith PetscFunctionReturn(0); 2359cb5b572fSBarry Smith } 2360cb5b572fSBarry Smith 23614a2ae208SSatish Balay #undef __FUNCT__ 23624994cf47SJed Brown #define __FUNCT__ "MatSetUp_SeqAIJ" 23634994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2364273d9f13SBarry Smith { 2365dfbe8321SBarry Smith PetscErrorCode ierr; 2366273d9f13SBarry Smith 2367273d9f13SBarry Smith PetscFunctionBegin; 2368ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2369273d9f13SBarry Smith PetscFunctionReturn(0); 2370273d9f13SBarry Smith } 2371273d9f13SBarry Smith 23724a2ae208SSatish Balay #undef __FUNCT__ 23734a2ae208SSatish Balay #define __FUNCT__ "MatGetArray_SeqAIJ" 2374a77337e4SBarry Smith PetscErrorCode MatGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 23756c0721eeSBarry Smith { 23766c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 23776c0721eeSBarry Smith PetscFunctionBegin; 23786c0721eeSBarry Smith *array = a->a; 23796c0721eeSBarry Smith PetscFunctionReturn(0); 23806c0721eeSBarry Smith } 23816c0721eeSBarry Smith 23824a2ae208SSatish Balay #undef __FUNCT__ 23834a2ae208SSatish Balay #define __FUNCT__ "MatRestoreArray_SeqAIJ" 2384dfbe8321SBarry Smith PetscErrorCode MatRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 23856c0721eeSBarry Smith { 23866c0721eeSBarry Smith PetscFunctionBegin; 23876c0721eeSBarry Smith PetscFunctionReturn(0); 23886c0721eeSBarry Smith } 2389273d9f13SBarry Smith 2390ee4f033dSBarry Smith #undef __FUNCT__ 2391ee4f033dSBarry Smith #define __FUNCT__ "MatFDColoringApply_SeqAIJ" 2392dfbe8321SBarry Smith PetscErrorCode MatFDColoringApply_SeqAIJ(Mat J,MatFDColoring coloring,Vec x1,MatStructure *flag,void *sctx) 2393ee4f033dSBarry Smith { 23946849ba73SBarry Smith PetscErrorCode (*f)(void*,Vec,Vec,void*) = (PetscErrorCode (*)(void*,Vec,Vec,void *))coloring->f; 23956849ba73SBarry Smith PetscErrorCode ierr; 239697f1f81fSBarry Smith PetscInt k,N,start,end,l,row,col,srow,**vscaleforrow,m1,m2; 2397efb30889SBarry Smith PetscScalar dx,*y,*xx,*w3_array; 239887828ca2SBarry Smith PetscScalar *vscale_array; 2399ee4f033dSBarry Smith PetscReal epsilon = coloring->error_rel,umin = coloring->umin; 2400ee4f033dSBarry Smith Vec w1,w2,w3; 2401ee4f033dSBarry Smith void *fctx = coloring->fctx; 2402ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 2403ee4f033dSBarry Smith 2404ee4f033dSBarry Smith PetscFunctionBegin; 2405ee4f033dSBarry Smith if (!coloring->w1) { 2406ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w1);CHKERRQ(ierr); 240752e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w1);CHKERRQ(ierr); 2408ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w2);CHKERRQ(ierr); 240952e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w2);CHKERRQ(ierr); 2410ee4f033dSBarry Smith ierr = VecDuplicate(x1,&coloring->w3);CHKERRQ(ierr); 241152e6d16bSBarry Smith ierr = PetscLogObjectParent(coloring,coloring->w3);CHKERRQ(ierr); 2412ee4f033dSBarry Smith } 2413ee4f033dSBarry Smith w1 = coloring->w1; w2 = coloring->w2; w3 = coloring->w3; 2414ee4f033dSBarry Smith 2415ee4f033dSBarry Smith ierr = MatSetUnfactored(J);CHKERRQ(ierr); 2416acfcf0e5SJed Brown ierr = PetscOptionsGetBool(((PetscObject)coloring)->prefix,"-mat_fd_coloring_dont_rezero",&flg,PETSC_NULL);CHKERRQ(ierr); 2417ee4f033dSBarry Smith if (flg) { 2418ae15b995SBarry Smith ierr = PetscInfo(coloring,"Not calling MatZeroEntries()\n");CHKERRQ(ierr); 2419ee4f033dSBarry Smith } else { 2420ace3abfcSBarry Smith PetscBool assembled; 24210b9b6f31SBarry Smith ierr = MatAssembled(J,&assembled);CHKERRQ(ierr); 24220b9b6f31SBarry Smith if (assembled) { 2423ee4f033dSBarry Smith ierr = MatZeroEntries(J);CHKERRQ(ierr); 2424ee4f033dSBarry Smith } 24250b9b6f31SBarry Smith } 2426ee4f033dSBarry Smith 2427ee4f033dSBarry Smith ierr = VecGetOwnershipRange(x1,&start,&end);CHKERRQ(ierr); 2428ee4f033dSBarry Smith ierr = VecGetSize(x1,&N);CHKERRQ(ierr); 2429ee4f033dSBarry Smith 2430ee4f033dSBarry Smith /* 243198bf7241SBarry Smith This is a horrible, horrible, hack. 2432ee4f033dSBarry Smith */ 2433ee4f033dSBarry Smith if (coloring->F) { 2434ee4f033dSBarry Smith ierr = VecGetLocalSize(coloring->F,&m1);CHKERRQ(ierr); 2435ee4f033dSBarry Smith ierr = VecGetLocalSize(w1,&m2);CHKERRQ(ierr); 2436ee4f033dSBarry Smith if (m1 != m2) { 2437ee4f033dSBarry Smith coloring->F = 0; 2438ee4f033dSBarry Smith } 2439ee4f033dSBarry Smith } 2440ee4f033dSBarry Smith 2441ee4f033dSBarry Smith if (coloring->F) { 2442ee4f033dSBarry Smith w1 = coloring->F; 2443ee4f033dSBarry Smith coloring->F = 0; 2444ee4f033dSBarry Smith } else { 244566f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2446ee4f033dSBarry Smith ierr = (*f)(sctx,x1,w1,fctx);CHKERRQ(ierr); 244766f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2448ee4f033dSBarry Smith } 2449ee4f033dSBarry Smith 2450ee4f033dSBarry Smith /* 2451ee4f033dSBarry Smith Compute all the scale factors and share with other processors 2452ee4f033dSBarry Smith */ 24531ebc52fbSHong Zhang ierr = VecGetArray(x1,&xx);CHKERRQ(ierr);xx = xx - start; 24541ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr);vscale_array = vscale_array - start; 2455ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 2456ee4f033dSBarry Smith /* 2457ee4f033dSBarry Smith Loop over each column associated with color adding the 2458ee4f033dSBarry Smith perturbation to the vector w3. 2459ee4f033dSBarry Smith */ 2460ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2461ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2462ee4f033dSBarry Smith dx = xx[col]; 2463ee4f033dSBarry Smith if (dx == 0.0) dx = 1.0; 2464ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2465ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2466ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2467ee4f033dSBarry Smith #else 2468ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2469ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2470ee4f033dSBarry Smith #endif 2471ee4f033dSBarry Smith dx *= epsilon; 2472ee4f033dSBarry Smith vscale_array[col] = 1.0/dx; 2473ee4f033dSBarry Smith } 2474ee4f033dSBarry Smith } 24751ebc52fbSHong Zhang vscale_array = vscale_array + start;ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2476ee4f033dSBarry Smith ierr = VecGhostUpdateBegin(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2477ee4f033dSBarry Smith ierr = VecGhostUpdateEnd(coloring->vscale,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2478ee4f033dSBarry Smith 2479ee4f033dSBarry Smith /* ierr = VecView(coloring->vscale,PETSC_VIEWER_STDOUT_WORLD); 2480ee4f033dSBarry Smith ierr = VecView(x1,PETSC_VIEWER_STDOUT_WORLD);*/ 2481ee4f033dSBarry Smith 2482ee4f033dSBarry Smith if (coloring->vscaleforrow) vscaleforrow = coloring->vscaleforrow; 2483ee4f033dSBarry Smith else vscaleforrow = coloring->columnsforrow; 2484ee4f033dSBarry Smith 24851ebc52fbSHong Zhang ierr = VecGetArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 2486ee4f033dSBarry Smith /* 2487ee4f033dSBarry Smith Loop over each color 2488ee4f033dSBarry Smith */ 2489ee4f033dSBarry Smith for (k=0; k<coloring->ncolors; k++) { 249049b058dcSBarry Smith coloring->currentcolor = k; 2491ee4f033dSBarry Smith ierr = VecCopy(x1,w3);CHKERRQ(ierr); 24921ebc52fbSHong Zhang ierr = VecGetArray(w3,&w3_array);CHKERRQ(ierr);w3_array = w3_array - start; 2493ee4f033dSBarry Smith /* 2494ee4f033dSBarry Smith Loop over each column associated with color adding the 2495ee4f033dSBarry Smith perturbation to the vector w3. 2496ee4f033dSBarry Smith */ 2497ee4f033dSBarry Smith for (l=0; l<coloring->ncolumns[k]; l++) { 2498ee4f033dSBarry Smith col = coloring->columns[k][l]; /* column of the matrix we are probing for */ 2499ee4f033dSBarry Smith dx = xx[col]; 25005b8514ebSBarry Smith if (dx == 0.0) dx = 1.0; 2501ee4f033dSBarry Smith #if !defined(PETSC_USE_COMPLEX) 2502ee4f033dSBarry Smith if (dx < umin && dx >= 0.0) dx = umin; 2503ee4f033dSBarry Smith else if (dx < 0.0 && dx > -umin) dx = -umin; 2504ee4f033dSBarry Smith #else 2505ee4f033dSBarry Smith if (PetscAbsScalar(dx) < umin && PetscRealPart(dx) >= 0.0) dx = umin; 2506ee4f033dSBarry Smith else if (PetscRealPart(dx) < 0.0 && PetscAbsScalar(dx) < umin) dx = -umin; 2507ee4f033dSBarry Smith #endif 2508ee4f033dSBarry Smith dx *= epsilon; 2509e32f2f54SBarry Smith if (!PetscAbsScalar(dx)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Computed 0 differencing parameter"); 2510ee4f033dSBarry Smith w3_array[col] += dx; 2511ee4f033dSBarry Smith } 25121ebc52fbSHong Zhang w3_array = w3_array + start; ierr = VecRestoreArray(w3,&w3_array);CHKERRQ(ierr); 2513ee4f033dSBarry Smith 2514ee4f033dSBarry Smith /* 2515ee4f033dSBarry Smith Evaluate function at x1 + dx (here dx is a vector of perturbations) 2516ee4f033dSBarry Smith */ 2517ee4f033dSBarry Smith 251866f9b7ceSBarry Smith ierr = PetscLogEventBegin(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2519ee4f033dSBarry Smith ierr = (*f)(sctx,w3,w2,fctx);CHKERRQ(ierr); 252066f9b7ceSBarry Smith ierr = PetscLogEventEnd(MAT_FDColoringFunction,0,0,0,0);CHKERRQ(ierr); 2521efb30889SBarry Smith ierr = VecAXPY(w2,-1.0,w1);CHKERRQ(ierr); 2522ee4f033dSBarry Smith 2523ee4f033dSBarry Smith /* 2524ee4f033dSBarry Smith Loop over rows of vector, putting results into Jacobian matrix 2525ee4f033dSBarry Smith */ 25261ebc52fbSHong Zhang ierr = VecGetArray(w2,&y);CHKERRQ(ierr); 2527ee4f033dSBarry Smith for (l=0; l<coloring->nrows[k]; l++) { 2528ee4f033dSBarry Smith row = coloring->rows[k][l]; 2529ee4f033dSBarry Smith col = coloring->columnsforrow[k][l]; 2530ee4f033dSBarry Smith y[row] *= vscale_array[vscaleforrow[k][l]]; 2531ee4f033dSBarry Smith srow = row + start; 2532ee4f033dSBarry Smith ierr = MatSetValues_SeqAIJ(J,1,&srow,1,&col,y+row,INSERT_VALUES);CHKERRQ(ierr); 2533ee4f033dSBarry Smith } 25341ebc52fbSHong Zhang ierr = VecRestoreArray(w2,&y);CHKERRQ(ierr); 2535ee4f033dSBarry Smith } 253649b058dcSBarry Smith coloring->currentcolor = k; 25371ebc52fbSHong Zhang ierr = VecRestoreArray(coloring->vscale,&vscale_array);CHKERRQ(ierr); 25381ebc52fbSHong Zhang xx = xx + start; ierr = VecRestoreArray(x1,&xx);CHKERRQ(ierr); 2539ee4f033dSBarry Smith ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2540ee4f033dSBarry Smith ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2541ee4f033dSBarry Smith PetscFunctionReturn(0); 2542ee4f033dSBarry Smith } 2543ee4f033dSBarry Smith 25448229c054SShri Abhyankar /* 25458229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 25468229c054SShri Abhyankar have different nonzero structure. 25478229c054SShri Abhyankar */ 2548ac90fabeSBarry Smith #undef __FUNCT__ 25498229c054SShri Abhyankar #define __FUNCT__ "MatAXPYGetPreallocation_SeqAIJ" 25508229c054SShri Abhyankar PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt* nnz) 2551ec7775f6SShri Abhyankar { 25528229c054SShri Abhyankar PetscInt i,m=Y->rmap->N; 2553ec7775f6SShri Abhyankar Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2554ec7775f6SShri Abhyankar Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2555ec7775f6SShri Abhyankar const PetscInt *xi = x->i,*yi = y->i; 2556ec7775f6SShri Abhyankar 2557ec7775f6SShri Abhyankar PetscFunctionBegin; 2558ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2559ec7775f6SShri Abhyankar for(i=0; i<m; i++) { 25608af7cee1SJed Brown PetscInt j,k,nzx = xi[i+1] - xi[i],nzy = yi[i+1] - yi[i]; 25618af7cee1SJed Brown const PetscInt *xj = x->j+xi[i],*yj = y->j+yi[i]; 25628af7cee1SJed Brown nnz[i] = 0; 25638af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 25648af7cee1SJed Brown for (; k<nzy && yj[k]<xj[j]; k++) nnz[i]++; /* Catch up to X */ 25658af7cee1SJed Brown if (k<nzy && yj[k]==xj[j]) k++; /* Skip duplicate */ 25668af7cee1SJed Brown nnz[i]++; 25678af7cee1SJed Brown } 25688af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2569ec7775f6SShri Abhyankar } 2570ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2571ec7775f6SShri Abhyankar } 2572ec7775f6SShri Abhyankar 2573ec7775f6SShri Abhyankar #undef __FUNCT__ 2574ac90fabeSBarry Smith #define __FUNCT__ "MatAXPY_SeqAIJ" 2575f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2576ac90fabeSBarry Smith { 2577dfbe8321SBarry Smith PetscErrorCode ierr; 257897f1f81fSBarry Smith PetscInt i; 2579ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ *)X->data,*y = (Mat_SeqAIJ *)Y->data; 25800805154bSBarry Smith PetscBLASInt one=1,bnz = PetscBLASIntCast(x->nz); 2581ac90fabeSBarry Smith 2582ac90fabeSBarry Smith PetscFunctionBegin; 2583ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2584f4df32b1SMatthew Knepley PetscScalar alpha = a; 2585f4df32b1SMatthew Knepley BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one); 25860847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2587c537a176SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2588a30b2313SHong Zhang if (y->xtoy && y->XtoY != X) { 2589a30b2313SHong Zhang ierr = PetscFree(y->xtoy);CHKERRQ(ierr); 25906bf464f9SBarry Smith ierr = MatDestroy(&y->XtoY);CHKERRQ(ierr); 2591a30b2313SHong Zhang } 2592a30b2313SHong Zhang if (!y->xtoy) { /* get xtoy */ 2593d0f46423SBarry Smith ierr = MatAXPYGetxtoy_Private(X->rmap->n,x->i,x->j,PETSC_NULL, y->i,y->j,PETSC_NULL, &y->xtoy);CHKERRQ(ierr); 2594a30b2313SHong Zhang y->XtoY = X; 2595407f6b05SHong Zhang ierr = PetscObjectReference((PetscObject)X);CHKERRQ(ierr); 2596c537a176SHong Zhang } 2597f4df32b1SMatthew Knepley for (i=0; i<x->nz; i++) y->a[y->xtoy[i]] += a*(x->a[i]); 25988644d96aSMark F. Adams ierr = PetscInfo3(Y,"ratio of nnz(X)/nnz(Y): %d/%d = %G\n",x->nz,y->nz,(PetscReal)(x->nz)/(y->nz+1));CHKERRQ(ierr); 2599ac90fabeSBarry Smith } else { 26008229c054SShri Abhyankar Mat B; 26018229c054SShri Abhyankar PetscInt *nnz; 260216b2e9dcSShri Abhyankar ierr = PetscMalloc(Y->rmap->N*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 2603ec7775f6SShri Abhyankar ierr = MatCreate(((PetscObject)Y)->comm,&B);CHKERRQ(ierr); 2604bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 26054aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 2606a2f3521dSMark F. Adams ierr = MatSetBlockSizes(B,Y->rmap->bs,Y->cmap->bs);CHKERRQ(ierr); 2607176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 26088229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2609ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2610ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 2611ec7775f6SShri Abhyankar ierr = MatHeaderReplace(Y,B);CHKERRQ(ierr); 26128229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2613ac90fabeSBarry Smith } 2614ac90fabeSBarry Smith PetscFunctionReturn(0); 2615ac90fabeSBarry Smith } 2616ac90fabeSBarry Smith 2617521d7252SBarry Smith #undef __FUNCT__ 2618354c94deSBarry Smith #define __FUNCT__ "MatConjugate_SeqAIJ" 26197087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2620354c94deSBarry Smith { 2621354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2622354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 2623354c94deSBarry Smith PetscInt i,nz; 2624354c94deSBarry Smith PetscScalar *a; 2625354c94deSBarry Smith 2626354c94deSBarry Smith PetscFunctionBegin; 2627354c94deSBarry Smith nz = aij->nz; 2628354c94deSBarry Smith a = aij->a; 2629354c94deSBarry Smith for (i=0; i<nz; i++) { 2630354c94deSBarry Smith a[i] = PetscConj(a[i]); 2631354c94deSBarry Smith } 2632354c94deSBarry Smith #else 2633354c94deSBarry Smith PetscFunctionBegin; 2634354c94deSBarry Smith #endif 2635354c94deSBarry Smith PetscFunctionReturn(0); 2636354c94deSBarry Smith } 2637354c94deSBarry Smith 2638e34fafa9SBarry Smith #undef __FUNCT__ 2639985db425SBarry Smith #define __FUNCT__ "MatGetRowMaxAbs_SeqAIJ" 2640985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2641e34fafa9SBarry Smith { 2642e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2643e34fafa9SBarry Smith PetscErrorCode ierr; 2644d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2645e34fafa9SBarry Smith PetscReal atmp; 2646985db425SBarry Smith PetscScalar *x; 2647e34fafa9SBarry Smith MatScalar *aa; 2648e34fafa9SBarry Smith 2649e34fafa9SBarry Smith PetscFunctionBegin; 2650e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2651e34fafa9SBarry Smith aa = a->a; 2652e34fafa9SBarry Smith ai = a->i; 2653e34fafa9SBarry Smith aj = a->j; 2654e34fafa9SBarry Smith 2655985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2656e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2657e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2658e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2659e34fafa9SBarry Smith for (i=0; i<m; i++) { 2660e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 26619189402eSHong Zhang x[i] = 0.0; 2662e34fafa9SBarry Smith for (j=0; j<ncols; j++){ 2663985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2664985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2665985db425SBarry Smith aa++; aj++; 2666985db425SBarry Smith } 2667985db425SBarry Smith } 2668985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2669985db425SBarry Smith PetscFunctionReturn(0); 2670985db425SBarry Smith } 2671985db425SBarry Smith 2672985db425SBarry Smith #undef __FUNCT__ 2673985db425SBarry Smith #define __FUNCT__ "MatGetRowMax_SeqAIJ" 2674985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2675985db425SBarry Smith { 2676985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2677985db425SBarry Smith PetscErrorCode ierr; 2678d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2679985db425SBarry Smith PetscScalar *x; 2680985db425SBarry Smith MatScalar *aa; 2681985db425SBarry Smith 2682985db425SBarry Smith PetscFunctionBegin; 2683e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2684985db425SBarry Smith aa = a->a; 2685985db425SBarry Smith ai = a->i; 2686985db425SBarry Smith aj = a->j; 2687985db425SBarry Smith 2688985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2689985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2690985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2691e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2692985db425SBarry Smith for (i=0; i<m; i++) { 2693985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2694d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2695985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2696985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2697985db425SBarry Smith x[i] = 0.0; 2698985db425SBarry Smith if (idx) { 2699985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2700985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2701985db425SBarry Smith if (aj[j] > j) { 2702985db425SBarry Smith idx[i] = j; 2703985db425SBarry Smith break; 2704985db425SBarry Smith } 2705985db425SBarry Smith } 2706985db425SBarry Smith } 2707985db425SBarry Smith } 2708985db425SBarry Smith for (j=0; j<ncols; j++){ 2709985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2710985db425SBarry Smith aa++; aj++; 2711985db425SBarry Smith } 2712985db425SBarry Smith } 2713985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2714985db425SBarry Smith PetscFunctionReturn(0); 2715985db425SBarry Smith } 2716985db425SBarry Smith 2717985db425SBarry Smith #undef __FUNCT__ 2718c87e5d42SMatthew Knepley #define __FUNCT__ "MatGetRowMinAbs_SeqAIJ" 2719c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2720c87e5d42SMatthew Knepley { 2721c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2722c87e5d42SMatthew Knepley PetscErrorCode ierr; 2723c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2724c87e5d42SMatthew Knepley PetscReal atmp; 2725c87e5d42SMatthew Knepley PetscScalar *x; 2726c87e5d42SMatthew Knepley MatScalar *aa; 2727c87e5d42SMatthew Knepley 2728c87e5d42SMatthew Knepley PetscFunctionBegin; 2729e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2730c87e5d42SMatthew Knepley aa = a->a; 2731c87e5d42SMatthew Knepley ai = a->i; 2732c87e5d42SMatthew Knepley aj = a->j; 2733c87e5d42SMatthew Knepley 2734c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2735c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2736c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 27373bb78c5cSMatthew G Knepley if (n != A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector, %d vs. %d rows", A->rmap->n, n); 2738c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2739c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2740289a08f5SMatthew Knepley if (ncols) { 2741289a08f5SMatthew Knepley /* Get first nonzero */ 2742289a08f5SMatthew Knepley for(j = 0; j < ncols; j++) { 2743289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 2744289a08f5SMatthew Knepley if (atmp > 1.0e-12) {x[i] = atmp; if (idx) idx[i] = aj[j]; break;} 2745289a08f5SMatthew Knepley } 274612431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2747289a08f5SMatthew Knepley } else { 2748289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2749289a08f5SMatthew Knepley } 2750c87e5d42SMatthew Knepley for(j = 0; j < ncols; j++) { 2751c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2752289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2753c87e5d42SMatthew Knepley aa++; aj++; 2754c87e5d42SMatthew Knepley } 2755c87e5d42SMatthew Knepley } 2756c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2757c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2758c87e5d42SMatthew Knepley } 2759c87e5d42SMatthew Knepley 2760c87e5d42SMatthew Knepley #undef __FUNCT__ 2761985db425SBarry Smith #define __FUNCT__ "MatGetRowMin_SeqAIJ" 2762985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2763985db425SBarry Smith { 2764985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2765985db425SBarry Smith PetscErrorCode ierr; 2766d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2767985db425SBarry Smith PetscScalar *x; 2768985db425SBarry Smith MatScalar *aa; 2769985db425SBarry Smith 2770985db425SBarry Smith PetscFunctionBegin; 2771e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2772985db425SBarry Smith aa = a->a; 2773985db425SBarry Smith ai = a->i; 2774985db425SBarry Smith aj = a->j; 2775985db425SBarry Smith 2776985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2777985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2778985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2779e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2780985db425SBarry Smith for (i=0; i<m; i++) { 2781985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2782d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2783985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2784985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2785985db425SBarry Smith x[i] = 0.0; 2786985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2787985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2788985db425SBarry Smith for (j=0;j<ncols;j++) { 2789985db425SBarry Smith if (aj[j] > j) { 2790985db425SBarry Smith idx[i] = j; 2791985db425SBarry Smith break; 2792985db425SBarry Smith } 2793985db425SBarry Smith } 2794985db425SBarry Smith } 2795985db425SBarry Smith } 2796985db425SBarry Smith for (j=0; j<ncols; j++){ 2797985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2798985db425SBarry Smith aa++; aj++; 2799e34fafa9SBarry Smith } 2800e34fafa9SBarry Smith } 2801e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2802e34fafa9SBarry Smith PetscFunctionReturn(0); 2803e34fafa9SBarry Smith } 2804bbead8a2SBarry Smith 2805bbead8a2SBarry Smith #include <petscblaslapack.h> 2806bbead8a2SBarry Smith #include <../src/mat/blockinvert.h> 2807bbead8a2SBarry Smith 2808bbead8a2SBarry Smith #undef __FUNCT__ 2809bbead8a2SBarry Smith #define __FUNCT__ "MatInvertBlockDiagonal_SeqAIJ" 2810713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2811bbead8a2SBarry Smith { 2812bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2813bbead8a2SBarry Smith PetscErrorCode ierr; 281434fc4b71SJed Brown PetscInt i,bs = A->rmap->bs,mbs = A->rmap->n/A->rmap->bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2815bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2816bbead8a2SBarry Smith PetscReal shift = 0.0; 2817bbead8a2SBarry Smith 2818bbead8a2SBarry Smith PetscFunctionBegin; 28194a0d0026SBarry Smith if (a->ibdiagvalid) { 28204a0d0026SBarry Smith if (values) *values = a->ibdiag; 28214a0d0026SBarry Smith PetscFunctionReturn(0); 28224a0d0026SBarry Smith } 2823bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2824bbead8a2SBarry Smith if (!a->ibdiag) { 2825bbead8a2SBarry Smith ierr = PetscMalloc(bs2*mbs*sizeof(PetscScalar),&a->ibdiag);CHKERRQ(ierr); 2826bbead8a2SBarry Smith ierr = PetscLogObjectMemory(A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2827bbead8a2SBarry Smith } 2828bbead8a2SBarry Smith diag = a->ibdiag; 2829bbead8a2SBarry Smith if (values) *values = a->ibdiag; 2830bbead8a2SBarry Smith /* factor and invert each block */ 2831bbead8a2SBarry Smith switch (bs){ 2832bbead8a2SBarry Smith case 1: 2833bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2834bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 2835bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 2836bbead8a2SBarry Smith } 2837bbead8a2SBarry Smith break; 2838bbead8a2SBarry Smith case 2: 2839bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2840bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 2841bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 284296b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_2(diag,shift);CHKERRQ(ierr); 284396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 2844bbead8a2SBarry Smith diag += 4; 2845bbead8a2SBarry Smith } 2846bbead8a2SBarry Smith break; 2847bbead8a2SBarry Smith case 3: 2848bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2849bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 2850bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 285196b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_3(diag,shift);CHKERRQ(ierr); 285296b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 2853bbead8a2SBarry Smith diag += 9; 2854bbead8a2SBarry Smith } 2855bbead8a2SBarry Smith break; 2856bbead8a2SBarry Smith case 4: 2857bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2858bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 2859bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 286096b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_4(diag,shift);CHKERRQ(ierr); 286196b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 2862bbead8a2SBarry Smith diag += 16; 2863bbead8a2SBarry Smith } 2864bbead8a2SBarry Smith break; 2865bbead8a2SBarry Smith case 5: 2866bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2867bbead8a2SBarry Smith ij[0] = 5*i; ij[1] = 5*i + 1; ij[2] = 5*i + 2; ij[3] = 5*i + 3; ij[4] = 5*i + 4; 2868bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 286996b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift);CHKERRQ(ierr); 287096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 2871bbead8a2SBarry Smith diag += 25; 2872bbead8a2SBarry Smith } 2873bbead8a2SBarry Smith break; 2874bbead8a2SBarry Smith case 6: 2875bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2876bbead8a2SBarry Smith ij[0] = 6*i; ij[1] = 6*i + 1; ij[2] = 6*i + 2; ij[3] = 6*i + 3; ij[4] = 6*i + 4; ij[5] = 6*i + 5; 2877bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 287896b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_6(diag,shift);CHKERRQ(ierr); 287996b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 2880bbead8a2SBarry Smith diag += 36; 2881bbead8a2SBarry Smith } 2882bbead8a2SBarry Smith break; 2883bbead8a2SBarry Smith case 7: 2884bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2885bbead8a2SBarry Smith ij[0] = 7*i; ij[1] = 7*i + 1; ij[2] = 7*i + 2; ij[3] = 7*i + 3; ij[4] = 7*i + 4; ij[5] = 7*i + 5; ij[5] = 7*i + 6; 2886bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 288796b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A_7(diag,shift);CHKERRQ(ierr); 288896b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 2889bbead8a2SBarry Smith diag += 49; 2890bbead8a2SBarry Smith } 2891bbead8a2SBarry Smith break; 2892bbead8a2SBarry Smith default: 2893bbead8a2SBarry Smith ierr = PetscMalloc3(bs,MatScalar,&v_work,bs,PetscInt,&v_pivots,bs,PetscInt,&IJ);CHKERRQ(ierr); 2894bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2895bbead8a2SBarry Smith for (j=0; j<bs; j++) { 2896bbead8a2SBarry Smith IJ[j] = bs*i + j; 2897bbead8a2SBarry Smith } 2898bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 289996b95a6bSBarry Smith ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work);CHKERRQ(ierr); 290096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 2901bbead8a2SBarry Smith diag += bs2; 2902bbead8a2SBarry Smith } 2903bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 2904bbead8a2SBarry Smith } 2905bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 2906bbead8a2SBarry Smith PetscFunctionReturn(0); 2907bbead8a2SBarry Smith } 2908bbead8a2SBarry Smith 29097087cfbeSBarry Smith extern PetscErrorCode MatFDColoringApply_AIJ(Mat,MatFDColoring,Vec,MatStructure*,void*); 2910682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 29110a6ffc59SBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqAIJ, 2912cb5b572fSBarry Smith MatGetRow_SeqAIJ, 2913cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 2914cb5b572fSBarry Smith MatMult_SeqAIJ, 291597304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 29167c922b88SBarry Smith MatMultTranspose_SeqAIJ, 29177c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 2918db4efbfdSBarry Smith 0, 2919db4efbfdSBarry Smith 0, 2920db4efbfdSBarry Smith 0, 2921db4efbfdSBarry Smith /*10*/ 0, 2922cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 2923cb5b572fSBarry Smith 0, 292441f059aeSBarry Smith MatSOR_SeqAIJ, 292517ab2063SBarry Smith MatTranspose_SeqAIJ, 292697304618SKris Buschelman /*15*/ MatGetInfo_SeqAIJ, 2927cb5b572fSBarry Smith MatEqual_SeqAIJ, 2928cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 2929cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 2930cb5b572fSBarry Smith MatNorm_SeqAIJ, 293197304618SKris Buschelman /*20*/ 0, 2932cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 2933cb5b572fSBarry Smith MatSetOption_SeqAIJ, 2934cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 2935d519adbfSMatthew Knepley /*24*/ MatZeroRows_SeqAIJ, 2936db4efbfdSBarry Smith 0, 2937db4efbfdSBarry Smith 0, 2938db4efbfdSBarry Smith 0, 2939db4efbfdSBarry Smith 0, 29404994cf47SJed Brown /*29*/ MatSetUp_SeqAIJ, 2941db4efbfdSBarry Smith 0, 2942db4efbfdSBarry Smith 0, 29436c0721eeSBarry Smith MatGetArray_SeqAIJ, 29446c0721eeSBarry Smith MatRestoreArray_SeqAIJ, 2945d519adbfSMatthew Knepley /*34*/ MatDuplicate_SeqAIJ, 2946cb5b572fSBarry Smith 0, 2947cb5b572fSBarry Smith 0, 2948cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 2949cb5b572fSBarry Smith 0, 2950d519adbfSMatthew Knepley /*39*/ MatAXPY_SeqAIJ, 2951cb5b572fSBarry Smith MatGetSubMatrices_SeqAIJ, 2952cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 2953cb5b572fSBarry Smith MatGetValues_SeqAIJ, 2954cb5b572fSBarry Smith MatCopy_SeqAIJ, 2955d519adbfSMatthew Knepley /*44*/ MatGetRowMax_SeqAIJ, 2956cb5b572fSBarry Smith MatScale_SeqAIJ, 2957cb5b572fSBarry Smith 0, 295879299369SBarry Smith MatDiagonalSet_SeqAIJ, 29596e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 2960f73d5cc4SBarry Smith /*49*/ 0, 29613b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 29623b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 29633b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 2964a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 2965d519adbfSMatthew Knepley /*54*/ MatFDColoringCreate_SeqAIJ, 2966b9617806SBarry Smith 0, 29670513a670SBarry Smith 0, 2968cda55fadSBarry Smith MatPermute_SeqAIJ, 2969cda55fadSBarry Smith 0, 2970d519adbfSMatthew Knepley /*59*/ 0, 2971b9b97703SBarry Smith MatDestroy_SeqAIJ, 2972b9b97703SBarry Smith MatView_SeqAIJ, 2973357abbc8SBarry Smith 0, 2974ee4f033dSBarry Smith 0, 2975d519adbfSMatthew Knepley /*64*/ 0, 2976ee4f033dSBarry Smith 0, 2977ee4f033dSBarry Smith 0, 2978ee4f033dSBarry Smith 0, 2979ee4f033dSBarry Smith 0, 2980d519adbfSMatthew Knepley /*69*/ MatGetRowMaxAbs_SeqAIJ, 2981c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 2982ee4f033dSBarry Smith 0, 2983ee4f033dSBarry Smith MatSetColoring_SeqAIJ, 2984dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 2985ee4f033dSBarry Smith MatSetValuesAdic_SeqAIJ, 2986dcf5cc72SBarry Smith #else 2987dcf5cc72SBarry Smith 0, 2988dcf5cc72SBarry Smith #endif 2989d519adbfSMatthew Knepley /*74*/ MatSetValuesAdifor_SeqAIJ, 29903acb8795SBarry Smith MatFDColoringApply_AIJ, 299197304618SKris Buschelman 0, 299297304618SKris Buschelman 0, 299397304618SKris Buschelman 0, 29946ce1633cSBarry Smith /*79*/ MatFindZeroDiagonals_SeqAIJ, 299597304618SKris Buschelman 0, 299697304618SKris Buschelman 0, 299797304618SKris Buschelman 0, 2998bc011b1eSHong Zhang MatLoad_SeqAIJ, 2999d519adbfSMatthew Knepley /*84*/ MatIsSymmetric_SeqAIJ, 30001cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 30016284ec50SHong Zhang 0, 30026284ec50SHong Zhang 0, 3003bc011b1eSHong Zhang 0, 3004d519adbfSMatthew Knepley /*89*/ MatMatMult_SeqAIJ_SeqAIJ, 300526be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 300626be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 3007d439da42SKris Buschelman MatPtAP_Basic, 30087ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ, 3009d519adbfSMatthew Knepley /*94*/ MatPtAPNumeric_SeqAIJ, 30106fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 30116fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 30126fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 30137ba1a0bfSKris Buschelman MatPtAPSymbolic_SeqAIJ_SeqAIJ, 3014d519adbfSMatthew Knepley /*99*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 3015609c6c4dSKris Buschelman 0, 3016609c6c4dSKris Buschelman 0, 301787d4246cSBarry Smith MatConjugate_SeqAIJ, 301887d4246cSBarry Smith 0, 3019d519adbfSMatthew Knepley /*104*/MatSetValuesRow_SeqAIJ, 302099cafbc1SBarry Smith MatRealPart_SeqAIJ, 3021f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3022f5edf698SHong Zhang 0, 30232bebee5dSHong Zhang 0, 3024cbd44569SHong Zhang /*109*/MatMatSolve_SeqAIJ, 3025985db425SBarry Smith 0, 30262af78befSBarry Smith MatGetRowMin_SeqAIJ, 30272af78befSBarry Smith 0, 3028599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3029d519adbfSMatthew Knepley /*114*/0, 3030599ef60dSHong Zhang 0, 30313c2a7987SHong Zhang 0, 3032fe97e370SBarry Smith 0, 3033fbdbba38SShri Abhyankar 0, 3034fbdbba38SShri Abhyankar /*119*/0, 3035fbdbba38SShri Abhyankar 0, 3036fbdbba38SShri Abhyankar 0, 303782d44351SHong Zhang 0, 3038b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 30390716a85fSBarry Smith /*124*/MatFindNonzeroRows_SeqAIJ, 3040bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 304137868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 304237868618SMatthew G Knepley 0, 304337868618SMatthew G Knepley 0, 30445df89d91SHong Zhang /*129*/0, 304575648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 304675648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 304775648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3048b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3049b9af6bddSHong Zhang /*134*/MatTransColoringApplySpToDen_SeqAIJ, 30502b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 30512b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 30522b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 30532b8ad9a3SHong Zhang MatRARtNumeric_SeqAIJ_SeqAIJ 30549e29f15eSvictorle }; 305517ab2063SBarry Smith 3056fb2e594dSBarry Smith EXTERN_C_BEGIN 30574a2ae208SSatish Balay #undef __FUNCT__ 30584a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices_SeqAIJ" 30597087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3060bef8e0ddSBarry Smith { 3061bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 306297f1f81fSBarry Smith PetscInt i,nz,n; 3063bef8e0ddSBarry Smith 3064bef8e0ddSBarry Smith PetscFunctionBegin; 3065bef8e0ddSBarry Smith 3066bef8e0ddSBarry Smith nz = aij->maxnz; 3067d0f46423SBarry Smith n = mat->rmap->n; 3068bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3069bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3070bef8e0ddSBarry Smith } 3071bef8e0ddSBarry Smith aij->nz = nz; 3072bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3073bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3074bef8e0ddSBarry Smith } 3075bef8e0ddSBarry Smith 3076bef8e0ddSBarry Smith PetscFunctionReturn(0); 3077bef8e0ddSBarry Smith } 3078fb2e594dSBarry Smith EXTERN_C_END 3079bef8e0ddSBarry Smith 30804a2ae208SSatish Balay #undef __FUNCT__ 30814a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetColumnIndices" 3082bef8e0ddSBarry Smith /*@ 3083bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3084bef8e0ddSBarry Smith in the matrix. 3085bef8e0ddSBarry Smith 3086bef8e0ddSBarry Smith Input Parameters: 3087bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3088bef8e0ddSBarry Smith - indices - the column indices 3089bef8e0ddSBarry Smith 309015091d37SBarry Smith Level: advanced 309115091d37SBarry Smith 3092bef8e0ddSBarry Smith Notes: 3093bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3094bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3095bef8e0ddSBarry Smith of the MatSetValues() operation. 3096bef8e0ddSBarry Smith 3097bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3098d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3099bef8e0ddSBarry Smith 3100bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3101bef8e0ddSBarry Smith 3102b9617806SBarry Smith The indices should start with zero, not one. 3103b9617806SBarry Smith 3104bef8e0ddSBarry Smith @*/ 31057087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3106bef8e0ddSBarry Smith { 31074ac538c5SBarry Smith PetscErrorCode ierr; 3108bef8e0ddSBarry Smith 3109bef8e0ddSBarry Smith PetscFunctionBegin; 31100700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 31114482741eSBarry Smith PetscValidPointer(indices,2); 31124ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt *),(mat,indices));CHKERRQ(ierr); 3113bef8e0ddSBarry Smith PetscFunctionReturn(0); 3114bef8e0ddSBarry Smith } 3115bef8e0ddSBarry Smith 3116be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3117be6bf707SBarry Smith 3118fb2e594dSBarry Smith EXTERN_C_BEGIN 31194a2ae208SSatish Balay #undef __FUNCT__ 31204a2ae208SSatish Balay #define __FUNCT__ "MatStoreValues_SeqAIJ" 31217087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3122be6bf707SBarry Smith { 3123be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 31246849ba73SBarry Smith PetscErrorCode ierr; 3125d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3126be6bf707SBarry Smith 3127be6bf707SBarry Smith PetscFunctionBegin; 3128be6bf707SBarry Smith if (aij->nonew != 1) { 3129e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3130be6bf707SBarry Smith } 3131be6bf707SBarry Smith 3132be6bf707SBarry Smith /* allocate space for values if not already there */ 3133be6bf707SBarry Smith if (!aij->saved_values) { 313487828ca2SBarry Smith ierr = PetscMalloc((nz+1)*sizeof(PetscScalar),&aij->saved_values);CHKERRQ(ierr); 31359518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3136be6bf707SBarry Smith } 3137be6bf707SBarry Smith 3138be6bf707SBarry Smith /* copy values over */ 313987828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3140be6bf707SBarry Smith PetscFunctionReturn(0); 3141be6bf707SBarry Smith } 3142fb2e594dSBarry Smith EXTERN_C_END 3143be6bf707SBarry Smith 31444a2ae208SSatish Balay #undef __FUNCT__ 3145b9617806SBarry Smith #define __FUNCT__ "MatStoreValues" 3146be6bf707SBarry Smith /*@ 3147be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3148be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3149be6bf707SBarry Smith nonlinear portion. 3150be6bf707SBarry Smith 3151be6bf707SBarry Smith Collect on Mat 3152be6bf707SBarry Smith 3153be6bf707SBarry Smith Input Parameters: 31540e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3155be6bf707SBarry Smith 315615091d37SBarry Smith Level: advanced 315715091d37SBarry Smith 3158be6bf707SBarry Smith Common Usage, with SNESSolve(): 3159be6bf707SBarry Smith $ Create Jacobian matrix 3160be6bf707SBarry Smith $ Set linear terms into matrix 3161be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3162be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3163be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3164512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3165be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3166be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3167be6bf707SBarry Smith $ In your Jacobian routine 3168be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3169be6bf707SBarry Smith $ Set nonlinear terms in matrix 3170be6bf707SBarry Smith 3171be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3172be6bf707SBarry Smith $ // build linear portion of Jacobian 3173512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3174be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3175be6bf707SBarry Smith $ loop over nonlinear iterations 3176be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3177be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3178be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3179be6bf707SBarry Smith $ Solve linear system with Jacobian 3180be6bf707SBarry Smith $ endloop 3181be6bf707SBarry Smith 3182be6bf707SBarry Smith Notes: 3183be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3184512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3185be6bf707SBarry Smith calling this routine. 3186be6bf707SBarry Smith 31870c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 31880c468ba9SBarry Smith and does not allocated additional space. 31890c468ba9SBarry Smith 3190be6bf707SBarry Smith .seealso: MatRetrieveValues() 3191be6bf707SBarry Smith 3192be6bf707SBarry Smith @*/ 31937087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3194be6bf707SBarry Smith { 31954ac538c5SBarry Smith PetscErrorCode ierr; 3196be6bf707SBarry Smith 3197be6bf707SBarry Smith PetscFunctionBegin; 31980700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3199e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3200e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32014ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3202be6bf707SBarry Smith PetscFunctionReturn(0); 3203be6bf707SBarry Smith } 3204be6bf707SBarry Smith 3205fb2e594dSBarry Smith EXTERN_C_BEGIN 32064a2ae208SSatish Balay #undef __FUNCT__ 32074a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues_SeqAIJ" 32087087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3209be6bf707SBarry Smith { 3210be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ *)mat->data; 32116849ba73SBarry Smith PetscErrorCode ierr; 3212d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3213be6bf707SBarry Smith 3214be6bf707SBarry Smith PetscFunctionBegin; 3215be6bf707SBarry Smith if (aij->nonew != 1) { 3216e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3217be6bf707SBarry Smith } 3218be6bf707SBarry Smith if (!aij->saved_values) { 3219e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3220be6bf707SBarry Smith } 3221be6bf707SBarry Smith /* copy values over */ 322287828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3223be6bf707SBarry Smith PetscFunctionReturn(0); 3224be6bf707SBarry Smith } 3225fb2e594dSBarry Smith EXTERN_C_END 3226be6bf707SBarry Smith 32274a2ae208SSatish Balay #undef __FUNCT__ 32284a2ae208SSatish Balay #define __FUNCT__ "MatRetrieveValues" 3229be6bf707SBarry Smith /*@ 3230be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3231be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3232be6bf707SBarry Smith nonlinear portion. 3233be6bf707SBarry Smith 3234be6bf707SBarry Smith Collect on Mat 3235be6bf707SBarry Smith 3236be6bf707SBarry Smith Input Parameters: 3237be6bf707SBarry Smith . mat - the matrix (currently on AIJ matrices support this option) 3238be6bf707SBarry Smith 323915091d37SBarry Smith Level: advanced 324015091d37SBarry Smith 3241be6bf707SBarry Smith .seealso: MatStoreValues() 3242be6bf707SBarry Smith 3243be6bf707SBarry Smith @*/ 32447087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3245be6bf707SBarry Smith { 32464ac538c5SBarry Smith PetscErrorCode ierr; 3247be6bf707SBarry Smith 3248be6bf707SBarry Smith PetscFunctionBegin; 32490700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3250e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3251e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 32524ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3253be6bf707SBarry Smith PetscFunctionReturn(0); 3254be6bf707SBarry Smith } 3255be6bf707SBarry Smith 3256f83d6046SBarry Smith 3257be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 32584a2ae208SSatish Balay #undef __FUNCT__ 32594a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJ" 326017ab2063SBarry Smith /*@C 3261682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 32620d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 32636e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 326451c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 32652bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 326617ab2063SBarry Smith 3267db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3268db81eaa0SLois Curfman McInnes 326917ab2063SBarry Smith Input Parameters: 3270db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 327117ab2063SBarry Smith . m - number of rows 327217ab2063SBarry Smith . n - number of columns 327317ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 327451c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 32752bd5e0b2SLois Curfman McInnes (possibly different for each row) or PETSC_NULL 327617ab2063SBarry Smith 327717ab2063SBarry Smith Output Parameter: 3278416022c9SBarry Smith . A - the matrix 327917ab2063SBarry Smith 3280175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3281ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3282175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3283175b88e8SBarry Smith 3284b259b22eSLois Curfman McInnes Notes: 328549a6f317SBarry Smith If nnz is given then nz is ignored 328649a6f317SBarry Smith 328717ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 328817ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 32890002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 329044cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 329117ab2063SBarry Smith 329217ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3293a40aa06bSLois Curfman McInnes Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 32943d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 32956da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 329617ab2063SBarry Smith 3297682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 32984fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3299682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 33006c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 33016c7ebb05SLois Curfman McInnes 33026c7ebb05SLois Curfman McInnes Options Database Keys: 3303698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 33049db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 330517ab2063SBarry Smith 3306027ccd11SLois Curfman McInnes Level: intermediate 3307027ccd11SLois Curfman McInnes 330869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 330936db0b34SBarry Smith 331017ab2063SBarry Smith @*/ 33117087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 331217ab2063SBarry Smith { 3313dfbe8321SBarry Smith PetscErrorCode ierr; 33146945ee14SBarry Smith 33153a40ed3dSBarry Smith PetscFunctionBegin; 3316f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3317117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3318c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3319d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3320273d9f13SBarry Smith PetscFunctionReturn(0); 3321273d9f13SBarry Smith } 3322273d9f13SBarry Smith 33234a2ae208SSatish Balay #undef __FUNCT__ 33244a2ae208SSatish Balay #define __FUNCT__ "MatSeqAIJSetPreallocation" 3325273d9f13SBarry Smith /*@C 3326273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3327273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3328273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3329273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3330273d9f13SBarry Smith 3331273d9f13SBarry Smith Collective on MPI_Comm 3332273d9f13SBarry Smith 3333273d9f13SBarry Smith Input Parameters: 3334117016b1SBarry Smith + B - The matrix-free 3335273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3336273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 3337273d9f13SBarry Smith (possibly different for each row) or PETSC_NULL 3338273d9f13SBarry Smith 3339273d9f13SBarry Smith Notes: 334049a6f317SBarry Smith If nnz is given then nz is ignored 334149a6f317SBarry Smith 3342273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3343273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3344273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3345273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3346273d9f13SBarry Smith 3347273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 3348273d9f13SBarry Smith Set nz=PETSC_DEFAULT and nnz=PETSC_NULL for PETSc to control dynamic memory 3349273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3350273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3351273d9f13SBarry Smith 3352aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3353aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3354aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3355aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3356aa95bbe8SBarry Smith 3357a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3358a96a251dSBarry Smith entries or columns indices 3359a96a251dSBarry Smith 3360273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3361273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3362273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3363273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3364273d9f13SBarry Smith 3365273d9f13SBarry Smith Options Database Keys: 3366698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3367698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3368273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3369273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3370273d9f13SBarry Smith the user still MUST index entries starting at 0! 3371273d9f13SBarry Smith 3372273d9f13SBarry Smith Level: intermediate 3373273d9f13SBarry Smith 337469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3375273d9f13SBarry Smith 3376273d9f13SBarry Smith @*/ 33777087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3378273d9f13SBarry Smith { 33794ac538c5SBarry Smith PetscErrorCode ierr; 3380a23d5eceSKris Buschelman 3381a23d5eceSKris Buschelman PetscFunctionBegin; 33826ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 33836ba663aaSJed Brown PetscValidType(B,1); 33844ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3385a23d5eceSKris Buschelman PetscFunctionReturn(0); 3386a23d5eceSKris Buschelman } 3387a23d5eceSKris Buschelman 3388a23d5eceSKris Buschelman EXTERN_C_BEGIN 3389a23d5eceSKris Buschelman #undef __FUNCT__ 3390a23d5eceSKris Buschelman #define __FUNCT__ "MatSeqAIJSetPreallocation_SeqAIJ" 33917087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3392a23d5eceSKris Buschelman { 3393273d9f13SBarry Smith Mat_SeqAIJ *b; 33942576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 33956849ba73SBarry Smith PetscErrorCode ierr; 339697f1f81fSBarry Smith PetscInt i; 3397273d9f13SBarry Smith 3398273d9f13SBarry Smith PetscFunctionBegin; 33992576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3400a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3401c461c341SBarry Smith skipallocation = PETSC_TRUE; 3402c461c341SBarry Smith nz = 0; 3403c461c341SBarry Smith } 3404c461c341SBarry Smith 340526283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 340626283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3407899cda47SBarry Smith 3408435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 3409e32f2f54SBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %d",nz); 3410b73539f3SBarry Smith if (nnz) { 3411d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 3412e32f2f54SBarry 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]); 3413e32f2f54SBarry 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); 3414b73539f3SBarry Smith } 3415b73539f3SBarry Smith } 3416b73539f3SBarry Smith 3417273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3418273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3419273d9f13SBarry Smith 3420ab93d7beSBarry Smith if (!skipallocation) { 34212ee49352SLisandro Dalcin if (!b->imax) { 3422d0f46423SBarry Smith ierr = PetscMalloc2(B->rmap->n,PetscInt,&b->imax,B->rmap->n,PetscInt,&b->ilen);CHKERRQ(ierr); 3423d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 34242ee49352SLisandro Dalcin } 3425273d9f13SBarry Smith if (!nnz) { 3426435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3427c62bd62aSJed Brown else if (nz < 0) nz = 1; 3428d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3429d0f46423SBarry Smith nz = nz*B->rmap->n; 3430273d9f13SBarry Smith } else { 3431273d9f13SBarry Smith nz = 0; 3432d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3433273d9f13SBarry Smith } 3434ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 3435d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { b->ilen[i] = 0; } 3436ab93d7beSBarry Smith 3437273d9f13SBarry Smith /* allocate the matrix space */ 34382ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3439d0f46423SBarry Smith ierr = PetscMalloc3(nz,PetscScalar,&b->a,nz,PetscInt,&b->j,B->rmap->n+1,PetscInt,&b->i);CHKERRQ(ierr); 3440d0f46423SBarry Smith ierr = PetscLogObjectMemory(B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3441bfeeae90SHong Zhang b->i[0] = 0; 3442d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 34435da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 34445da197adSKris Buschelman } 3445273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3446e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3447e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3448c461c341SBarry Smith } else { 3449e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3450e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3451c461c341SBarry Smith } 3452273d9f13SBarry Smith 3453273d9f13SBarry Smith b->nz = 0; 3454273d9f13SBarry Smith b->maxnz = nz; 3455273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 34562576faa2SJed Brown if (realalloc) {ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr);} 3457273d9f13SBarry Smith PetscFunctionReturn(0); 3458273d9f13SBarry Smith } 3459a23d5eceSKris Buschelman EXTERN_C_END 3460273d9f13SBarry Smith 3461a1661176SMatthew Knepley #undef __FUNCT__ 3462a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR" 346358d36128SBarry Smith /*@ 3464a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3465a1661176SMatthew Knepley 3466a1661176SMatthew Knepley Input Parameters: 3467a1661176SMatthew Knepley + B - the matrix 3468a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3469a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3470a1661176SMatthew Knepley - v - optional values in the matrix 3471a1661176SMatthew Knepley 3472a1661176SMatthew Knepley Level: developer 3473a1661176SMatthew Knepley 347458d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 347558d36128SBarry Smith 3476a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3477a1661176SMatthew Knepley 3478a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3479a1661176SMatthew Knepley @*/ 3480a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3481a1661176SMatthew Knepley { 3482a1661176SMatthew Knepley PetscErrorCode ierr; 3483a1661176SMatthew Knepley 3484a1661176SMatthew Knepley PetscFunctionBegin; 34850700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 34866ba663aaSJed Brown PetscValidType(B,1); 34874ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3488a1661176SMatthew Knepley PetscFunctionReturn(0); 3489a1661176SMatthew Knepley } 3490a1661176SMatthew Knepley 3491a1661176SMatthew Knepley EXTERN_C_BEGIN 3492a1661176SMatthew Knepley #undef __FUNCT__ 3493a1661176SMatthew Knepley #define __FUNCT__ "MatSeqAIJSetPreallocationCSR_SeqAIJ" 34947087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3495a1661176SMatthew Knepley { 3496a1661176SMatthew Knepley PetscInt i; 3497a1661176SMatthew Knepley PetscInt m,n; 3498a1661176SMatthew Knepley PetscInt nz; 3499a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3500a1661176SMatthew Knepley PetscScalar *values; 3501a1661176SMatthew Knepley PetscErrorCode ierr; 3502a1661176SMatthew Knepley 3503a1661176SMatthew Knepley PetscFunctionBegin; 350465e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3505779a8d59SSatish Balay 3506779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3507779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3508779a8d59SSatish Balay 3509779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3510a1661176SMatthew Knepley ierr = PetscMalloc((m+1) * sizeof(PetscInt), &nnz);CHKERRQ(ierr); 3511a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3512b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3513a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 351465e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3515a1661176SMatthew Knepley nnz[i] = nz; 3516a1661176SMatthew Knepley } 3517a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3518a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3519a1661176SMatthew Knepley 3520a1661176SMatthew Knepley if (v) { 3521a1661176SMatthew Knepley values = (PetscScalar*) v; 3522a1661176SMatthew Knepley } else { 35230e83c824SBarry Smith ierr = PetscMalloc(nz_max*sizeof(PetscScalar), &values);CHKERRQ(ierr); 3524a1661176SMatthew Knepley ierr = PetscMemzero(values, nz_max*sizeof(PetscScalar));CHKERRQ(ierr); 3525a1661176SMatthew Knepley } 3526a1661176SMatthew Knepley 3527a1661176SMatthew Knepley for(i = 0; i < m; i++) { 3528b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3529b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3530a1661176SMatthew Knepley } 3531a1661176SMatthew Knepley 3532a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3533a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3534a1661176SMatthew Knepley 3535a1661176SMatthew Knepley if (!v) { 3536a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3537a1661176SMatthew Knepley } 35387827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3539a1661176SMatthew Knepley PetscFunctionReturn(0); 3540a1661176SMatthew Knepley } 3541a1661176SMatthew Knepley EXTERN_C_END 3542a1661176SMatthew Knepley 3543c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3544b45d2f2cSJed Brown #include <petsc-private/petscaxpy.h> 3545170fe5c8SBarry Smith 3546170fe5c8SBarry Smith #undef __FUNCT__ 3547170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultNumeric_SeqDense_SeqAIJ" 3548170fe5c8SBarry Smith /* 3549170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3550170fe5c8SBarry Smith 3551170fe5c8SBarry Smith n p p 3552170fe5c8SBarry Smith ( ) ( ) ( ) 3553170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3554170fe5c8SBarry Smith ( ) ( ) ( ) 3555170fe5c8SBarry Smith 3556170fe5c8SBarry Smith */ 3557170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3558170fe5c8SBarry Smith { 3559170fe5c8SBarry Smith PetscErrorCode ierr; 3560170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3561170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3562170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 35631de00fd4SBarry Smith PetscInt i,n,m,q,p; 3564170fe5c8SBarry Smith const PetscInt *ii,*idx; 3565170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3566170fe5c8SBarry Smith PetscScalar *c,*c_q; 3567170fe5c8SBarry Smith 3568170fe5c8SBarry Smith PetscFunctionBegin; 3569d0f46423SBarry Smith m = A->rmap->n; 3570d0f46423SBarry Smith n = A->cmap->n; 3571d0f46423SBarry Smith p = B->cmap->n; 3572170fe5c8SBarry Smith a = sub_a->v; 3573170fe5c8SBarry Smith b = sub_b->a; 3574170fe5c8SBarry Smith c = sub_c->v; 3575170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3576170fe5c8SBarry Smith 3577170fe5c8SBarry Smith ii = sub_b->i; 3578170fe5c8SBarry Smith idx = sub_b->j; 3579170fe5c8SBarry Smith for (i=0; i<n; i++) { 3580170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3581170fe5c8SBarry Smith while (q-->0) { 3582170fe5c8SBarry Smith c_q = c + m*(*idx); 3583170fe5c8SBarry Smith a_q = a + m*i; 3584be7314b0SBarry Smith PetscAXPY(c_q,*b,a_q,m); 3585170fe5c8SBarry Smith idx++; 3586170fe5c8SBarry Smith b++; 3587170fe5c8SBarry Smith } 3588170fe5c8SBarry Smith } 3589170fe5c8SBarry Smith PetscFunctionReturn(0); 3590170fe5c8SBarry Smith } 3591170fe5c8SBarry Smith 3592170fe5c8SBarry Smith #undef __FUNCT__ 3593170fe5c8SBarry Smith #define __FUNCT__ "MatMatMultSymbolic_SeqDense_SeqAIJ" 3594170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3595170fe5c8SBarry Smith { 3596170fe5c8SBarry Smith PetscErrorCode ierr; 3597d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3598170fe5c8SBarry Smith Mat Cmat; 3599170fe5c8SBarry Smith 3600170fe5c8SBarry Smith PetscFunctionBegin; 3601e32f2f54SBarry 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); 360239804f7cSBarry Smith ierr = MatCreate(((PetscObject)A)->comm,&Cmat);CHKERRQ(ierr); 3603170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 3604a2f3521dSMark F. Adams ierr = MatSetBlockSizes(Cmat,A->rmap->bs,B->cmap->bs);CHKERRQ(ierr); 3605170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 3606170fe5c8SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr); 3607170fe5c8SBarry Smith Cmat->assembled = PETSC_TRUE; 36088cdbd757SHong Zhang Cmat->ops->matmult = MatMatMult_SeqDense_SeqAIJ; 3609170fe5c8SBarry Smith *C = Cmat; 3610170fe5c8SBarry Smith PetscFunctionReturn(0); 3611170fe5c8SBarry Smith } 3612170fe5c8SBarry Smith 3613170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3614170fe5c8SBarry Smith #undef __FUNCT__ 3615170fe5c8SBarry Smith #define __FUNCT__ "MatMatMult_SeqDense_SeqAIJ" 3616170fe5c8SBarry Smith PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3617170fe5c8SBarry Smith { 3618170fe5c8SBarry Smith PetscErrorCode ierr; 3619170fe5c8SBarry Smith 3620170fe5c8SBarry Smith PetscFunctionBegin; 3621170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX){ 3622170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 3623170fe5c8SBarry Smith } 3624170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 3625170fe5c8SBarry Smith PetscFunctionReturn(0); 3626170fe5c8SBarry Smith } 3627170fe5c8SBarry Smith 3628170fe5c8SBarry Smith 36290bad9183SKris Buschelman /*MC 3630fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 36310bad9183SKris Buschelman based on compressed sparse row format. 36320bad9183SKris Buschelman 36330bad9183SKris Buschelman Options Database Keys: 36340bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 36350bad9183SKris Buschelman 36360bad9183SKris Buschelman Level: beginner 36370bad9183SKris Buschelman 3638f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 36390bad9183SKris Buschelman M*/ 36400bad9183SKris Buschelman 3641a6175056SHong Zhang EXTERN_C_BEGIN 3642b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3643b5e56a35SBarry Smith extern PetscErrorCode MatGetFactor_seqaij_pastix(Mat,MatFactorType,Mat*); 3644b5e56a35SBarry Smith #endif 3645ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 3646af1023dbSSatish Balay extern PetscErrorCode MatGetFactor_seqaij_essl(Mat,MatFactorType,Mat *); 3647af1023dbSSatish Balay #endif 36487087cfbeSBarry Smith extern PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 36497087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_petsc(Mat,MatFactorType,Mat*); 36507087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_bas(Mat,MatFactorType,Mat*); 36517087cfbeSBarry Smith extern PetscErrorCode MatGetFactorAvailable_seqaij_petsc(Mat,MatFactorType,PetscBool *); 3652611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 36537087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_aij_mumps(Mat,MatFactorType,Mat*); 3654611f576cSBarry Smith #endif 3655611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 36567087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_superlu(Mat,MatFactorType,Mat*); 3657611f576cSBarry Smith #endif 3658f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3659f3c0ef26SHong Zhang extern PetscErrorCode MatGetFactor_seqaij_superlu_dist(Mat,MatFactorType,Mat*); 3660f3c0ef26SHong Zhang #endif 3661611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 36627087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_spooles(Mat,MatFactorType,Mat*); 3663611f576cSBarry Smith #endif 3664eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 36657087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_umfpack(Mat,MatFactorType,Mat*); 3666eb3b5408SSatish Balay #endif 3667586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 36687087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_cholmod(Mat,MatFactorType,Mat*); 3669586621ddSJed Brown #endif 3670719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 36717087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_lusol(Mat,MatFactorType,Mat*); 3672719d5645SBarry Smith #endif 3673b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 36747087cfbeSBarry Smith extern PetscErrorCode MatGetFactor_seqaij_matlab(Mat,MatFactorType,Mat*); 36757087cfbeSBarry Smith extern PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 36767087cfbeSBarry Smith extern PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3677b3866ffcSBarry Smith #endif 367817667f90SBarry Smith EXTERN_C_END 367917667f90SBarry Smith 3680c0c8ee5eSDmitry Karpeev 368117667f90SBarry Smith EXTERN_C_BEGIN 36824a2ae208SSatish Balay #undef __FUNCT__ 36834a2ae208SSatish Balay #define __FUNCT__ "MatCreate_SeqAIJ" 36847087cfbeSBarry Smith PetscErrorCode MatCreate_SeqAIJ(Mat B) 3685273d9f13SBarry Smith { 3686273d9f13SBarry Smith Mat_SeqAIJ *b; 3687dfbe8321SBarry Smith PetscErrorCode ierr; 368838baddfdSBarry Smith PetscMPIInt size; 3689273d9f13SBarry Smith 3690273d9f13SBarry Smith PetscFunctionBegin; 36917adad957SLisandro Dalcin ierr = MPI_Comm_size(((PetscObject)B)->comm,&size);CHKERRQ(ierr); 3692e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3693273d9f13SBarry Smith 369438f2d2fdSLisandro Dalcin ierr = PetscNewLog(B,Mat_SeqAIJ,&b);CHKERRQ(ierr); 3695b0a32e0cSBarry Smith B->data = (void*)b; 3696549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 3697416022c9SBarry Smith b->row = 0; 3698416022c9SBarry Smith b->col = 0; 369982bf6240SBarry Smith b->icol = 0; 3700b810aeb4SBarry Smith b->reallocs = 0; 370136db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3702f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3703416022c9SBarry Smith b->nonew = 0; 3704416022c9SBarry Smith b->diag = 0; 3705416022c9SBarry Smith b->solve_work = 0; 37062a1b7f2aSHong Zhang B->spptr = 0; 3707be6bf707SBarry Smith b->saved_values = 0; 3708d7f994e1SBarry Smith b->idiag = 0; 370971f1c65dSBarry Smith b->mdiag = 0; 371071f1c65dSBarry Smith b->ssor_work = 0; 371171f1c65dSBarry Smith b->omega = 1.0; 371271f1c65dSBarry Smith b->fshift = 0.0; 371371f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3714bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3715a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 3716a30b2313SHong Zhang b->xtoy = 0; 3717a30b2313SHong Zhang b->XtoY = 0; 371888e51ccdSHong Zhang B->same_nonzero = PETSC_FALSE; 371917ab2063SBarry Smith 372035d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3721b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3722700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_matlab_C","MatGetFactor_seqaij_matlab",MatGetFactor_seqaij_matlab);CHKERRQ(ierr); 3723b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEnginePut_C","MatlabEnginePut_SeqAIJ",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3724b3866ffcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"PetscMatlabEngineGet_C","MatlabEngineGet_SeqAIJ",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3725b3866ffcSBarry Smith #endif 3726b5e56a35SBarry Smith #if defined(PETSC_HAVE_PASTIX) 3727700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_pastix_C","MatGetFactor_seqaij_pastix",MatGetFactor_seqaij_pastix);CHKERRQ(ierr); 3728b5e56a35SBarry Smith #endif 3729ce63c4c1SBarry Smith #if defined(PETSC_HAVE_ESSL) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) 3730700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_essl_C","MatGetFactor_seqaij_essl",MatGetFactor_seqaij_essl);CHKERRQ(ierr); 3731719d5645SBarry Smith #endif 3732611f576cSBarry Smith #if defined(PETSC_HAVE_SUPERLU) 3733700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_C","MatGetFactor_seqaij_superlu",MatGetFactor_seqaij_superlu);CHKERRQ(ierr); 3734611f576cSBarry Smith #endif 3735f3c0ef26SHong Zhang #if defined(PETSC_HAVE_SUPERLU_DIST) 3736700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_superlu_dist_C","MatGetFactor_seqaij_superlu_dist",MatGetFactor_seqaij_superlu_dist);CHKERRQ(ierr); 3737f3c0ef26SHong Zhang #endif 3738611f576cSBarry Smith #if defined(PETSC_HAVE_SPOOLES) 3739700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_spooles_C","MatGetFactor_seqaij_spooles",MatGetFactor_seqaij_spooles);CHKERRQ(ierr); 3740611f576cSBarry Smith #endif 3741611f576cSBarry Smith #if defined(PETSC_HAVE_MUMPS) 3742700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_mumps_C","MatGetFactor_aij_mumps",MatGetFactor_aij_mumps);CHKERRQ(ierr); 3743611f576cSBarry Smith #endif 3744eb3b5408SSatish Balay #if defined(PETSC_HAVE_UMFPACK) 3745700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_umfpack_C","MatGetFactor_seqaij_umfpack",MatGetFactor_seqaij_umfpack);CHKERRQ(ierr); 3746eb3b5408SSatish Balay #endif 3747586621ddSJed Brown #if defined(PETSC_HAVE_CHOLMOD) 3748700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_cholmod_C","MatGetFactor_seqaij_cholmod",MatGetFactor_seqaij_cholmod);CHKERRQ(ierr); 3749586621ddSJed Brown #endif 3750719d5645SBarry Smith #if defined(PETSC_HAVE_LUSOL) 3751700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_lusol_C","MatGetFactor_seqaij_lusol",MatGetFactor_seqaij_lusol);CHKERRQ(ierr); 3752719d5645SBarry Smith #endif 3753700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_petsc_C","MatGetFactor_seqaij_petsc",MatGetFactor_seqaij_petsc);CHKERRQ(ierr); 3754700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactorAvailable_petsc_C","MatGetFactorAvailable_seqaij_petsc",MatGetFactorAvailable_seqaij_petsc);CHKERRQ(ierr); 3755700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatGetFactor_bas_C","MatGetFactor_seqaij_bas",MatGetFactor_seqaij_bas);CHKERRQ(ierr); 3756700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetColumnIndices_C","MatSeqAIJSetColumnIndices_SeqAIJ",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3757700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatStoreValues_C","MatStoreValues_SeqAIJ",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3758700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatRetrieveValues_C","MatRetrieveValues_SeqAIJ",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3759700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqsbaij_C","MatConvert_SeqAIJ_SeqSBAIJ",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3760700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqbaij_C","MatConvert_SeqAIJ_SeqBAIJ",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3761700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijperm_C","MatConvert_SeqAIJ_SeqAIJPERM",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3762700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C","MatConvert_SeqAIJ_SeqAIJCRL",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3763700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsTranspose_C","MatIsTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3764700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatIsHermitianTranspose_C","MatIsHermitianTranspose_SeqAIJ",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3765700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocation_C","MatSeqAIJSetPreallocation_SeqAIJ",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3766700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C","MatSeqAIJSetPreallocationCSR_SeqAIJ",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3767700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatReorderForNonzeroDiagonal_C","MatReorderForNonzeroDiagonal_SeqAIJ",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3768700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMult_seqdense_seqaij_C","MatMatMult_SeqDense_SeqAIJ",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3769700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C","MatMatMultSymbolic_SeqDense_SeqAIJ",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3770700c5bfcSBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C","MatMatMultNumeric_SeqDense_SeqAIJ",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 37714108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 377217667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 37733a40ed3dSBarry Smith PetscFunctionReturn(0); 377417ab2063SBarry Smith } 3775273d9f13SBarry Smith EXTERN_C_END 377617ab2063SBarry Smith 37774a2ae208SSatish Balay #undef __FUNCT__ 3778b24902e0SBarry Smith #define __FUNCT__ "MatDuplicateNoCreate_SeqAIJ" 3779b24902e0SBarry Smith /* 3780b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3781b24902e0SBarry Smith */ 3782ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 378317ab2063SBarry Smith { 3784416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 37856849ba73SBarry Smith PetscErrorCode ierr; 3786d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 378717ab2063SBarry Smith 37883a40ed3dSBarry Smith PetscFunctionBegin; 3789273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3790273d9f13SBarry Smith 3791d5f3da31SBarry Smith C->factortype = A->factortype; 3792416022c9SBarry Smith c->row = 0; 3793416022c9SBarry Smith c->col = 0; 379482bf6240SBarry Smith c->icol = 0; 37956ad4291fSHong Zhang c->reallocs = 0; 379617ab2063SBarry Smith 37976ad4291fSHong Zhang C->assembled = PETSC_TRUE; 379817ab2063SBarry Smith 3799aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3800aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3801eec197d1SBarry Smith 380233b91e9fSSatish Balay ierr = PetscMalloc2(m,PetscInt,&c->imax,m,PetscInt,&c->ilen);CHKERRQ(ierr); 38039518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 380417ab2063SBarry Smith for (i=0; i<m; i++) { 3805416022c9SBarry Smith c->imax[i] = a->imax[i]; 3806416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 380717ab2063SBarry Smith } 380817ab2063SBarry Smith 380917ab2063SBarry Smith /* allocate the matrix space */ 3810f77e22a1SHong Zhang if (mallocmatspace){ 3811a96a251dSBarry Smith ierr = PetscMalloc3(a->i[m],PetscScalar,&c->a,a->i[m],PetscInt,&c->j,m+1,PetscInt,&c->i);CHKERRQ(ierr); 38129518dbb4SMatthew Knepley ierr = PetscLogObjectMemory(C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 3813f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 381497f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 381517ab2063SBarry Smith if (m > 0) { 381697f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3817be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3818bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3819be6bf707SBarry Smith } else { 3820bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 382117ab2063SBarry Smith } 382208480c60SBarry Smith } 3823f77e22a1SHong Zhang } 382417ab2063SBarry Smith 38256ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 3826416022c9SBarry Smith c->roworiented = a->roworiented; 3827416022c9SBarry Smith c->nonew = a->nonew; 3828416022c9SBarry Smith if (a->diag) { 382997f1f81fSBarry Smith ierr = PetscMalloc((m+1)*sizeof(PetscInt),&c->diag);CHKERRQ(ierr); 383052e6d16bSBarry Smith ierr = PetscLogObjectMemory(C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 383117ab2063SBarry Smith for (i=0; i<m; i++) { 3832416022c9SBarry Smith c->diag[i] = a->diag[i]; 383317ab2063SBarry Smith } 38343a40ed3dSBarry Smith } else c->diag = 0; 38356ad4291fSHong Zhang c->solve_work = 0; 38366ad4291fSHong Zhang c->saved_values = 0; 38376ad4291fSHong Zhang c->idiag = 0; 383871f1c65dSBarry Smith c->ssor_work = 0; 3839a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 3840e6b907acSBarry Smith c->free_a = PETSC_TRUE; 3841e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 38426ad4291fSHong Zhang c->xtoy = 0; 38436ad4291fSHong Zhang c->XtoY = 0; 38446ad4291fSHong Zhang 3845893ad86cSHong Zhang c->rmax = a->rmax; 3846416022c9SBarry Smith c->nz = a->nz; 38478ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 3848273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 3849754ec7b1SSatish Balay 38506ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 38516ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 3852cd6b891eSBarry Smith c->compressedrow.check = a->compressedrow.check; 3853cd6b891eSBarry Smith if (a->compressedrow.use){ 38546ad4291fSHong Zhang i = a->compressedrow.nrows; 38550e83c824SBarry Smith ierr = PetscMalloc2(i+1,PetscInt,&c->compressedrow.i,i,PetscInt,&c->compressedrow.rindex);CHKERRQ(ierr); 38566ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 38576ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 385827ea64f8SHong Zhang } else { 385927ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 386027ea64f8SHong Zhang c->compressedrow.i = PETSC_NULL; 386127ea64f8SHong Zhang c->compressedrow.rindex = PETSC_NULL; 38626ad4291fSHong Zhang } 386388e51ccdSHong Zhang C->same_nonzero = A->same_nonzero; 38644108e4d5SBarry Smith ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 38654846f1f5SKris Buschelman 38667adad957SLisandro Dalcin ierr = PetscFListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 38673a40ed3dSBarry Smith PetscFunctionReturn(0); 386817ab2063SBarry Smith } 386917ab2063SBarry Smith 38704a2ae208SSatish Balay #undef __FUNCT__ 3871b24902e0SBarry Smith #define __FUNCT__ "MatDuplicate_SeqAIJ" 3872b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 3873b24902e0SBarry Smith { 3874b24902e0SBarry Smith PetscErrorCode ierr; 3875b24902e0SBarry Smith 3876b24902e0SBarry Smith PetscFunctionBegin; 3877b24902e0SBarry Smith ierr = MatCreate(((PetscObject)A)->comm,B);CHKERRQ(ierr); 38784b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 3879a2f3521dSMark F. Adams ierr = MatSetBlockSizes(*B,A->rmap->bs,A->cmap->bs);CHKERRQ(ierr); 3880a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 3881f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 3882b24902e0SBarry Smith PetscFunctionReturn(0); 3883b24902e0SBarry Smith } 3884b24902e0SBarry Smith 3885b24902e0SBarry Smith #undef __FUNCT__ 38864a2ae208SSatish Balay #define __FUNCT__ "MatLoad_SeqAIJ" 3887112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 3888fbdbba38SShri Abhyankar { 3889fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 3890fbdbba38SShri Abhyankar PetscErrorCode ierr; 3891fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 3892fbdbba38SShri Abhyankar int fd; 3893fbdbba38SShri Abhyankar PetscMPIInt size; 3894fbdbba38SShri Abhyankar MPI_Comm comm; 3895bbead8a2SBarry Smith PetscInt bs = 1; 3896fbdbba38SShri Abhyankar 3897fbdbba38SShri Abhyankar PetscFunctionBegin; 3898fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 3899fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 3900fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 3901bbead8a2SBarry Smith 3902bbead8a2SBarry Smith ierr = PetscOptionsBegin(comm,PETSC_NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 3903bbead8a2SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,PETSC_NULL);CHKERRQ(ierr); 3904bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 3905*1814747fSJed Brown if (bs > 1) {ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr);} 3906bbead8a2SBarry Smith 3907fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 3908fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 3909fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 3910fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 3911fbdbba38SShri Abhyankar 3912bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 3913fbdbba38SShri Abhyankar 3914fbdbba38SShri Abhyankar /* read in row lengths */ 3915fbdbba38SShri Abhyankar ierr = PetscMalloc(M*sizeof(PetscInt),&rowlengths);CHKERRQ(ierr); 3916fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 3917fbdbba38SShri Abhyankar 3918fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 3919fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 3920fbdbba38SShri 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); 3921fbdbba38SShri Abhyankar 3922fbdbba38SShri Abhyankar /* set global size if not set already*/ 3923f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 3924fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 3925aabbc4fbSShri Abhyankar } else { 3926fbdbba38SShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 3927fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 39284c5b953cSHong Zhang if (rows < 0 && cols < 0){ /* user might provide local size instead of global size */ 39294c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 39304c5b953cSHong Zhang } 3931f501eaabSShri 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); 3932aabbc4fbSShri Abhyankar } 3933fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 3934fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 3935fbdbba38SShri Abhyankar 3936fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 3937fbdbba38SShri Abhyankar 3938fbdbba38SShri Abhyankar /* read in nonzero values */ 3939fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 3940fbdbba38SShri Abhyankar 3941fbdbba38SShri Abhyankar /* set matrix "i" values */ 3942fbdbba38SShri Abhyankar a->i[0] = 0; 3943fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 3944fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 3945fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 3946fbdbba38SShri Abhyankar } 3947fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 3948fbdbba38SShri Abhyankar 3949fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3950fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3951fbdbba38SShri Abhyankar PetscFunctionReturn(0); 3952fbdbba38SShri Abhyankar } 3953fbdbba38SShri Abhyankar 3954fbdbba38SShri Abhyankar #undef __FUNCT__ 3955b9617806SBarry Smith #define __FUNCT__ "MatEqual_SeqAIJ" 3956ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 39577264ac53SSatish Balay { 39587264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data,*b = (Mat_SeqAIJ *)B->data; 3959dfbe8321SBarry Smith PetscErrorCode ierr; 3960eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 3961eeffb40dSHong Zhang PetscInt k; 3962eeffb40dSHong Zhang #endif 39637264ac53SSatish Balay 39643a40ed3dSBarry Smith PetscFunctionBegin; 3965bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 3966d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 3967ca44d042SBarry Smith *flg = PETSC_FALSE; 3968ca44d042SBarry Smith PetscFunctionReturn(0); 3969bcd2baecSBarry Smith } 39707264ac53SSatish Balay 39717264ac53SSatish Balay /* if the a->i are the same */ 3972d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3973abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 39747264ac53SSatish Balay 39757264ac53SSatish Balay /* if a->j are the same */ 397697f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 3977abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 3978bcd2baecSBarry Smith 3979bcd2baecSBarry Smith /* if a->a are the same */ 3980eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 3981eeffb40dSHong Zhang for (k=0; k<a->nz; k++){ 3982eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])){ 3983eeffb40dSHong Zhang *flg = PETSC_FALSE; 39843a40ed3dSBarry Smith PetscFunctionReturn(0); 3985eeffb40dSHong Zhang } 3986eeffb40dSHong Zhang } 3987eeffb40dSHong Zhang #else 3988eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 3989eeffb40dSHong Zhang #endif 3990eeffb40dSHong Zhang PetscFunctionReturn(0); 39917264ac53SSatish Balay } 399236db0b34SBarry Smith 39934a2ae208SSatish Balay #undef __FUNCT__ 39944a2ae208SSatish Balay #define __FUNCT__ "MatCreateSeqAIJWithArrays" 399505869f15SSatish Balay /*@ 399636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 399736db0b34SBarry Smith provided by the user. 399836db0b34SBarry Smith 3999c75a6043SHong Zhang Collective on MPI_Comm 400036db0b34SBarry Smith 400136db0b34SBarry Smith Input Parameters: 400236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 400336db0b34SBarry Smith . m - number of rows 400436db0b34SBarry Smith . n - number of columns 400536db0b34SBarry Smith . i - row indices 400636db0b34SBarry Smith . j - column indices 400736db0b34SBarry Smith - a - matrix values 400836db0b34SBarry Smith 400936db0b34SBarry Smith Output Parameter: 401036db0b34SBarry Smith . mat - the matrix 401136db0b34SBarry Smith 401236db0b34SBarry Smith Level: intermediate 401336db0b34SBarry Smith 401436db0b34SBarry Smith Notes: 40150551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4016292fb18eSBarry Smith once the matrix is destroyed and not before 401736db0b34SBarry Smith 401836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 401936db0b34SBarry Smith 4020bfeeae90SHong Zhang The i and j indices are 0 based 402136db0b34SBarry Smith 4022a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4023a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 4024a4552177SSatish Balay as shown: 4025a4552177SSatish Balay 4026a4552177SSatish Balay 1 0 0 4027a4552177SSatish Balay 2 0 3 4028a4552177SSatish Balay 4 5 6 4029a4552177SSatish Balay 4030a4552177SSatish Balay i = {0,1,3,6} [size = nrow+1 = 3+1] 40319985e31cSBarry Smith j = {0,0,2,0,1,2} [size = nz = 6]; values must be sorted for each row 4032a4552177SSatish Balay v = {1,2,3,4,5,6} [size = nz = 6] 4033a4552177SSatish Balay 40349985e31cSBarry Smith 403569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 403636db0b34SBarry Smith 403736db0b34SBarry Smith @*/ 40387087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat) 403936db0b34SBarry Smith { 4040dfbe8321SBarry Smith PetscErrorCode ierr; 4041cbcfb4deSHong Zhang PetscInt ii; 404236db0b34SBarry Smith Mat_SeqAIJ *aij; 4043cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4044cbcfb4deSHong Zhang PetscInt jj; 4045cbcfb4deSHong Zhang #endif 404636db0b34SBarry Smith 404736db0b34SBarry Smith PetscFunctionBegin; 4048a96a251dSBarry Smith if (i[0]) { 4049e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 405036db0b34SBarry Smith } 4051f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4052f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4053a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4054ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4055ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4056ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4057ab93d7beSBarry Smith ierr = PetscMalloc2(m,PetscInt,&aij->imax,m,PetscInt,&aij->ilen);CHKERRQ(ierr); 4058ab93d7beSBarry Smith 405936db0b34SBarry Smith aij->i = i; 406036db0b34SBarry Smith aij->j = j; 406136db0b34SBarry Smith aij->a = a; 406236db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 406336db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4064e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4065e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 406636db0b34SBarry Smith 406736db0b34SBarry Smith for (ii=0; ii<m; ii++) { 406836db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 40692515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 4070e32f2f54SBarry 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]); 40719985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4072e32f2f54SBarry 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); 4073e32f2f54SBarry 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); 40749985e31cSBarry Smith } 407536db0b34SBarry Smith #endif 407636db0b34SBarry Smith } 40772515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 407836db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 4079e32f2f54SBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %d index = %d",ii,j[ii]); 4080e32f2f54SBarry 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]); 408136db0b34SBarry Smith } 408236db0b34SBarry Smith #endif 408336db0b34SBarry Smith 4084b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4085b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 408636db0b34SBarry Smith PetscFunctionReturn(0); 408736db0b34SBarry Smith } 40888a0b0e6bSVictor Minden #undef __FUNCT__ 40898a0b0e6bSVictor Minden #define __FUNCT__ "MatCreateSeqAIJFromTriple" 409080ef6e79SMatthew G Knepley /*@C 4091d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 40928a0b0e6bSVictor Minden provided by the user. 40938a0b0e6bSVictor Minden 40948a0b0e6bSVictor Minden Collective on MPI_Comm 40958a0b0e6bSVictor Minden 40968a0b0e6bSVictor Minden Input Parameters: 40978a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 40988a0b0e6bSVictor Minden . m - number of rows 40998a0b0e6bSVictor Minden . n - number of columns 41008a0b0e6bSVictor Minden . i - row indices 41018a0b0e6bSVictor Minden . j - column indices 41021230e6d1SVictor Minden . a - matrix values 41031230e6d1SVictor Minden . nz - number of nonzeros 41041230e6d1SVictor Minden - idx - 0 or 1 based 41058a0b0e6bSVictor Minden 41068a0b0e6bSVictor Minden Output Parameter: 41078a0b0e6bSVictor Minden . mat - the matrix 41088a0b0e6bSVictor Minden 41098a0b0e6bSVictor Minden Level: intermediate 41108a0b0e6bSVictor Minden 41118a0b0e6bSVictor Minden Notes: 41128a0b0e6bSVictor Minden The i and j indices are 0 based 41138a0b0e6bSVictor Minden 41148a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 41158a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 41168a0b0e6bSVictor Minden as shown: 41178a0b0e6bSVictor Minden 41188a0b0e6bSVictor Minden 1 0 0 41198a0b0e6bSVictor Minden 2 0 3 41208a0b0e6bSVictor Minden 4 5 6 41218a0b0e6bSVictor Minden 41228a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 41238a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 41248a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 41258a0b0e6bSVictor Minden 41268a0b0e6bSVictor Minden 412769b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 41288a0b0e6bSVictor Minden 41298a0b0e6bSVictor Minden @*/ 41301230e6d1SVictor Minden PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt* i,PetscInt*j,PetscScalar *a,Mat *mat,PetscInt nz,PetscBool idx) 41318a0b0e6bSVictor Minden { 41328a0b0e6bSVictor Minden PetscErrorCode ierr; 4133d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 41348a0b0e6bSVictor Minden 41358a0b0e6bSVictor Minden 41368a0b0e6bSVictor Minden PetscFunctionBegin; 4137d021a1c5SVictor Minden ierr = PetscMalloc(m*sizeof(PetscInt),&nnz);CHKERRQ(ierr); 41381230e6d1SVictor Minden ierr = PetscMemzero(nnz,m*sizeof(PetscInt));CHKERRQ(ierr); 41391230e6d1SVictor Minden for (ii = 0; ii < nz; ii++){ 41401230e6d1SVictor Minden nnz[i[ii]] += 1; 41411230e6d1SVictor Minden } 41428a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 41438a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4144a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 41458a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 41461230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 41471230e6d1SVictor Minden for (ii = 0; ii < nz; ii++){ 41481230e6d1SVictor Minden if (idx){ 41491230e6d1SVictor Minden row = i[ii] - 1; 41501230e6d1SVictor Minden col = j[ii] - 1; 41511230e6d1SVictor Minden } else { 41521230e6d1SVictor Minden row = i[ii]; 41531230e6d1SVictor Minden col = j[ii]; 41548a0b0e6bSVictor Minden } 41551230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 41568a0b0e6bSVictor Minden } 41578a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 41588a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4159d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 41608a0b0e6bSVictor Minden PetscFunctionReturn(0); 41618a0b0e6bSVictor Minden } 416236db0b34SBarry Smith 4163cc8ba8e1SBarry Smith #undef __FUNCT__ 4164ee4f033dSBarry Smith #define __FUNCT__ "MatSetColoring_SeqAIJ" 4165dfbe8321SBarry Smith PetscErrorCode MatSetColoring_SeqAIJ(Mat A,ISColoring coloring) 4166cc8ba8e1SBarry Smith { 4167dfbe8321SBarry Smith PetscErrorCode ierr; 4168cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 416936db0b34SBarry Smith 4170cc8ba8e1SBarry Smith PetscFunctionBegin; 41718ee2e534SBarry Smith if (coloring->ctype == IS_COLORING_GLOBAL) { 4172cc8ba8e1SBarry Smith ierr = ISColoringReference(coloring);CHKERRQ(ierr); 4173cc8ba8e1SBarry Smith a->coloring = coloring; 417412c595b3SBarry Smith } else if (coloring->ctype == IS_COLORING_GHOSTED) { 417597f1f81fSBarry Smith PetscInt i,*larray; 417612c595b3SBarry Smith ISColoring ocoloring; 417708b6dcc0SBarry Smith ISColoringValue *colors; 417812c595b3SBarry Smith 417912c595b3SBarry Smith /* set coloring for diagonal portion */ 41800e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(PetscInt),&larray);CHKERRQ(ierr); 4181d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 418212c595b3SBarry Smith larray[i] = i; 418312c595b3SBarry Smith } 4184992144d0SBarry Smith ierr = ISGlobalToLocalMappingApply(A->cmap->mapping,IS_GTOLM_MASK,A->cmap->n,larray,PETSC_NULL,larray);CHKERRQ(ierr); 41850e83c824SBarry Smith ierr = PetscMalloc(A->cmap->n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); 4186d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 418712c595b3SBarry Smith colors[i] = coloring->colors[larray[i]]; 418812c595b3SBarry Smith } 418912c595b3SBarry Smith ierr = PetscFree(larray);CHKERRQ(ierr); 4190d0f46423SBarry Smith ierr = ISColoringCreate(PETSC_COMM_SELF,coloring->n,A->cmap->n,colors,&ocoloring);CHKERRQ(ierr); 419112c595b3SBarry Smith a->coloring = ocoloring; 419212c595b3SBarry Smith } 4193cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4194cc8ba8e1SBarry Smith } 4195cc8ba8e1SBarry Smith 4196dcf5cc72SBarry Smith #if defined(PETSC_HAVE_ADIC) 4197ee4f033dSBarry Smith EXTERN_C_BEGIN 4198c6db04a5SJed Brown #include <adic/ad_utils.h> 4199ee4f033dSBarry Smith EXTERN_C_END 4200cc8ba8e1SBarry Smith 4201cc8ba8e1SBarry Smith #undef __FUNCT__ 4202ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdic_SeqAIJ" 4203dfbe8321SBarry Smith PetscErrorCode MatSetValuesAdic_SeqAIJ(Mat A,void *advalues) 4204cc8ba8e1SBarry Smith { 4205cc8ba8e1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4206d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j,nlen; 42074440f671SBarry Smith PetscScalar *v = a->a,*values = ((PetscScalar*)advalues)+1; 420808b6dcc0SBarry Smith ISColoringValue *color; 4209cc8ba8e1SBarry Smith 4210cc8ba8e1SBarry Smith PetscFunctionBegin; 4211e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 42124440f671SBarry Smith nlen = PetscADGetDerivTypeSize()/sizeof(PetscScalar); 4213cc8ba8e1SBarry Smith color = a->coloring->colors; 4214cc8ba8e1SBarry Smith /* loop over rows */ 4215cc8ba8e1SBarry Smith for (i=0; i<m; i++) { 4216cc8ba8e1SBarry Smith nz = ii[i+1] - ii[i]; 4217cc8ba8e1SBarry Smith /* loop over columns putting computed value into matrix */ 4218cc8ba8e1SBarry Smith for (j=0; j<nz; j++) { 4219cc8ba8e1SBarry Smith *v++ = values[color[*jj++]]; 4220cc8ba8e1SBarry Smith } 42214440f671SBarry Smith values += nlen; /* jump to next row of derivatives */ 4222ee4f033dSBarry Smith } 4223ee4f033dSBarry Smith PetscFunctionReturn(0); 4224ee4f033dSBarry Smith } 4225ee4f033dSBarry Smith #endif 4226ee4f033dSBarry Smith 4227ee4f033dSBarry Smith #undef __FUNCT__ 4228ee4f033dSBarry Smith #define __FUNCT__ "MatSetValuesAdifor_SeqAIJ" 422997f1f81fSBarry Smith PetscErrorCode MatSetValuesAdifor_SeqAIJ(Mat A,PetscInt nl,void *advalues) 4230ee4f033dSBarry Smith { 4231ee4f033dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 4232d0f46423SBarry Smith PetscInt m = A->rmap->n,*ii = a->i,*jj = a->j,nz,i,j; 423354f21887SBarry Smith MatScalar *v = a->a; 423454f21887SBarry Smith PetscScalar *values = (PetscScalar *)advalues; 423508b6dcc0SBarry Smith ISColoringValue *color; 4236ee4f033dSBarry Smith 4237ee4f033dSBarry Smith PetscFunctionBegin; 4238e32f2f54SBarry Smith if (!a->coloring) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Coloring not set for matrix"); 4239ee4f033dSBarry Smith color = a->coloring->colors; 4240ee4f033dSBarry Smith /* loop over rows */ 4241ee4f033dSBarry Smith for (i=0; i<m; i++) { 4242ee4f033dSBarry Smith nz = ii[i+1] - ii[i]; 4243ee4f033dSBarry Smith /* loop over columns putting computed value into matrix */ 4244ee4f033dSBarry Smith for (j=0; j<nz; j++) { 4245ee4f033dSBarry Smith *v++ = values[color[*jj++]]; 4246ee4f033dSBarry Smith } 4247ee4f033dSBarry Smith values += nl; /* jump to next row of derivatives */ 4248cc8ba8e1SBarry Smith } 4249cc8ba8e1SBarry Smith PetscFunctionReturn(0); 4250cc8ba8e1SBarry Smith } 425136db0b34SBarry Smith 42520847f33cSJed Brown #undef __FUNCT__ 42530847f33cSJed Brown #define __FUNCT__ "MatSeqAIJInvalidateDiagonal" 42540847f33cSJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 42550847f33cSJed Brown { 42560847f33cSJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 42570847f33cSJed Brown PetscErrorCode ierr; 42580847f33cSJed Brown 42590847f33cSJed Brown PetscFunctionBegin; 42600847f33cSJed Brown a->idiagvalid = PETSC_FALSE; 42610847f33cSJed Brown a->ibdiagvalid = PETSC_FALSE; 42620847f33cSJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 42630847f33cSJed Brown PetscFunctionReturn(0); 42640847f33cSJed Brown } 42650847f33cSJed Brown 426681824310SBarry Smith /* 426781824310SBarry Smith Special version for direct calls from Fortran 426881824310SBarry Smith */ 4269b45d2f2cSJed Brown #include <petsc-private/fortranimpl.h> 427081824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 427181824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 427281824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 427381824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 427481824310SBarry Smith #endif 427581824310SBarry Smith 427681824310SBarry Smith /* Change these macros so can be used in void function */ 427781824310SBarry Smith #undef CHKERRQ 42787adad957SLisandro Dalcin #define CHKERRQ(ierr) CHKERRABORT(((PetscObject)A)->comm,ierr) 427981824310SBarry Smith #undef SETERRQ2 4280e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 42814994cf47SJed Brown #undef SETERRQ3 42824994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 428381824310SBarry Smith 428481824310SBarry Smith EXTERN_C_BEGIN 428581824310SBarry Smith #undef __FUNCT__ 428681824310SBarry Smith #define __FUNCT__ "matsetvaluesseqaij_" 42871f6cc5b2SSatish Balay void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 428881824310SBarry Smith { 428981824310SBarry Smith Mat A = *AA; 429081824310SBarry Smith PetscInt m = *mm, n = *nn; 429181824310SBarry Smith InsertMode is = *isis; 429281824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 429381824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 429481824310SBarry Smith PetscInt *imax,*ai,*ailen; 429581824310SBarry Smith PetscErrorCode ierr; 429681824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 429754f21887SBarry Smith MatScalar *ap,value,*aa; 4298ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4299ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 430081824310SBarry Smith 430181824310SBarry Smith PetscFunctionBegin; 43024994cf47SJed Brown MatCheckPreallocated(A,1); 430381824310SBarry Smith imax = a->imax; 430481824310SBarry Smith ai = a->i; 430581824310SBarry Smith ailen = a->ilen; 430681824310SBarry Smith aj = a->j; 430781824310SBarry Smith aa = a->a; 430881824310SBarry Smith 430981824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 431081824310SBarry Smith row = im[k]; 431181824310SBarry Smith if (row < 0) continue; 431281824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4313d0f46423SBarry Smith if (row >= A->rmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 431481824310SBarry Smith #endif 431581824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 431681824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 431781824310SBarry Smith low = 0; 431881824310SBarry Smith high = nrow; 431981824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 432081824310SBarry Smith if (in[l] < 0) continue; 432181824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4322d0f46423SBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 432381824310SBarry Smith #endif 432481824310SBarry Smith col = in[l]; 432581824310SBarry Smith if (roworiented) { 432681824310SBarry Smith value = v[l + k*n]; 432781824310SBarry Smith } else { 432881824310SBarry Smith value = v[k + l*m]; 432981824310SBarry Smith } 433081824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 433181824310SBarry Smith 433281824310SBarry Smith if (col <= lastcol) low = 0; else high = nrow; 433381824310SBarry Smith lastcol = col; 433481824310SBarry Smith while (high-low > 5) { 433581824310SBarry Smith t = (low+high)/2; 433681824310SBarry Smith if (rp[t] > col) high = t; 433781824310SBarry Smith else low = t; 433881824310SBarry Smith } 433981824310SBarry Smith for (i=low; i<high; i++) { 434081824310SBarry Smith if (rp[i] > col) break; 434181824310SBarry Smith if (rp[i] == col) { 434281824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 434381824310SBarry Smith else ap[i] = value; 434481824310SBarry Smith goto noinsert; 434581824310SBarry Smith } 434681824310SBarry Smith } 434781824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 434881824310SBarry Smith if (nonew == 1) goto noinsert; 43497adad957SLisandro Dalcin if (nonew == -1) SETERRABORT(((PetscObject)A)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4350fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 435181824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 435281824310SBarry Smith /* shift up all the later entries in this row */ 435381824310SBarry Smith for (ii=N; ii>=i; ii--) { 435481824310SBarry Smith rp[ii+1] = rp[ii]; 435581824310SBarry Smith ap[ii+1] = ap[ii]; 435681824310SBarry Smith } 435781824310SBarry Smith rp[i] = col; 435881824310SBarry Smith ap[i] = value; 435981824310SBarry Smith noinsert:; 436081824310SBarry Smith low = i + 1; 436181824310SBarry Smith } 436281824310SBarry Smith ailen[row] = nrow; 436381824310SBarry Smith } 436481824310SBarry Smith A->same_nonzero = PETSC_FALSE; 436581824310SBarry Smith PetscFunctionReturnVoid(); 436681824310SBarry Smith } 436781824310SBarry Smith EXTERN_C_END 436862298a1eSBarry Smith 4369