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> 11af0996ceSBarry Smith #include <petsc/private/kernels/blocktranspose.h> 120716a85fSBarry Smith 130716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqAIJ(Mat A,NormType type,PetscReal *norms) 140716a85fSBarry Smith { 150716a85fSBarry Smith PetscErrorCode ierr; 160716a85fSBarry Smith PetscInt i,m,n; 170716a85fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 180716a85fSBarry Smith 190716a85fSBarry Smith PetscFunctionBegin; 200716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 210716a85fSBarry Smith ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr); 220716a85fSBarry Smith if (type == NORM_2) { 230716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 240716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]*aij->a[i]); 250716a85fSBarry Smith } 260716a85fSBarry Smith } else if (type == NORM_1) { 270716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 280716a85fSBarry Smith norms[aij->j[i]] += PetscAbsScalar(aij->a[i]); 290716a85fSBarry Smith } 300716a85fSBarry Smith } else if (type == NORM_INFINITY) { 310716a85fSBarry Smith for (i=0; i<aij->i[m]; i++) { 320716a85fSBarry Smith norms[aij->j[i]] = PetscMax(PetscAbsScalar(aij->a[i]),norms[aij->j[i]]); 330716a85fSBarry Smith } 340716a85fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown NormType"); 350716a85fSBarry Smith 360716a85fSBarry Smith if (type == NORM_2) { 378f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 380716a85fSBarry Smith } 390716a85fSBarry Smith PetscFunctionReturn(0); 400716a85fSBarry Smith } 410716a85fSBarry Smith 423a062f41SBarry Smith PetscErrorCode MatFindOffBlockDiagonalEntries_SeqAIJ(Mat A,IS *is) 433a062f41SBarry Smith { 443a062f41SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 453a062f41SBarry Smith PetscInt i,m=A->rmap->n,cnt = 0, bs = A->rmap->bs; 463a062f41SBarry Smith const PetscInt *jj = a->j,*ii = a->i; 473a062f41SBarry Smith PetscInt *rows; 483a062f41SBarry Smith PetscErrorCode ierr; 493a062f41SBarry Smith 503a062f41SBarry Smith PetscFunctionBegin; 513a062f41SBarry Smith for (i=0; i<m; i++) { 523a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 533a062f41SBarry Smith cnt++; 543a062f41SBarry Smith } 553a062f41SBarry Smith } 563a062f41SBarry Smith ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 573a062f41SBarry Smith cnt = 0; 583a062f41SBarry Smith for (i=0; i<m; i++) { 593a062f41SBarry Smith if ((ii[i] != ii[i+1]) && ((jj[ii[i]] < bs*(i/bs)) || (jj[ii[i+1]-1] > bs*((i+bs)/bs)-1))) { 603a062f41SBarry Smith rows[cnt] = i; 613a062f41SBarry Smith cnt++; 623a062f41SBarry Smith } 633a062f41SBarry Smith } 643a062f41SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,is);CHKERRQ(ierr); 653a062f41SBarry Smith PetscFunctionReturn(0); 663a062f41SBarry Smith } 673a062f41SBarry Smith 68f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ_Private(Mat A,PetscInt *nrows,PetscInt **zrows) 696ce1633cSBarry Smith { 706ce1633cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 716ce1633cSBarry Smith const MatScalar *aa = a->a; 726ce1633cSBarry Smith PetscInt i,m=A->rmap->n,cnt = 0; 73b2db7409Sstefano_zampini const PetscInt *ii = a->i,*jj = a->j,*diag; 746ce1633cSBarry Smith PetscInt *rows; 756ce1633cSBarry Smith PetscErrorCode ierr; 766ce1633cSBarry Smith 776ce1633cSBarry Smith PetscFunctionBegin; 786ce1633cSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 796ce1633cSBarry Smith diag = a->diag; 806ce1633cSBarry Smith for (i=0; i<m; i++) { 81b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 826ce1633cSBarry Smith cnt++; 836ce1633cSBarry Smith } 846ce1633cSBarry Smith } 85785e854fSJed Brown ierr = PetscMalloc1(cnt,&rows);CHKERRQ(ierr); 866ce1633cSBarry Smith cnt = 0; 876ce1633cSBarry Smith for (i=0; i<m; i++) { 88b2db7409Sstefano_zampini if ((diag[i] >= ii[i+1]) || (jj[diag[i]] != i) || (aa[diag[i]] == 0.0)) { 896ce1633cSBarry Smith rows[cnt++] = i; 906ce1633cSBarry Smith } 916ce1633cSBarry Smith } 92f1f41ecbSJed Brown *nrows = cnt; 93f1f41ecbSJed Brown *zrows = rows; 94f1f41ecbSJed Brown PetscFunctionReturn(0); 95f1f41ecbSJed Brown } 96f1f41ecbSJed Brown 97f1f41ecbSJed Brown PetscErrorCode MatFindZeroDiagonals_SeqAIJ(Mat A,IS *zrows) 98f1f41ecbSJed Brown { 99f1f41ecbSJed Brown PetscInt nrows,*rows; 100f1f41ecbSJed Brown PetscErrorCode ierr; 101f1f41ecbSJed Brown 102f1f41ecbSJed Brown PetscFunctionBegin; 1030298fd71SBarry Smith *zrows = NULL; 104f1f41ecbSJed Brown ierr = MatFindZeroDiagonals_SeqAIJ_Private(A,&nrows,&rows);CHKERRQ(ierr); 105ce94432eSBarry Smith ierr = ISCreateGeneral(PetscObjectComm((PetscObject)A),nrows,rows,PETSC_OWN_POINTER,zrows);CHKERRQ(ierr); 1066ce1633cSBarry Smith PetscFunctionReturn(0); 1076ce1633cSBarry Smith } 1086ce1633cSBarry Smith 109b3a44c85SBarry Smith PetscErrorCode MatFindNonzeroRows_SeqAIJ(Mat A,IS *keptrows) 110b3a44c85SBarry Smith { 111b3a44c85SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 112b3a44c85SBarry Smith const MatScalar *aa; 113b3a44c85SBarry Smith PetscInt m=A->rmap->n,cnt = 0; 114b3a44c85SBarry Smith const PetscInt *ii; 115b3a44c85SBarry Smith PetscInt n,i,j,*rows; 116b3a44c85SBarry Smith PetscErrorCode ierr; 117b3a44c85SBarry Smith 118b3a44c85SBarry Smith PetscFunctionBegin; 119b3a44c85SBarry Smith *keptrows = 0; 120b3a44c85SBarry Smith ii = a->i; 121b3a44c85SBarry Smith for (i=0; i<m; i++) { 122b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 123b3a44c85SBarry Smith if (!n) { 124b3a44c85SBarry Smith cnt++; 125b3a44c85SBarry Smith goto ok1; 126b3a44c85SBarry Smith } 127b3a44c85SBarry Smith aa = a->a + ii[i]; 128b3a44c85SBarry Smith for (j=0; j<n; j++) { 129b3a44c85SBarry Smith if (aa[j] != 0.0) goto ok1; 130b3a44c85SBarry Smith } 131b3a44c85SBarry Smith cnt++; 132b3a44c85SBarry Smith ok1:; 133b3a44c85SBarry Smith } 134b3a44c85SBarry Smith if (!cnt) PetscFunctionReturn(0); 135854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n-cnt,&rows);CHKERRQ(ierr); 136b3a44c85SBarry Smith cnt = 0; 137b3a44c85SBarry Smith for (i=0; i<m; i++) { 138b3a44c85SBarry Smith n = ii[i+1] - ii[i]; 139b3a44c85SBarry Smith if (!n) continue; 140b3a44c85SBarry Smith aa = a->a + ii[i]; 141b3a44c85SBarry Smith for (j=0; j<n; j++) { 142b3a44c85SBarry Smith if (aa[j] != 0.0) { 143b3a44c85SBarry Smith rows[cnt++] = i; 144b3a44c85SBarry Smith break; 145b3a44c85SBarry Smith } 146b3a44c85SBarry Smith } 147b3a44c85SBarry Smith } 148b3a44c85SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,cnt,rows,PETSC_OWN_POINTER,keptrows);CHKERRQ(ierr); 149b3a44c85SBarry Smith PetscFunctionReturn(0); 150b3a44c85SBarry Smith } 151b3a44c85SBarry Smith 1527087cfbeSBarry Smith PetscErrorCode MatDiagonalSet_SeqAIJ(Mat Y,Vec D,InsertMode is) 15379299369SBarry Smith { 15479299369SBarry Smith PetscErrorCode ierr; 15579299369SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) Y->data; 15699e65526SBarry Smith PetscInt i,m = Y->rmap->n; 15799e65526SBarry Smith const PetscInt *diag; 15854f21887SBarry Smith MatScalar *aa = aij->a; 15999e65526SBarry Smith const PetscScalar *v; 160ace3abfcSBarry Smith PetscBool missing; 16179299369SBarry Smith 16279299369SBarry Smith PetscFunctionBegin; 16309f38230SBarry Smith if (Y->assembled) { 1640298fd71SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(Y,&missing,NULL);CHKERRQ(ierr); 16509f38230SBarry Smith if (!missing) { 16679299369SBarry Smith diag = aij->diag; 16799e65526SBarry Smith ierr = VecGetArrayRead(D,&v);CHKERRQ(ierr); 16879299369SBarry Smith if (is == INSERT_VALUES) { 16979299369SBarry Smith for (i=0; i<m; i++) { 17079299369SBarry Smith aa[diag[i]] = v[i]; 17179299369SBarry Smith } 17279299369SBarry Smith } else { 17379299369SBarry Smith for (i=0; i<m; i++) { 17479299369SBarry Smith aa[diag[i]] += v[i]; 17579299369SBarry Smith } 17679299369SBarry Smith } 17799e65526SBarry Smith ierr = VecRestoreArrayRead(D,&v);CHKERRQ(ierr); 17879299369SBarry Smith PetscFunctionReturn(0); 17979299369SBarry Smith } 180acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 18109f38230SBarry Smith } 18209f38230SBarry Smith ierr = MatDiagonalSet_Default(Y,D,is);CHKERRQ(ierr); 18309f38230SBarry Smith PetscFunctionReturn(0); 18409f38230SBarry Smith } 18579299369SBarry Smith 1861a83f524SJed Brown PetscErrorCode MatGetRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *m,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 18717ab2063SBarry Smith { 188416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 189dfbe8321SBarry Smith PetscErrorCode ierr; 19097f1f81fSBarry Smith PetscInt i,ishift; 19117ab2063SBarry Smith 1923a40ed3dSBarry Smith PetscFunctionBegin; 193d0f46423SBarry Smith *m = A->rmap->n; 1943a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 195bfeeae90SHong Zhang ishift = 0; 19653e63a63SBarry Smith if (symmetric && !A->structurally_symmetric) { 1972462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,ishift,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 198bfeeae90SHong Zhang } else if (oshift == 1) { 1991a83f524SJed Brown PetscInt *tia; 200d0f46423SBarry Smith PetscInt nz = a->i[A->rmap->n]; 2013b2fbd54SBarry Smith /* malloc space and add 1 to i and j indices */ 202854ce69bSBarry Smith ierr = PetscMalloc1(A->rmap->n+1,&tia);CHKERRQ(ierr); 2031a83f524SJed Brown for (i=0; i<A->rmap->n+1; i++) tia[i] = a->i[i] + 1; 2041a83f524SJed Brown *ia = tia; 205ecc77c7aSBarry Smith if (ja) { 2061a83f524SJed Brown PetscInt *tja; 207854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&tja);CHKERRQ(ierr); 2081a83f524SJed Brown for (i=0; i<nz; i++) tja[i] = a->j[i] + 1; 2091a83f524SJed Brown *ja = tja; 210ecc77c7aSBarry Smith } 2116945ee14SBarry Smith } else { 212ecc77c7aSBarry Smith *ia = a->i; 213ecc77c7aSBarry Smith if (ja) *ja = a->j; 214a2ce50c7SBarry Smith } 2153a40ed3dSBarry Smith PetscFunctionReturn(0); 216a2744918SBarry Smith } 217a2744918SBarry Smith 2181a83f524SJed Brown PetscErrorCode MatRestoreRowIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2196945ee14SBarry Smith { 220dfbe8321SBarry Smith PetscErrorCode ierr; 2216945ee14SBarry Smith 2223a40ed3dSBarry Smith PetscFunctionBegin; 2233a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 224bfeeae90SHong Zhang if ((symmetric && !A->structurally_symmetric) || oshift == 1) { 225606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 226ecc77c7aSBarry Smith if (ja) {ierr = PetscFree(*ja);CHKERRQ(ierr);} 227bcd2baecSBarry Smith } 2283a40ed3dSBarry Smith PetscFunctionReturn(0); 22917ab2063SBarry Smith } 23017ab2063SBarry Smith 2311a83f524SJed Brown PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2323b2fbd54SBarry Smith { 2333b2fbd54SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 234dfbe8321SBarry Smith PetscErrorCode ierr; 235d0f46423SBarry Smith PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 23697f1f81fSBarry Smith PetscInt nz = a->i[m],row,*jj,mr,col; 2373b2fbd54SBarry Smith 2383a40ed3dSBarry Smith PetscFunctionBegin; 239899cda47SBarry Smith *nn = n; 2403a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2413b2fbd54SBarry Smith if (symmetric) { 2422462f5fdSStefano Zampini ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,PETSC_TRUE,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 2433b2fbd54SBarry Smith } else { 2441795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 245854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 246854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr); 2473b2fbd54SBarry Smith jj = a->j; 2483b2fbd54SBarry Smith for (i=0; i<nz; i++) { 249bfeeae90SHong Zhang collengths[jj[i]]++; 2503b2fbd54SBarry Smith } 2513b2fbd54SBarry Smith cia[0] = oshift; 2523b2fbd54SBarry Smith for (i=0; i<n; i++) { 2533b2fbd54SBarry Smith cia[i+1] = cia[i] + collengths[i]; 2543b2fbd54SBarry Smith } 25597f1f81fSBarry Smith ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 2563b2fbd54SBarry Smith jj = a->j; 257a93ec695SBarry Smith for (row=0; row<m; row++) { 258a93ec695SBarry Smith mr = a->i[row+1] - a->i[row]; 259a93ec695SBarry Smith for (i=0; i<mr; i++) { 260bfeeae90SHong Zhang col = *jj++; 2612205254eSKarl Rupp 2623b2fbd54SBarry Smith cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 2633b2fbd54SBarry Smith } 2643b2fbd54SBarry Smith } 265606d414cSSatish Balay ierr = PetscFree(collengths);CHKERRQ(ierr); 2663b2fbd54SBarry Smith *ia = cia; *ja = cja; 2673b2fbd54SBarry Smith } 2683a40ed3dSBarry Smith PetscFunctionReturn(0); 2693b2fbd54SBarry Smith } 2703b2fbd54SBarry Smith 2711a83f524SJed Brown PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done) 2723b2fbd54SBarry Smith { 273dfbe8321SBarry Smith PetscErrorCode ierr; 274606d414cSSatish Balay 2753a40ed3dSBarry Smith PetscFunctionBegin; 2763a40ed3dSBarry Smith if (!ia) PetscFunctionReturn(0); 2773b2fbd54SBarry Smith 278606d414cSSatish Balay ierr = PetscFree(*ia);CHKERRQ(ierr); 279606d414cSSatish Balay ierr = PetscFree(*ja);CHKERRQ(ierr); 2803a40ed3dSBarry Smith PetscFunctionReturn(0); 2813b2fbd54SBarry Smith } 2823b2fbd54SBarry Smith 2837cee066cSHong Zhang /* 2847cee066cSHong Zhang MatGetColumnIJ_SeqAIJ_Color() and MatRestoreColumnIJ_SeqAIJ_Color() are customized from 2857cee066cSHong Zhang MatGetColumnIJ_SeqAIJ() and MatRestoreColumnIJ_SeqAIJ() by adding an output 286040ebd07SHong Zhang spidx[], index of a->a, to be used in MatTransposeColoringCreate_SeqAIJ() and MatFDColoringCreate_SeqXAIJ() 2877cee066cSHong Zhang */ 2887cee066cSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool *done) 2897cee066cSHong Zhang { 2907cee066cSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2917cee066cSHong Zhang PetscErrorCode ierr; 2927cee066cSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 2937cee066cSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 2947cee066cSHong Zhang PetscInt *cspidx; 2957cee066cSHong Zhang 2967cee066cSHong Zhang PetscFunctionBegin; 2977cee066cSHong Zhang *nn = n; 2987cee066cSHong Zhang if (!ia) PetscFunctionReturn(0); 299625f6d37SHong Zhang 3001795a4d1SJed Brown ierr = PetscCalloc1(n+1,&collengths);CHKERRQ(ierr); 301854ce69bSBarry Smith ierr = PetscMalloc1(n+1,&cia);CHKERRQ(ierr); 302854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cja);CHKERRQ(ierr); 303854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&cspidx);CHKERRQ(ierr); 3047cee066cSHong Zhang jj = a->j; 3057cee066cSHong Zhang for (i=0; i<nz; i++) { 3067cee066cSHong Zhang collengths[jj[i]]++; 3077cee066cSHong Zhang } 3087cee066cSHong Zhang cia[0] = oshift; 3097cee066cSHong Zhang for (i=0; i<n; i++) { 3107cee066cSHong Zhang cia[i+1] = cia[i] + collengths[i]; 3117cee066cSHong Zhang } 3127cee066cSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 3137cee066cSHong Zhang jj = a->j; 3147cee066cSHong Zhang for (row=0; row<m; row++) { 3157cee066cSHong Zhang mr = a->i[row+1] - a->i[row]; 3167cee066cSHong Zhang for (i=0; i<mr; i++) { 3177cee066cSHong Zhang col = *jj++; 3187cee066cSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 3197cee066cSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 3207cee066cSHong Zhang } 3217cee066cSHong Zhang } 3227cee066cSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 3237cee066cSHong Zhang *ia = cia; *ja = cja; 3247cee066cSHong Zhang *spidx = cspidx; 3257cee066cSHong Zhang PetscFunctionReturn(0); 3267cee066cSHong Zhang } 3277cee066cSHong Zhang 3287cee066cSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool *done) 3297cee066cSHong Zhang { 3307cee066cSHong Zhang PetscErrorCode ierr; 3317cee066cSHong Zhang 3327cee066cSHong Zhang PetscFunctionBegin; 3335243ef75SHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ(A,oshift,symmetric,inodecompressed,n,ia,ja,done);CHKERRQ(ierr); 3347cee066cSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 3357cee066cSHong Zhang PetscFunctionReturn(0); 3367cee066cSHong Zhang } 3377cee066cSHong Zhang 33887d4246cSBarry Smith PetscErrorCode MatSetValuesRow_SeqAIJ(Mat A,PetscInt row,const PetscScalar v[]) 33987d4246cSBarry Smith { 34087d4246cSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 34187d4246cSBarry Smith PetscInt *ai = a->i; 34287d4246cSBarry Smith PetscErrorCode ierr; 34387d4246cSBarry Smith 34487d4246cSBarry Smith PetscFunctionBegin; 34587d4246cSBarry Smith ierr = PetscMemcpy(a->a+ai[row],v,(ai[row+1]-ai[row])*sizeof(PetscScalar));CHKERRQ(ierr); 34687d4246cSBarry Smith PetscFunctionReturn(0); 34787d4246cSBarry Smith } 34887d4246cSBarry Smith 349bd04181cSBarry Smith /* 350bd04181cSBarry Smith MatSeqAIJSetValuesLocalFast - An optimized version of MatSetValuesLocal() for SeqAIJ matrices with several assumptions 351bd04181cSBarry Smith 352bd04181cSBarry Smith - a single row of values is set with each call 353bd04181cSBarry Smith - no row or column indices are negative or (in error) larger than the number of rows or columns 354bd04181cSBarry Smith - the values are always added to the matrix, not set 355bd04181cSBarry Smith - no new locations are introduced in the nonzero structure of the matrix 356bd04181cSBarry Smith 3571f763a69SBarry Smith This does NOT assume the global column indices are sorted 358bd04181cSBarry Smith 3591f763a69SBarry Smith */ 360bd04181cSBarry Smith 361af0996ceSBarry Smith #include <petsc/private/isimpl.h> 362189e4007SBarry Smith PetscErrorCode MatSeqAIJSetValuesLocalFast(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 363189e4007SBarry Smith { 364189e4007SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 3651f763a69SBarry Smith PetscInt low,high,t,row,nrow,i,col,l; 3661f763a69SBarry Smith const PetscInt *rp,*ai = a->i,*ailen = a->ilen,*aj = a->j; 3671f763a69SBarry Smith PetscInt lastcol = -1; 368189e4007SBarry Smith MatScalar *ap,value,*aa = a->a; 369189e4007SBarry Smith const PetscInt *ridx = A->rmap->mapping->indices,*cidx = A->cmap->mapping->indices; 370189e4007SBarry Smith 371f38dd0b8SBarry Smith row = ridx[im[0]]; 3721f763a69SBarry Smith rp = aj + ai[row]; 3731f763a69SBarry Smith ap = aa + ai[row]; 3741f763a69SBarry Smith nrow = ailen[row]; 375189e4007SBarry Smith low = 0; 376189e4007SBarry Smith high = nrow; 377189e4007SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 378189e4007SBarry Smith col = cidx[in[l]]; 379f38dd0b8SBarry Smith value = v[l]; 380189e4007SBarry Smith 381189e4007SBarry Smith if (col <= lastcol) low = 0; 382189e4007SBarry Smith else high = nrow; 383189e4007SBarry Smith lastcol = col; 384189e4007SBarry Smith while (high-low > 5) { 385189e4007SBarry Smith t = (low+high)/2; 386189e4007SBarry Smith if (rp[t] > col) high = t; 387189e4007SBarry Smith else low = t; 388189e4007SBarry Smith } 389189e4007SBarry Smith for (i=low; i<high; i++) { 390189e4007SBarry Smith if (rp[i] == col) { 3911f763a69SBarry Smith ap[i] += value; 392189e4007SBarry Smith low = i + 1; 3931f763a69SBarry Smith break; 394189e4007SBarry Smith } 395189e4007SBarry Smith } 396189e4007SBarry Smith } 397f38dd0b8SBarry Smith return 0; 398189e4007SBarry Smith } 399189e4007SBarry Smith 40097f1f81fSBarry Smith PetscErrorCode MatSetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],const PetscScalar v[],InsertMode is) 40117ab2063SBarry Smith { 402416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 403e2ee6c50SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 40497f1f81fSBarry Smith PetscInt *imax = a->imax,*ai = a->i,*ailen = a->ilen; 4056849ba73SBarry Smith PetscErrorCode ierr; 406e2ee6c50SBarry Smith PetscInt *aj = a->j,nonew = a->nonew,lastcol = -1; 40754f21887SBarry Smith MatScalar *ap,value,*aa = a->a; 408ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 409ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 41017ab2063SBarry Smith 4113a40ed3dSBarry Smith PetscFunctionBegin; 412*720833daSHong Zhang //printf("A->structure_only %d\n",A->structure_only); 41317ab2063SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 414416022c9SBarry Smith row = im[k]; 4155ef9f2a5SBarry Smith if (row < 0) continue; 4162515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 417e32f2f54SBarry 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); 4183b2fbd54SBarry Smith #endif 419*720833daSHong Zhang rp = aj + ai[row]; 420*720833daSHong Zhang if (A->structure_only) { 421*720833daSHong Zhang ap = aa + ai[row]; 422*720833daSHong Zhang } 42317ab2063SBarry Smith rmax = imax[row]; nrow = ailen[row]; 424416022c9SBarry Smith low = 0; 425c71e6ed7SBarry Smith high = nrow; 42617ab2063SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 4275ef9f2a5SBarry Smith if (in[l] < 0) continue; 4282515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 429e32f2f54SBarry 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); 4303b2fbd54SBarry Smith #endif 431bfeeae90SHong Zhang col = in[l]; 432*720833daSHong Zhang if (!A->structure_only) { 4334b0e389bSBarry Smith if (roworiented) { 4345ef9f2a5SBarry Smith value = v[l + k*n]; 435bef8e0ddSBarry Smith } else { 4364b0e389bSBarry Smith value = v[k + l*m]; 4374b0e389bSBarry Smith } 438*720833daSHong Zhang } else { /* A->structure_only */ 439*720833daSHong Zhang value = 1; /* avoid 'continue' below? */ 440*720833daSHong Zhang } 441dcd36c23SBarry Smith if ((value == 0.0 && ignorezeroentries) && (is == ADD_VALUES) && row != col) continue; 44236db0b34SBarry Smith 4432205254eSKarl Rupp if (col <= lastcol) low = 0; 4442205254eSKarl Rupp else high = nrow; 445e2ee6c50SBarry Smith lastcol = col; 446416022c9SBarry Smith while (high-low > 5) { 447416022c9SBarry Smith t = (low+high)/2; 448416022c9SBarry Smith if (rp[t] > col) high = t; 449416022c9SBarry Smith else low = t; 45017ab2063SBarry Smith } 451416022c9SBarry Smith for (i=low; i<high; i++) { 45217ab2063SBarry Smith if (rp[i] > col) break; 45317ab2063SBarry Smith if (rp[i] == col) { 454*720833daSHong Zhang if (A->structure_only) { 455416022c9SBarry Smith if (is == ADD_VALUES) ap[i] += value; 45617ab2063SBarry Smith else ap[i] = value; 457*720833daSHong Zhang } 458e44c0bd4SBarry Smith low = i + 1; 45917ab2063SBarry Smith goto noinsert; 46017ab2063SBarry Smith } 46117ab2063SBarry Smith } 462dcd36c23SBarry Smith if (value == 0.0 && ignorezeroentries && row != col) goto noinsert; 463c2653b3dSLois Curfman McInnes if (nonew == 1) goto noinsert; 464e32f2f54SBarry Smith if (nonew == -1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero at (%D,%D) in the matrix",row,col); 465*720833daSHong Zhang if (A->structure_only) { 466*720833daSHong Zhang MatSeqXAIJReallocateAIJ_structure_only(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,imax,nonew,MatScalar); 467*720833daSHong Zhang } else { 468fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 469*720833daSHong Zhang } 470c03d1d03SSatish Balay N = nrow++ - 1; a->nz++; high++; 471416022c9SBarry Smith /* shift up all the later entries in this row */ 472416022c9SBarry Smith for (ii=N; ii>=i; ii--) { 47317ab2063SBarry Smith rp[ii+1] = rp[ii]; 474*720833daSHong Zhang if (A->structure_only) { 47517ab2063SBarry Smith ap[ii+1] = ap[ii]; 47617ab2063SBarry Smith } 477*720833daSHong Zhang } 47817ab2063SBarry Smith rp[i] = col; 479*720833daSHong Zhang if (A->structure_only) { 48017ab2063SBarry Smith ap[i] = value; 481*720833daSHong Zhang } 482416022c9SBarry Smith low = i + 1; 483e56f5c9eSBarry Smith A->nonzerostate++; 484e44c0bd4SBarry Smith noinsert:; 48517ab2063SBarry Smith } 48617ab2063SBarry Smith ailen[row] = nrow; 48717ab2063SBarry Smith } 4883a40ed3dSBarry Smith PetscFunctionReturn(0); 48917ab2063SBarry Smith } 49017ab2063SBarry Smith 49181824310SBarry Smith 492a77337e4SBarry Smith PetscErrorCode MatGetValues_SeqAIJ(Mat A,PetscInt m,const PetscInt im[],PetscInt n,const PetscInt in[],PetscScalar v[]) 4937eb43aa7SLois Curfman McInnes { 4947eb43aa7SLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 49597f1f81fSBarry Smith PetscInt *rp,k,low,high,t,row,nrow,i,col,l,*aj = a->j; 49697f1f81fSBarry Smith PetscInt *ai = a->i,*ailen = a->ilen; 49754f21887SBarry Smith MatScalar *ap,*aa = a->a; 4987eb43aa7SLois Curfman McInnes 4993a40ed3dSBarry Smith PetscFunctionBegin; 5007eb43aa7SLois Curfman McInnes for (k=0; k<m; k++) { /* loop over rows */ 5017eb43aa7SLois Curfman McInnes row = im[k]; 502e32f2f54SBarry Smith if (row < 0) {v += n; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row: %D",row); */ 503e32f2f54SBarry 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); 504bfeeae90SHong Zhang rp = aj + ai[row]; ap = aa + ai[row]; 5057eb43aa7SLois Curfman McInnes nrow = ailen[row]; 5067eb43aa7SLois Curfman McInnes for (l=0; l<n; l++) { /* loop over columns */ 507e32f2f54SBarry Smith if (in[l] < 0) {v++; continue;} /* SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column: %D",in[l]); */ 508e32f2f54SBarry 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); 509bfeeae90SHong Zhang col = in[l]; 5107eb43aa7SLois Curfman McInnes high = nrow; low = 0; /* assume unsorted */ 5117eb43aa7SLois Curfman McInnes while (high-low > 5) { 5127eb43aa7SLois Curfman McInnes t = (low+high)/2; 5137eb43aa7SLois Curfman McInnes if (rp[t] > col) high = t; 5147eb43aa7SLois Curfman McInnes else low = t; 5157eb43aa7SLois Curfman McInnes } 5167eb43aa7SLois Curfman McInnes for (i=low; i<high; i++) { 5177eb43aa7SLois Curfman McInnes if (rp[i] > col) break; 5187eb43aa7SLois Curfman McInnes if (rp[i] == col) { 519b49de8d1SLois Curfman McInnes *v++ = ap[i]; 5207eb43aa7SLois Curfman McInnes goto finished; 5217eb43aa7SLois Curfman McInnes } 5227eb43aa7SLois Curfman McInnes } 52397e567efSBarry Smith *v++ = 0.0; 5247eb43aa7SLois Curfman McInnes finished:; 5257eb43aa7SLois Curfman McInnes } 5267eb43aa7SLois Curfman McInnes } 5273a40ed3dSBarry Smith PetscFunctionReturn(0); 5287eb43aa7SLois Curfman McInnes } 5297eb43aa7SLois Curfman McInnes 53017ab2063SBarry Smith 531dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Binary(Mat A,PetscViewer viewer) 53217ab2063SBarry Smith { 533416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 5346849ba73SBarry Smith PetscErrorCode ierr; 5356f69ff64SBarry Smith PetscInt i,*col_lens; 5366f69ff64SBarry Smith int fd; 537b37d52dbSMark F. Adams FILE *file; 53817ab2063SBarry Smith 5393a40ed3dSBarry Smith PetscFunctionBegin; 540b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 541854ce69bSBarry Smith ierr = PetscMalloc1(4+A->rmap->n,&col_lens);CHKERRQ(ierr); 5422205254eSKarl Rupp 5430700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 544d0f46423SBarry Smith col_lens[1] = A->rmap->n; 545d0f46423SBarry Smith col_lens[2] = A->cmap->n; 546416022c9SBarry Smith col_lens[3] = a->nz; 547416022c9SBarry Smith 548416022c9SBarry Smith /* store lengths of each row and write (including header) to file */ 549d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 550416022c9SBarry Smith col_lens[4+i] = a->i[i+1] - a->i[i]; 55117ab2063SBarry Smith } 552d0f46423SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+A->rmap->n,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 553606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 554416022c9SBarry Smith 555416022c9SBarry Smith /* store column indices (zero start index) */ 5566f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->j,a->nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 557416022c9SBarry Smith 558416022c9SBarry Smith /* store nonzero values */ 5596f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,a->a,a->nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 560b37d52dbSMark F. Adams 561b37d52dbSMark F. Adams ierr = PetscViewerBinaryGetInfoPointer(viewer,&file);CHKERRQ(ierr); 562b37d52dbSMark F. Adams if (file) { 56333d57670SJed Brown fprintf(file,"-matload_block_size %d\n",(int)PetscAbs(A->rmap->bs)); 564b37d52dbSMark F. Adams } 5653a40ed3dSBarry Smith PetscFunctionReturn(0); 56617ab2063SBarry Smith } 567416022c9SBarry Smith 56809573ac7SBarry Smith extern PetscErrorCode MatSeqAIJFactorInfo_Matlab(Mat,PetscViewer); 569cd155464SBarry Smith 570dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_ASCII(Mat A,PetscViewer viewer) 571416022c9SBarry Smith { 572416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 573dfbe8321SBarry Smith PetscErrorCode ierr; 57460e0710aSBarry Smith PetscInt i,j,m = A->rmap->n; 575e060cb09SBarry Smith const char *name; 576f3ef73ceSBarry Smith PetscViewerFormat format; 57717ab2063SBarry Smith 5783a40ed3dSBarry Smith PetscFunctionBegin; 57943e49210SHong Zhang if (!a->a) PetscFunctionReturn(0); 58043e49210SHong Zhang 581b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 58271c2f376SKris Buschelman if (format == PETSC_VIEWER_ASCII_MATLAB) { 58397f1f81fSBarry Smith PetscInt nofinalvalue = 0; 58460e0710aSBarry Smith if (m && ((a->i[m] == a->i[m-1]) || (a->j[a->nz-1] != A->cmap->n-1))) { 585c337ccceSJed Brown /* Need a dummy value to ensure the dimension of the matrix. */ 586d00d2cf4SBarry Smith nofinalvalue = 1; 587d00d2cf4SBarry Smith } 588d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 589d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",m,A->cmap->n);CHKERRQ(ierr); 59077431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Nonzeros = %D \n",a->nz);CHKERRQ(ierr); 591fbfe6fa7SJed Brown #if defined(PETSC_USE_COMPLEX) 592fbfe6fa7SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,4);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 593fbfe6fa7SJed Brown #else 59477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = zeros(%D,3);\n",a->nz+nofinalvalue);CHKERRQ(ierr); 595fbfe6fa7SJed Brown #endif 596b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"zzz = [\n");CHKERRQ(ierr); 59717ab2063SBarry Smith 59817ab2063SBarry Smith for (i=0; i<m; i++) { 59960e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 600aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 601a9bf72d8SJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",i+1,a->j[j]+1,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 60217ab2063SBarry Smith #else 60360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",i+1,a->j[j]+1,(double)a->a[j]);CHKERRQ(ierr); 60417ab2063SBarry Smith #endif 60517ab2063SBarry Smith } 60617ab2063SBarry Smith } 607d00d2cf4SBarry Smith if (nofinalvalue) { 608c337ccceSJed Brown #if defined(PETSC_USE_COMPLEX) 609c337ccceSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e %18.16e\n",m,A->cmap->n,0.,0.);CHKERRQ(ierr); 610c337ccceSJed Brown #else 611d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %18.16e\n",m,A->cmap->n,0.0);CHKERRQ(ierr); 612c337ccceSJed Brown #endif 613d00d2cf4SBarry Smith } 614317d6ea6SBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 615fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"];\n %s = spconvert(zzz);\n",name);CHKERRQ(ierr); 616d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 61768369a75SKris Buschelman } else if (format == PETSC_VIEWER_ASCII_FACTOR_INFO || format == PETSC_VIEWER_ASCII_INFO) { 618cd155464SBarry Smith PetscFunctionReturn(0); 619fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 620d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 62144cd7ae7SLois Curfman McInnes for (i=0; i<m; i++) { 62277431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 62360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 624aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 62536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0 && PetscRealPart(a->a[j]) != 0.0) { 62660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 62736db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0 && PetscRealPart(a->a[j]) != 0.0) { 62860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 62936db0b34SBarry Smith } else if (PetscRealPart(a->a[j]) != 0.0) { 63060e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 6316831982aSBarry Smith } 63244cd7ae7SLois Curfman McInnes #else 63360e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr);} 63444cd7ae7SLois Curfman McInnes #endif 63544cd7ae7SLois Curfman McInnes } 636b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 63744cd7ae7SLois Curfman McInnes } 638d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 639fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_SYMMODU) { 64097f1f81fSBarry Smith PetscInt nzd=0,fshift=1,*sptr; 641d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 642854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&sptr);CHKERRQ(ierr); 643496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 644496be53dSLois Curfman McInnes sptr[i] = nzd+1; 64560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 646496be53dSLois Curfman McInnes if (a->j[j] >= i) { 647aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 64836db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) nzd++; 649496be53dSLois Curfman McInnes #else 650496be53dSLois Curfman McInnes if (a->a[j] != 0.0) nzd++; 651496be53dSLois Curfman McInnes #endif 652496be53dSLois Curfman McInnes } 653496be53dSLois Curfman McInnes } 654496be53dSLois Curfman McInnes } 6552e44a96cSLois Curfman McInnes sptr[m] = nzd+1; 65677431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %D %D\n\n",m,nzd);CHKERRQ(ierr); 6572e44a96cSLois Curfman McInnes for (i=0; i<m+1; i+=6) { 6582205254eSKarl Rupp if (i+4<m) { 6592205254eSKarl Rupp 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); 6602205254eSKarl Rupp } else if (i+3<m) { 6612205254eSKarl Rupp 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); 6622205254eSKarl Rupp } else if (i+2<m) { 6632205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2],sptr[i+3]);CHKERRQ(ierr); 6642205254eSKarl Rupp } else if (i+1<m) { 6652205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D %D\n",sptr[i],sptr[i+1],sptr[i+2]);CHKERRQ(ierr); 6662205254eSKarl Rupp } else if (i<m) { 6672205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D %D\n",sptr[i],sptr[i+1]);CHKERRQ(ierr); 6682205254eSKarl Rupp } else { 6692205254eSKarl Rupp ierr = PetscViewerASCIIPrintf(viewer," %D\n",sptr[i]);CHKERRQ(ierr); 6702205254eSKarl Rupp } 671496be53dSLois Curfman McInnes } 672b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 673606d414cSSatish Balay ierr = PetscFree(sptr);CHKERRQ(ierr); 674496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 67560e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 67677431f27SBarry Smith if (a->j[j] >= i) {ierr = PetscViewerASCIIPrintf(viewer," %D ",a->j[j]+fshift);CHKERRQ(ierr);} 677496be53dSLois Curfman McInnes } 678b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 679496be53dSLois Curfman McInnes } 680b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 681496be53dSLois Curfman McInnes for (i=0; i<m; i++) { 68260e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 683496be53dSLois Curfman McInnes if (a->j[j] >= i) { 684aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 68536db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) != 0.0 || PetscRealPart(a->a[j]) != 0.0) { 68660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %18.16e %18.16e ",(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 6876831982aSBarry Smith } 688496be53dSLois Curfman McInnes #else 68960e0710aSBarry Smith if (a->a[j] != 0.0) {ierr = PetscViewerASCIIPrintf(viewer," %18.16e ",(double)a->a[j]);CHKERRQ(ierr);} 690496be53dSLois Curfman McInnes #endif 691496be53dSLois Curfman McInnes } 692496be53dSLois Curfman McInnes } 693b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 694496be53dSLois Curfman McInnes } 695d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 696fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_DENSE) { 69797f1f81fSBarry Smith PetscInt cnt = 0,jcnt; 69887828ca2SBarry Smith PetscScalar value; 69968f1ed48SBarry Smith #if defined(PETSC_USE_COMPLEX) 70068f1ed48SBarry Smith PetscBool realonly = PETSC_TRUE; 70168f1ed48SBarry Smith 70268f1ed48SBarry Smith for (i=0; i<a->i[m]; i++) { 70368f1ed48SBarry Smith if (PetscImaginaryPart(a->a[i]) != 0.0) { 70468f1ed48SBarry Smith realonly = PETSC_FALSE; 70568f1ed48SBarry Smith break; 70668f1ed48SBarry Smith } 70768f1ed48SBarry Smith } 70868f1ed48SBarry Smith #endif 70902594712SBarry Smith 710d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 71102594712SBarry Smith for (i=0; i<m; i++) { 71202594712SBarry Smith jcnt = 0; 713d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 714e24b481bSBarry Smith if (jcnt < a->i[i+1]-a->i[i] && j == a->j[cnt]) { 71502594712SBarry Smith value = a->a[cnt++]; 716e24b481bSBarry Smith jcnt++; 71702594712SBarry Smith } else { 71802594712SBarry Smith value = 0.0; 71902594712SBarry Smith } 720aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 72168f1ed48SBarry Smith if (realonly) { 72260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)PetscRealPart(value));CHKERRQ(ierr); 72368f1ed48SBarry Smith } else { 72460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e+%7.5e i ",(double)PetscRealPart(value),(double)PetscImaginaryPart(value));CHKERRQ(ierr); 72568f1ed48SBarry Smith } 72602594712SBarry Smith #else 72760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," %7.5e ",(double)value);CHKERRQ(ierr); 72802594712SBarry Smith #endif 72902594712SBarry Smith } 730b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 73102594712SBarry Smith } 732d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7333c215bfdSMatthew Knepley } else if (format == PETSC_VIEWER_ASCII_MATRIXMARKET) { 734150b93efSMatthew G. Knepley PetscInt fshift=1; 735d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 7363c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 73719303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate complex general\n");CHKERRQ(ierr); 7383c215bfdSMatthew Knepley #else 73919303e72SJonathan Guyer ierr = PetscViewerASCIIPrintf(viewer,"%%%%MatrixMarket matrix coordinate real general\n");CHKERRQ(ierr); 7403c215bfdSMatthew Knepley #endif 741d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%D %D %D\n", m, A->cmap->n, a->nz);CHKERRQ(ierr); 7423c215bfdSMatthew Knepley for (i=0; i<m; i++) { 74360e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 7443c215bfdSMatthew Knepley #if defined(PETSC_USE_COMPLEX) 745a9a0e077SKarl Rupp ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g %g\n", i+fshift,a->j[j]+fshift,(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 7463c215bfdSMatthew Knepley #else 747150b93efSMatthew G. Knepley ierr = PetscViewerASCIIPrintf(viewer,"%D %D %g\n", i+fshift, a->j[j]+fshift, (double)a->a[j]);CHKERRQ(ierr); 7483c215bfdSMatthew Knepley #endif 7493c215bfdSMatthew Knepley } 7503c215bfdSMatthew Knepley } 751d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 7523a40ed3dSBarry Smith } else { 753d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 754d5f3da31SBarry Smith if (A->factortype) { 75516cd7e1dSShri Abhyankar for (i=0; i<m; i++) { 75616cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 75716cd7e1dSShri Abhyankar /* L part */ 75860e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 75916cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 76016cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 76160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 76216cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7636712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 76416cd7e1dSShri Abhyankar } else { 76560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 76616cd7e1dSShri Abhyankar } 76716cd7e1dSShri Abhyankar #else 76860e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 76916cd7e1dSShri Abhyankar #endif 77016cd7e1dSShri Abhyankar } 77116cd7e1dSShri Abhyankar /* diagonal */ 77216cd7e1dSShri Abhyankar j = a->diag[i]; 77316cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 77416cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 77560e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)PetscImaginaryPart(1.0/a->a[j]));CHKERRQ(ierr); 77616cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 7776712e2f1SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(1.0/a->a[j]),(double)(-PetscImaginaryPart(1.0/a->a[j])));CHKERRQ(ierr); 77816cd7e1dSShri Abhyankar } else { 77960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(1.0/a->a[j]));CHKERRQ(ierr); 78016cd7e1dSShri Abhyankar } 78116cd7e1dSShri Abhyankar #else 78260e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)(1.0/a->a[j]));CHKERRQ(ierr); 78316cd7e1dSShri Abhyankar #endif 78416cd7e1dSShri Abhyankar 78516cd7e1dSShri Abhyankar /* U part */ 78660e0710aSBarry Smith for (j=a->diag[i+1]+1; j<a->diag[i]; j++) { 78716cd7e1dSShri Abhyankar #if defined(PETSC_USE_COMPLEX) 78816cd7e1dSShri Abhyankar if (PetscImaginaryPart(a->a[j]) > 0.0) { 78960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 79016cd7e1dSShri Abhyankar } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 79122ab088eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)(-PetscImaginaryPart(a->a[j])));CHKERRQ(ierr); 79216cd7e1dSShri Abhyankar } else { 79360e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 79416cd7e1dSShri Abhyankar } 79516cd7e1dSShri Abhyankar #else 79660e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 79716cd7e1dSShri Abhyankar #endif 79816cd7e1dSShri Abhyankar } 79916cd7e1dSShri Abhyankar ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 80016cd7e1dSShri Abhyankar } 80116cd7e1dSShri Abhyankar } else { 80217ab2063SBarry Smith for (i=0; i<m; i++) { 80377431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 80460e0710aSBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 805aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 80636db0b34SBarry Smith if (PetscImaginaryPart(a->a[j]) > 0.0) { 80760e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 80836db0b34SBarry Smith } else if (PetscImaginaryPart(a->a[j]) < 0.0) { 80960e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g - %g i)",a->j[j],(double)PetscRealPart(a->a[j]),(double)-PetscImaginaryPart(a->a[j]));CHKERRQ(ierr); 8103a40ed3dSBarry Smith } else { 81160e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)PetscRealPart(a->a[j]));CHKERRQ(ierr); 81217ab2063SBarry Smith } 81317ab2063SBarry Smith #else 81460e0710aSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",a->j[j],(double)a->a[j]);CHKERRQ(ierr); 81517ab2063SBarry Smith #endif 81617ab2063SBarry Smith } 817b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 81817ab2063SBarry Smith } 81916cd7e1dSShri Abhyankar } 820d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 82117ab2063SBarry Smith } 822b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 8233a40ed3dSBarry Smith PetscFunctionReturn(0); 824416022c9SBarry Smith } 825416022c9SBarry Smith 8269804daf3SBarry Smith #include <petscdraw.h> 827dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw_Zoom(PetscDraw draw,void *Aa) 828416022c9SBarry Smith { 829480ef9eaSBarry Smith Mat A = (Mat) Aa; 830416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 831dfbe8321SBarry Smith PetscErrorCode ierr; 832383922c3SLisandro Dalcin PetscInt i,j,m = A->rmap->n; 833383922c3SLisandro Dalcin int color; 834b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 835b0a32e0cSBarry Smith PetscViewer viewer; 836f3ef73ceSBarry Smith PetscViewerFormat format; 837cddf8d76SBarry Smith 8383a40ed3dSBarry Smith PetscFunctionBegin; 839480ef9eaSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 840b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 841b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 842383922c3SLisandro Dalcin 843416022c9SBarry Smith /* loop over matrix elements drawing boxes */ 8440513a670SBarry Smith 845fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 846383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8470513a670SBarry Smith /* Blue for negative, Cyan for zero and Red for positive */ 848b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 849416022c9SBarry Smith for (i=0; i<m; i++) { 850cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 851bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 852bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 85336db0b34SBarry Smith if (PetscRealPart(a->a[j]) >= 0.) continue; 854b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 855cddf8d76SBarry Smith } 856cddf8d76SBarry Smith } 857b0a32e0cSBarry Smith color = PETSC_DRAW_CYAN; 858cddf8d76SBarry Smith for (i=0; i<m; i++) { 859cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 860bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 861bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 862cddf8d76SBarry Smith if (a->a[j] != 0.) continue; 863b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 864cddf8d76SBarry Smith } 865cddf8d76SBarry Smith } 866b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 867cddf8d76SBarry Smith for (i=0; i<m; i++) { 868cddf8d76SBarry Smith y_l = m - i - 1.0; y_r = y_l + 1.0; 869bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 870bfeeae90SHong Zhang x_l = a->j[j]; x_r = x_l + 1.0; 87136db0b34SBarry Smith if (PetscRealPart(a->a[j]) <= 0.) continue; 872b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 873416022c9SBarry Smith } 874416022c9SBarry Smith } 875383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 8760513a670SBarry Smith } else { 8770513a670SBarry Smith /* use contour shading to indicate magnitude of values */ 8780513a670SBarry Smith /* first determine max of all nonzero values */ 879b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 880383922c3SLisandro Dalcin PetscInt nz = a->nz, count = 0; 881b0a32e0cSBarry Smith PetscDraw popup; 8820513a670SBarry Smith 8830513a670SBarry Smith for (i=0; i<nz; i++) { 8840513a670SBarry Smith if (PetscAbsScalar(a->a[i]) > maxv) maxv = PetscAbsScalar(a->a[i]); 8850513a670SBarry Smith } 886383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 887b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 88845f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 889383922c3SLisandro Dalcin 890383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 8910513a670SBarry Smith for (i=0; i<m; i++) { 892383922c3SLisandro Dalcin y_l = m - i - 1.0; 893383922c3SLisandro Dalcin y_r = y_l + 1.0; 894bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 895383922c3SLisandro Dalcin x_l = a->j[j]; 896383922c3SLisandro Dalcin x_r = x_l + 1.0; 897b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(a->a[count]),minv,maxv); 898b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 8990513a670SBarry Smith count++; 9000513a670SBarry Smith } 9010513a670SBarry Smith } 902383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 9030513a670SBarry Smith } 904480ef9eaSBarry Smith PetscFunctionReturn(0); 905480ef9eaSBarry Smith } 906cddf8d76SBarry Smith 9079804daf3SBarry Smith #include <petscdraw.h> 908dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ_Draw(Mat A,PetscViewer viewer) 909480ef9eaSBarry Smith { 910dfbe8321SBarry Smith PetscErrorCode ierr; 911b0a32e0cSBarry Smith PetscDraw draw; 91236db0b34SBarry Smith PetscReal xr,yr,xl,yl,h,w; 913ace3abfcSBarry Smith PetscBool isnull; 914480ef9eaSBarry Smith 915480ef9eaSBarry Smith PetscFunctionBegin; 916b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 917b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 918480ef9eaSBarry Smith if (isnull) PetscFunctionReturn(0); 919480ef9eaSBarry Smith 920d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 921480ef9eaSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 922b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 923832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 924b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqAIJ_Draw_Zoom,A);CHKERRQ(ierr); 9250298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 926832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 9273a40ed3dSBarry Smith PetscFunctionReturn(0); 928416022c9SBarry Smith } 929416022c9SBarry Smith 930dfbe8321SBarry Smith PetscErrorCode MatView_SeqAIJ(Mat A,PetscViewer viewer) 931416022c9SBarry Smith { 932dfbe8321SBarry Smith PetscErrorCode ierr; 933ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 934416022c9SBarry Smith 9353a40ed3dSBarry Smith PetscFunctionBegin; 936251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 937251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 938251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 939c45a1595SBarry Smith if (iascii) { 9403a40ed3dSBarry Smith ierr = MatView_SeqAIJ_ASCII(A,viewer);CHKERRQ(ierr); 9410f5bd95cSBarry Smith } else if (isbinary) { 9423a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Binary(A,viewer);CHKERRQ(ierr); 9430f5bd95cSBarry Smith } else if (isdraw) { 9443a40ed3dSBarry Smith ierr = MatView_SeqAIJ_Draw(A,viewer);CHKERRQ(ierr); 94511aeaf0aSBarry Smith } 9464108e4d5SBarry Smith ierr = MatView_SeqAIJ_Inode(A,viewer);CHKERRQ(ierr); 9473a40ed3dSBarry Smith PetscFunctionReturn(0); 94817ab2063SBarry Smith } 94919bcc07fSBarry Smith 950dfbe8321SBarry Smith PetscErrorCode MatAssemblyEnd_SeqAIJ(Mat A,MatAssemblyType mode) 95117ab2063SBarry Smith { 952416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 9536849ba73SBarry Smith PetscErrorCode ierr; 95497f1f81fSBarry Smith PetscInt fshift = 0,i,j,*ai = a->i,*aj = a->j,*imax = a->imax; 955d0f46423SBarry Smith PetscInt m = A->rmap->n,*ip,N,*ailen = a->ilen,rmax = 0; 95654f21887SBarry Smith MatScalar *aa = a->a,*ap; 9573447b6efSHong Zhang PetscReal ratio = 0.6; 95817ab2063SBarry Smith 9593a40ed3dSBarry Smith PetscFunctionBegin; 9603a40ed3dSBarry Smith if (mode == MAT_FLUSH_ASSEMBLY) PetscFunctionReturn(0); 96117ab2063SBarry Smith 96243ee02c3SBarry Smith if (m) rmax = ailen[0]; /* determine row with most nonzeros */ 96317ab2063SBarry Smith for (i=1; i<m; i++) { 964416022c9SBarry Smith /* move each row back by the amount of empty slots (fshift) before it*/ 96517ab2063SBarry Smith fshift += imax[i-1] - ailen[i-1]; 96694a9d846SBarry Smith rmax = PetscMax(rmax,ailen[i]); 96717ab2063SBarry Smith if (fshift) { 968bfeeae90SHong Zhang ip = aj + ai[i]; 969bfeeae90SHong Zhang ap = aa + ai[i]; 97017ab2063SBarry Smith N = ailen[i]; 97117ab2063SBarry Smith for (j=0; j<N; j++) { 97217ab2063SBarry Smith ip[j-fshift] = ip[j]; 97317ab2063SBarry Smith ap[j-fshift] = ap[j]; 97417ab2063SBarry Smith } 97517ab2063SBarry Smith } 97617ab2063SBarry Smith ai[i] = ai[i-1] + ailen[i-1]; 97717ab2063SBarry Smith } 97817ab2063SBarry Smith if (m) { 97917ab2063SBarry Smith fshift += imax[m-1] - ailen[m-1]; 98017ab2063SBarry Smith ai[m] = ai[m-1] + ailen[m-1]; 98117ab2063SBarry Smith } 9827b083b7cSBarry Smith 98317ab2063SBarry Smith /* reset ilen and imax for each row */ 9847b083b7cSBarry Smith a->nonzerorowcnt = 0; 98517ab2063SBarry Smith for (i=0; i<m; i++) { 98617ab2063SBarry Smith ailen[i] = imax[i] = ai[i+1] - ai[i]; 9877b083b7cSBarry Smith a->nonzerorowcnt += ((ai[i+1] - ai[i]) > 0); 98817ab2063SBarry Smith } 989bfeeae90SHong Zhang a->nz = ai[m]; 99065e19b50SBarry 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); 99117ab2063SBarry Smith 99209f38230SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 993d0f46423SBarry 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); 994ae15b995SBarry Smith ierr = PetscInfo1(A,"Number of mallocs during MatSetValues() is %D\n",a->reallocs);CHKERRQ(ierr); 995ae15b995SBarry Smith ierr = PetscInfo1(A,"Maximum nonzeros in any row is %D\n",rmax);CHKERRQ(ierr); 9962205254eSKarl Rupp 9978e58a170SBarry Smith A->info.mallocs += a->reallocs; 998dd5f02e7SSatish Balay a->reallocs = 0; 9996712e2f1SBarry Smith A->info.nz_unneeded = (PetscReal)fshift; 100036db0b34SBarry Smith a->rmax = rmax; 10014e220ebcSLois Curfman McInnes 100211e456e1SBarry Smith ierr = MatCheckCompressedRow(A,a->nonzerorowcnt,&a->compressedrow,a->i,m,ratio);CHKERRQ(ierr); 10034108e4d5SBarry Smith ierr = MatAssemblyEnd_SeqAIJ_Inode(A,mode);CHKERRQ(ierr); 1004acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10053a40ed3dSBarry Smith PetscFunctionReturn(0); 100617ab2063SBarry Smith } 100717ab2063SBarry Smith 100899cafbc1SBarry Smith PetscErrorCode MatRealPart_SeqAIJ(Mat A) 100999cafbc1SBarry Smith { 101099cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 101199cafbc1SBarry Smith PetscInt i,nz = a->nz; 101254f21887SBarry Smith MatScalar *aa = a->a; 1013acf2f550SJed Brown PetscErrorCode ierr; 101499cafbc1SBarry Smith 101599cafbc1SBarry Smith PetscFunctionBegin; 101699cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1017acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 101899cafbc1SBarry Smith PetscFunctionReturn(0); 101999cafbc1SBarry Smith } 102099cafbc1SBarry Smith 102199cafbc1SBarry Smith PetscErrorCode MatImaginaryPart_SeqAIJ(Mat A) 102299cafbc1SBarry Smith { 102399cafbc1SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 102499cafbc1SBarry Smith PetscInt i,nz = a->nz; 102554f21887SBarry Smith MatScalar *aa = a->a; 1026acf2f550SJed Brown PetscErrorCode ierr; 102799cafbc1SBarry Smith 102899cafbc1SBarry Smith PetscFunctionBegin; 102999cafbc1SBarry Smith for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1030acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 103199cafbc1SBarry Smith PetscFunctionReturn(0); 103299cafbc1SBarry Smith } 103399cafbc1SBarry Smith 1034dfbe8321SBarry Smith PetscErrorCode MatZeroEntries_SeqAIJ(Mat A) 103517ab2063SBarry Smith { 1036416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1037dfbe8321SBarry Smith PetscErrorCode ierr; 10383a40ed3dSBarry Smith 10393a40ed3dSBarry Smith PetscFunctionBegin; 1040d0f46423SBarry Smith ierr = PetscMemzero(a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 1041acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 10423a40ed3dSBarry Smith PetscFunctionReturn(0); 104317ab2063SBarry Smith } 1044416022c9SBarry Smith 1045dfbe8321SBarry Smith PetscErrorCode MatDestroy_SeqAIJ(Mat A) 104617ab2063SBarry Smith { 1047416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1048dfbe8321SBarry Smith PetscErrorCode ierr; 1049d5d45c9bSBarry Smith 10503a40ed3dSBarry Smith PetscFunctionBegin; 1051aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1052d0f46423SBarry Smith PetscLogObjectState((PetscObject)A,"Rows=%D, Cols=%D, NZ=%D",A->rmap->n,A->cmap->n,a->nz); 105317ab2063SBarry Smith #endif 1054e6b907acSBarry Smith ierr = MatSeqXAIJFreeAIJ(A,&a->a,&a->j,&a->i);CHKERRQ(ierr); 10556bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 10566bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 105705b42c5fSBarry Smith ierr = PetscFree(a->diag);CHKERRQ(ierr); 1058d48dcb14SBarry Smith ierr = PetscFree(a->ibdiag);CHKERRQ(ierr); 105905b42c5fSBarry Smith ierr = PetscFree2(a->imax,a->ilen);CHKERRQ(ierr); 106071f1c65dSBarry Smith ierr = PetscFree3(a->idiag,a->mdiag,a->ssor_work);CHKERRQ(ierr); 106105b42c5fSBarry Smith ierr = PetscFree(a->solve_work);CHKERRQ(ierr); 10626bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 106305b42c5fSBarry Smith ierr = PetscFree(a->saved_values);CHKERRQ(ierr); 10646bf464f9SBarry Smith ierr = ISColoringDestroy(&a->coloring);CHKERRQ(ierr); 1065cd6b891eSBarry Smith ierr = PetscFree2(a->compressedrow.i,a->compressedrow.rindex);CHKERRQ(ierr); 10660b7e3e3dSHong Zhang ierr = PetscFree(a->matmult_abdense);CHKERRQ(ierr); 1067a30b2313SHong Zhang 10684108e4d5SBarry Smith ierr = MatDestroy_SeqAIJ_Inode(A);CHKERRQ(ierr); 1069bf0cc555SLisandro Dalcin ierr = PetscFree(A->data);CHKERRQ(ierr); 1070901853e0SKris Buschelman 1071dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)A,0);CHKERRQ(ierr); 1072bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetColumnIndices_C",NULL);CHKERRQ(ierr); 1073bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatStoreValues_C",NULL);CHKERRQ(ierr); 1074bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatRetrieveValues_C",NULL);CHKERRQ(ierr); 1075bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqsbaij_C",NULL);CHKERRQ(ierr); 1076bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqbaij_C",NULL);CHKERRQ(ierr); 1077bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqaijperm_C",NULL);CHKERRQ(ierr); 1078af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 1079af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_elemental_C",NULL);CHKERRQ(ierr); 1080af8000cdSHong Zhang #endif 108163c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 108263c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_hypre_C",NULL);CHKERRQ(ierr); 10833dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatMatMatMult_transpose_seqaij_seqaij_C",NULL);CHKERRQ(ierr); 108463c07aadSStefano Zampini #endif 1085b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)A,"MatConvert_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1086bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatIsTranspose_C",NULL);CHKERRQ(ierr); 1087bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocation_C",NULL);CHKERRQ(ierr); 1088bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatSeqAIJSetPreallocationCSR_C",NULL);CHKERRQ(ierr); 1089bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)A,"MatReorderForNonzeroDiagonal_C",NULL);CHKERRQ(ierr); 10903a40ed3dSBarry Smith PetscFunctionReturn(0); 109117ab2063SBarry Smith } 109217ab2063SBarry Smith 1093ace3abfcSBarry Smith PetscErrorCode MatSetOption_SeqAIJ(Mat A,MatOption op,PetscBool flg) 109417ab2063SBarry Smith { 1095416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 10964846f1f5SKris Buschelman PetscErrorCode ierr; 10973a40ed3dSBarry Smith 10983a40ed3dSBarry Smith PetscFunctionBegin; 1099a65d3064SKris Buschelman switch (op) { 1100a65d3064SKris Buschelman case MAT_ROW_ORIENTED: 11014e0d8c25SBarry Smith a->roworiented = flg; 1102a65d3064SKris Buschelman break; 1103a9817697SBarry Smith case MAT_KEEP_NONZERO_PATTERN: 1104a9817697SBarry Smith a->keepnonzeropattern = flg; 1105a65d3064SKris Buschelman break; 1106512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1107512a5fc5SBarry Smith a->nonew = (flg ? 0 : 1); 1108a65d3064SKris Buschelman break; 1109a65d3064SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 11104e0d8c25SBarry Smith a->nonew = (flg ? -1 : 0); 1111a65d3064SKris Buschelman break; 1112a65d3064SKris Buschelman case MAT_NEW_NONZERO_ALLOCATION_ERR: 11134e0d8c25SBarry Smith a->nonew = (flg ? -2 : 0); 1114a65d3064SKris Buschelman break; 111528b2fa4aSMatthew Knepley case MAT_UNUSED_NONZERO_LOCATION_ERR: 111628b2fa4aSMatthew Knepley a->nounused = (flg ? -1 : 0); 111728b2fa4aSMatthew Knepley break; 1118a65d3064SKris Buschelman case MAT_IGNORE_ZERO_ENTRIES: 11194e0d8c25SBarry Smith a->ignorezeroentries = flg; 11200df259c2SBarry Smith break; 11213d472b54SHong Zhang case MAT_SPD: 1122b1646e73SJed Brown case MAT_SYMMETRIC: 1123b1646e73SJed Brown case MAT_STRUCTURALLY_SYMMETRIC: 1124b1646e73SJed Brown case MAT_HERMITIAN: 1125b1646e73SJed Brown case MAT_SYMMETRY_ETERNAL: 1126957cac9fSHong Zhang case MAT_STRUCTURE_ONLY: 11275021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 11285021d80fSJed Brown break; 11294e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 1130a65d3064SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1131a65d3064SKris Buschelman case MAT_USE_HASH_TABLE: 1132290bbb0aSBarry Smith ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 1133a65d3064SKris Buschelman break; 1134b87ac2d8SJed Brown case MAT_USE_INODES: 1135b87ac2d8SJed Brown /* Not an error because MatSetOption_SeqAIJ_Inode handles this one */ 1136b87ac2d8SJed Brown break; 1137c10200c1SHong Zhang case MAT_SUBMAT_SINGLEIS: 1138c10200c1SHong Zhang A->submat_singleis = flg; 1139c10200c1SHong Zhang break; 1140a65d3064SKris Buschelman default: 1141e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %d",op); 1142a65d3064SKris Buschelman } 11434108e4d5SBarry Smith ierr = MatSetOption_SeqAIJ_Inode(A,op,flg);CHKERRQ(ierr); 11443a40ed3dSBarry Smith PetscFunctionReturn(0); 114517ab2063SBarry Smith } 114617ab2063SBarry Smith 1147dfbe8321SBarry Smith PetscErrorCode MatGetDiagonal_SeqAIJ(Mat A,Vec v) 114817ab2063SBarry Smith { 1149416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 11506849ba73SBarry Smith PetscErrorCode ierr; 1151d3e70bfaSHong Zhang PetscInt i,j,n,*ai=a->i,*aj=a->j,nz; 115235e7444dSHong Zhang PetscScalar *aa=a->a,*x,zero=0.0; 115317ab2063SBarry Smith 11543a40ed3dSBarry Smith PetscFunctionBegin; 1155d3e70bfaSHong Zhang ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 1156e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 115735e7444dSHong Zhang 1158d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_ILU || A->factortype == MAT_FACTOR_LU) { 1159d3e70bfaSHong Zhang PetscInt *diag=a->diag; 116035e7444dSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 11612c990fa1SHong Zhang for (i=0; i<n; i++) x[i] = 1.0/aa[diag[i]]; 116235e7444dSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 116335e7444dSHong Zhang PetscFunctionReturn(0); 116435e7444dSHong Zhang } 116535e7444dSHong Zhang 11662dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 11671ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 116835e7444dSHong Zhang for (i=0; i<n; i++) { 116935e7444dSHong Zhang nz = ai[i+1] - ai[i]; 11702f5a7c2eSBarry Smith if (!nz) x[i] = 0.0; 117135e7444dSHong Zhang for (j=ai[i]; j<ai[i+1]; j++) { 117235e7444dSHong Zhang if (aj[j] == i) { 117335e7444dSHong Zhang x[i] = aa[j]; 117417ab2063SBarry Smith break; 117517ab2063SBarry Smith } 117617ab2063SBarry Smith } 117717ab2063SBarry Smith } 11781ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 11793a40ed3dSBarry Smith PetscFunctionReturn(0); 118017ab2063SBarry Smith } 118117ab2063SBarry Smith 1182c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 1183dfbe8321SBarry Smith PetscErrorCode MatMultTransposeAdd_SeqAIJ(Mat A,Vec xx,Vec zz,Vec yy) 118417ab2063SBarry Smith { 1185416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1186d9ca1df4SBarry Smith PetscScalar *y; 1187d9ca1df4SBarry Smith const PetscScalar *x; 1188dfbe8321SBarry Smith PetscErrorCode ierr; 1189d0f46423SBarry Smith PetscInt m = A->rmap->n; 11905c897100SBarry Smith #if !defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1191d9ca1df4SBarry Smith const MatScalar *v; 1192a77337e4SBarry Smith PetscScalar alpha; 1193d9ca1df4SBarry Smith PetscInt n,i,j; 1194d9ca1df4SBarry Smith const PetscInt *idx,*ii,*ridx=NULL; 11953447b6efSHong Zhang Mat_CompressedRow cprow = a->compressedrow; 1196ace3abfcSBarry Smith PetscBool usecprow = cprow.use; 11975c897100SBarry Smith #endif 119817ab2063SBarry Smith 11993a40ed3dSBarry Smith PetscFunctionBegin; 12002e8a6d31SBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 1201d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12021ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 12035c897100SBarry Smith 12045c897100SBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTTRANSPOSEAIJ) 1205bfeeae90SHong Zhang fortranmulttransposeaddaij_(&m,x,a->i,a->j,a->a,y); 12065c897100SBarry Smith #else 12073447b6efSHong Zhang if (usecprow) { 12083447b6efSHong Zhang m = cprow.nrows; 12093447b6efSHong Zhang ii = cprow.i; 12107b2bb3b9SHong Zhang ridx = cprow.rindex; 12113447b6efSHong Zhang } else { 12123447b6efSHong Zhang ii = a->i; 12133447b6efSHong Zhang } 121417ab2063SBarry Smith for (i=0; i<m; i++) { 12153447b6efSHong Zhang idx = a->j + ii[i]; 12163447b6efSHong Zhang v = a->a + ii[i]; 12173447b6efSHong Zhang n = ii[i+1] - ii[i]; 12183447b6efSHong Zhang if (usecprow) { 12197b2bb3b9SHong Zhang alpha = x[ridx[i]]; 12203447b6efSHong Zhang } else { 122117ab2063SBarry Smith alpha = x[i]; 12223447b6efSHong Zhang } 122304fbf559SBarry Smith for (j=0; j<n; j++) y[idx[j]] += alpha*v[j]; 122417ab2063SBarry Smith } 12255c897100SBarry Smith #endif 1226dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1227d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12281ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12293a40ed3dSBarry Smith PetscFunctionReturn(0); 123017ab2063SBarry Smith } 123117ab2063SBarry Smith 1232dfbe8321SBarry Smith PetscErrorCode MatMultTranspose_SeqAIJ(Mat A,Vec xx,Vec yy) 12335c897100SBarry Smith { 1234dfbe8321SBarry Smith PetscErrorCode ierr; 12355c897100SBarry Smith 12365c897100SBarry Smith PetscFunctionBegin; 1237170fe5c8SBarry Smith ierr = VecSet(yy,0.0);CHKERRQ(ierr); 12385c897100SBarry Smith ierr = MatMultTransposeAdd_SeqAIJ(A,xx,yy,yy);CHKERRQ(ierr); 12395c897100SBarry Smith PetscFunctionReturn(0); 12405c897100SBarry Smith } 12415c897100SBarry Smith 1242c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmult.h> 124378b84d54SShri Abhyankar 1244dfbe8321SBarry Smith PetscErrorCode MatMult_SeqAIJ(Mat A,Vec xx,Vec yy) 124517ab2063SBarry Smith { 1246416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1247d9fead3dSBarry Smith PetscScalar *y; 124854f21887SBarry Smith const PetscScalar *x; 124954f21887SBarry Smith const MatScalar *aa; 1250dfbe8321SBarry Smith PetscErrorCode ierr; 1251003131ecSBarry Smith PetscInt m=A->rmap->n; 12520298fd71SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 12537b083b7cSBarry Smith PetscInt n,i; 1254362ced78SSatish Balay PetscScalar sum; 1255ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 125617ab2063SBarry Smith 1257b6410449SSatish Balay #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 125897952fefSHong Zhang #pragma disjoint(*x,*y,*aa) 1259fee21e36SBarry Smith #endif 1260fee21e36SBarry Smith 12613a40ed3dSBarry Smith PetscFunctionBegin; 12623649974fSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 12631ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1264416022c9SBarry Smith ii = a->i; 12654eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 12664f390cb1SBarry Smith ierr = PetscMemzero(y,m*sizeof(PetscScalar));CHKERRQ(ierr); 126797952fefSHong Zhang m = a->compressedrow.nrows; 126897952fefSHong Zhang ii = a->compressedrow.i; 126997952fefSHong Zhang ridx = a->compressedrow.rindex; 127097952fefSHong Zhang for (i=0; i<m; i++) { 127197952fefSHong Zhang n = ii[i+1] - ii[i]; 127297952fefSHong Zhang aj = a->j + ii[i]; 127397952fefSHong Zhang aa = a->a + ii[i]; 127497952fefSHong Zhang sum = 0.0; 1275003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 1276003131ecSBarry Smith /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 127797952fefSHong Zhang y[*ridx++] = sum; 127897952fefSHong Zhang } 127997952fefSHong Zhang } else { /* do not use compressed row format */ 1280b05257ddSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTAIJ) 12813d3eaba7SBarry Smith aj = a->j; 12823d3eaba7SBarry Smith aa = a->a; 1283b05257ddSBarry Smith fortranmultaij_(&m,x,ii,aj,aa,y); 1284b05257ddSBarry Smith #else 128517ab2063SBarry Smith for (i=0; i<m; i++) { 1286003131ecSBarry Smith n = ii[i+1] - ii[i]; 1287003131ecSBarry Smith aj = a->j + ii[i]; 1288003131ecSBarry Smith aa = a->a + ii[i]; 128917ab2063SBarry Smith sum = 0.0; 1290003131ecSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 129117ab2063SBarry Smith y[i] = sum; 129217ab2063SBarry Smith } 12938d195f9aSBarry Smith #endif 1294b05257ddSBarry Smith } 12957b083b7cSBarry Smith ierr = PetscLogFlops(2.0*a->nz - a->nonzerorowcnt);CHKERRQ(ierr); 12963649974fSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 12971ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 12983a40ed3dSBarry Smith PetscFunctionReturn(0); 129917ab2063SBarry Smith } 130017ab2063SBarry Smith 1301b434eb95SMatthew G. Knepley PetscErrorCode MatMultMax_SeqAIJ(Mat A,Vec xx,Vec yy) 1302b434eb95SMatthew G. Knepley { 1303b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1304b434eb95SMatthew G. Knepley PetscScalar *y; 1305b434eb95SMatthew G. Knepley const PetscScalar *x; 1306b434eb95SMatthew G. Knepley const MatScalar *aa; 1307b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1308b434eb95SMatthew G. Knepley PetscInt m=A->rmap->n; 1309b434eb95SMatthew G. Knepley const PetscInt *aj,*ii,*ridx=NULL; 1310b434eb95SMatthew G. Knepley PetscInt n,i,nonzerorow=0; 1311b434eb95SMatthew G. Knepley PetscScalar sum; 1312b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1313b434eb95SMatthew G. Knepley 1314b434eb95SMatthew G. Knepley #if defined(PETSC_HAVE_PRAGMA_DISJOINT) 1315b434eb95SMatthew G. Knepley #pragma disjoint(*x,*y,*aa) 1316b434eb95SMatthew G. Knepley #endif 1317b434eb95SMatthew G. Knepley 1318b434eb95SMatthew G. Knepley PetscFunctionBegin; 1319b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1320b434eb95SMatthew G. Knepley ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 1321b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1322b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1323b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1324b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1325b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1326b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1327b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1328b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1329b434eb95SMatthew G. Knepley sum = 0.0; 1330b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1331b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1332b434eb95SMatthew G. Knepley /* for (j=0; j<n; j++) sum += (*aa++)*x[*aj++]; */ 1333b434eb95SMatthew G. Knepley y[*ridx++] = sum; 1334b434eb95SMatthew G. Knepley } 1335b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13363d3eaba7SBarry Smith ii = a->i; 1337b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1338b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1339b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1340b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1341b434eb95SMatthew G. Knepley sum = 0.0; 1342b434eb95SMatthew G. Knepley nonzerorow += (n>0); 1343b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1344b434eb95SMatthew G. Knepley y[i] = sum; 1345b434eb95SMatthew G. Knepley } 1346b434eb95SMatthew G. Knepley } 1347b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz - nonzerorow);CHKERRQ(ierr); 1348b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1349b434eb95SMatthew G. Knepley ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 1350b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1351b434eb95SMatthew G. Knepley } 1352b434eb95SMatthew G. Knepley 1353b434eb95SMatthew G. Knepley PetscErrorCode MatMultAddMax_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 1354b434eb95SMatthew G. Knepley { 1355b434eb95SMatthew G. Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1356b434eb95SMatthew G. Knepley PetscScalar *y,*z; 1357b434eb95SMatthew G. Knepley const PetscScalar *x; 1358b434eb95SMatthew G. Knepley const MatScalar *aa; 1359b434eb95SMatthew G. Knepley PetscErrorCode ierr; 1360b434eb95SMatthew G. Knepley PetscInt m = A->rmap->n,*aj,*ii; 1361b434eb95SMatthew G. Knepley PetscInt n,i,*ridx=NULL; 1362b434eb95SMatthew G. Knepley PetscScalar sum; 1363b434eb95SMatthew G. Knepley PetscBool usecprow=a->compressedrow.use; 1364b434eb95SMatthew G. Knepley 1365b434eb95SMatthew G. Knepley PetscFunctionBegin; 1366b434eb95SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1367d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1368b434eb95SMatthew G. Knepley if (usecprow) { /* use compressed row format */ 1369b434eb95SMatthew G. Knepley if (zz != yy) { 1370b434eb95SMatthew G. Knepley ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 1371b434eb95SMatthew G. Knepley } 1372b434eb95SMatthew G. Knepley m = a->compressedrow.nrows; 1373b434eb95SMatthew G. Knepley ii = a->compressedrow.i; 1374b434eb95SMatthew G. Knepley ridx = a->compressedrow.rindex; 1375b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1376b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1377b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1378b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1379b434eb95SMatthew G. Knepley sum = y[*ridx]; 1380b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1381b434eb95SMatthew G. Knepley z[*ridx++] = sum; 1382b434eb95SMatthew G. Knepley } 1383b434eb95SMatthew G. Knepley } else { /* do not use compressed row format */ 13843d3eaba7SBarry Smith ii = a->i; 1385b434eb95SMatthew G. Knepley for (i=0; i<m; i++) { 1386b434eb95SMatthew G. Knepley n = ii[i+1] - ii[i]; 1387b434eb95SMatthew G. Knepley aj = a->j + ii[i]; 1388b434eb95SMatthew G. Knepley aa = a->a + ii[i]; 1389b434eb95SMatthew G. Knepley sum = y[i]; 1390b434eb95SMatthew G. Knepley PetscSparseDenseMaxDot(sum,x,aa,aj,n); 1391b434eb95SMatthew G. Knepley z[i] = sum; 1392b434eb95SMatthew G. Knepley } 1393b434eb95SMatthew G. Knepley } 1394b434eb95SMatthew G. Knepley ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1395b434eb95SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1396d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 1397b434eb95SMatthew G. Knepley PetscFunctionReturn(0); 1398b434eb95SMatthew G. Knepley } 1399b434eb95SMatthew G. Knepley 1400c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/fmultadd.h> 1401dfbe8321SBarry Smith PetscErrorCode MatMultAdd_SeqAIJ(Mat A,Vec xx,Vec yy,Vec zz) 140217ab2063SBarry Smith { 1403416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1404f15663dcSBarry Smith PetscScalar *y,*z; 1405f15663dcSBarry Smith const PetscScalar *x; 140654f21887SBarry Smith const MatScalar *aa; 1407dfbe8321SBarry Smith PetscErrorCode ierr; 1408d9ca1df4SBarry Smith const PetscInt *aj,*ii,*ridx=NULL; 1409d9ca1df4SBarry Smith PetscInt m = A->rmap->n,n,i; 1410362ced78SSatish Balay PetscScalar sum; 1411ace3abfcSBarry Smith PetscBool usecprow=a->compressedrow.use; 14129ea0dfa2SSatish Balay 14133a40ed3dSBarry Smith PetscFunctionBegin; 1414f15663dcSBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 1415d9ca1df4SBarry Smith ierr = VecGetArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14164eb6d288SHong Zhang if (usecprow) { /* use compressed row format */ 14174eb6d288SHong Zhang if (zz != yy) { 14184eb6d288SHong Zhang ierr = PetscMemcpy(z,y,m*sizeof(PetscScalar));CHKERRQ(ierr); 14194eb6d288SHong Zhang } 142097952fefSHong Zhang m = a->compressedrow.nrows; 142197952fefSHong Zhang ii = a->compressedrow.i; 142297952fefSHong Zhang ridx = a->compressedrow.rindex; 142397952fefSHong Zhang for (i=0; i<m; i++) { 142497952fefSHong Zhang n = ii[i+1] - ii[i]; 142597952fefSHong Zhang aj = a->j + ii[i]; 142697952fefSHong Zhang aa = a->a + ii[i]; 142797952fefSHong Zhang sum = y[*ridx]; 1428f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 142997952fefSHong Zhang z[*ridx++] = sum; 143097952fefSHong Zhang } 143197952fefSHong Zhang } else { /* do not use compressed row format */ 14323d3eaba7SBarry Smith ii = a->i; 1433f15663dcSBarry Smith #if defined(PETSC_USE_FORTRAN_KERNEL_MULTADDAIJ) 14343d3eaba7SBarry Smith aj = a->j; 14353d3eaba7SBarry Smith aa = a->a; 1436f15663dcSBarry Smith fortranmultaddaij_(&m,x,ii,aj,aa,y,z); 1437f15663dcSBarry Smith #else 143817ab2063SBarry Smith for (i=0; i<m; i++) { 1439f15663dcSBarry Smith n = ii[i+1] - ii[i]; 1440f15663dcSBarry Smith aj = a->j + ii[i]; 1441f15663dcSBarry Smith aa = a->a + ii[i]; 144217ab2063SBarry Smith sum = y[i]; 1443f15663dcSBarry Smith PetscSparseDensePlusDot(sum,x,aa,aj,n); 144417ab2063SBarry Smith z[i] = sum; 144517ab2063SBarry Smith } 144602ab625aSSatish Balay #endif 1447f15663dcSBarry Smith } 1448dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1449f15663dcSBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 1450d9ca1df4SBarry Smith ierr = VecRestoreArrayPair(yy,zz,&y,&z);CHKERRQ(ierr); 14518154be41SBarry Smith #if defined(PETSC_HAVE_CUSP) 14526b375ea7SVictor Minden /* 1453918e98c3SVictor Minden ierr = VecView(xx,0);CHKERRQ(ierr); 1454918e98c3SVictor Minden ierr = VecView(zz,0);CHKERRQ(ierr); 1455918e98c3SVictor Minden ierr = MatView(A,0);CHKERRQ(ierr); 14566b375ea7SVictor Minden */ 1457918e98c3SVictor Minden #endif 14583a40ed3dSBarry Smith PetscFunctionReturn(0); 145917ab2063SBarry Smith } 146017ab2063SBarry Smith 146117ab2063SBarry Smith /* 146217ab2063SBarry Smith Adds diagonal pointers to sparse matrix structure. 146317ab2063SBarry Smith */ 1464dfbe8321SBarry Smith PetscErrorCode MatMarkDiagonal_SeqAIJ(Mat A) 146517ab2063SBarry Smith { 1466416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14676849ba73SBarry Smith PetscErrorCode ierr; 1468d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n; 146917ab2063SBarry Smith 14703a40ed3dSBarry Smith PetscFunctionBegin; 147109f38230SBarry Smith if (!a->diag) { 1472785e854fSJed Brown ierr = PetscMalloc1(m,&a->diag);CHKERRQ(ierr); 14733bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, m*sizeof(PetscInt));CHKERRQ(ierr); 147409f38230SBarry Smith } 1475d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 147609f38230SBarry Smith a->diag[i] = a->i[i+1]; 1477bfeeae90SHong Zhang for (j=a->i[i]; j<a->i[i+1]; j++) { 1478bfeeae90SHong Zhang if (a->j[j] == i) { 147909f38230SBarry Smith a->diag[i] = j; 148017ab2063SBarry Smith break; 148117ab2063SBarry Smith } 148217ab2063SBarry Smith } 148317ab2063SBarry Smith } 14843a40ed3dSBarry Smith PetscFunctionReturn(0); 148517ab2063SBarry Smith } 148617ab2063SBarry Smith 1487be5855fcSBarry Smith /* 1488be5855fcSBarry Smith Checks for missing diagonals 1489be5855fcSBarry Smith */ 1490ace3abfcSBarry Smith PetscErrorCode MatMissingDiagonal_SeqAIJ(Mat A,PetscBool *missing,PetscInt *d) 1491be5855fcSBarry Smith { 1492be5855fcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 14937734d3b5SMatthew G. Knepley PetscInt *diag,*ii = a->i,i; 1494be5855fcSBarry Smith 1495be5855fcSBarry Smith PetscFunctionBegin; 149609f38230SBarry Smith *missing = PETSC_FALSE; 14977734d3b5SMatthew G. Knepley if (A->rmap->n > 0 && !ii) { 149809f38230SBarry Smith *missing = PETSC_TRUE; 149909f38230SBarry Smith if (d) *d = 0; 1500955c1f14SBarry Smith PetscInfo(A,"Matrix has no entries therefore is missing diagonal\n"); 150109f38230SBarry Smith } else { 1502f1e2ffcdSBarry Smith diag = a->diag; 1503d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 15047734d3b5SMatthew G. Knepley if (diag[i] >= ii[i+1]) { 150509f38230SBarry Smith *missing = PETSC_TRUE; 150609f38230SBarry Smith if (d) *d = i; 1507955c1f14SBarry Smith PetscInfo1(A,"Matrix is missing diagonal number %D\n",i); 1508358d2f5dSShri Abhyankar break; 150909f38230SBarry Smith } 1510be5855fcSBarry Smith } 1511be5855fcSBarry Smith } 1512be5855fcSBarry Smith PetscFunctionReturn(0); 1513be5855fcSBarry Smith } 1514be5855fcSBarry Smith 1515422a814eSBarry Smith /* 1516422a814eSBarry Smith Negative shift indicates do not generate an error if there is a zero diagonal, just invert it anyways 1517422a814eSBarry Smith */ 15187087cfbeSBarry Smith PetscErrorCode MatInvertDiagonal_SeqAIJ(Mat A,PetscScalar omega,PetscScalar fshift) 151971f1c65dSBarry Smith { 152071f1c65dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 152171f1c65dSBarry Smith PetscErrorCode ierr; 1522d0f46423SBarry Smith PetscInt i,*diag,m = A->rmap->n; 152354f21887SBarry Smith MatScalar *v = a->a; 152454f21887SBarry Smith PetscScalar *idiag,*mdiag; 152571f1c65dSBarry Smith 152671f1c65dSBarry Smith PetscFunctionBegin; 152771f1c65dSBarry Smith if (a->idiagvalid) PetscFunctionReturn(0); 152871f1c65dSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 152971f1c65dSBarry Smith diag = a->diag; 153071f1c65dSBarry Smith if (!a->idiag) { 1531dcca6d9dSJed Brown ierr = PetscMalloc3(m,&a->idiag,m,&a->mdiag,m,&a->ssor_work);CHKERRQ(ierr); 15323bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A, 3*m*sizeof(PetscScalar));CHKERRQ(ierr); 153371f1c65dSBarry Smith v = a->a; 153471f1c65dSBarry Smith } 153571f1c65dSBarry Smith mdiag = a->mdiag; 153671f1c65dSBarry Smith idiag = a->idiag; 153771f1c65dSBarry Smith 1538422a814eSBarry Smith if (omega == 1.0 && PetscRealPart(fshift) <= 0.0) { 153971f1c65dSBarry Smith for (i=0; i<m; i++) { 154071f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 1541899639b0SHong Zhang if (!PetscAbsScalar(mdiag[i])) { /* zero diagonal */ 1542899639b0SHong Zhang if (PetscRealPart(fshift)) { 1543899639b0SHong Zhang ierr = PetscInfo1(A,"Zero diagonal on row %D\n",i);CHKERRQ(ierr); 15447b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 15457b6c816cSBarry Smith A->factorerror_zeropivot_value = 0.0; 15467b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 15477b6c816cSBarry Smith } SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_INCOMP,"Zero diagonal on row %D",i); 1548899639b0SHong Zhang } 154971f1c65dSBarry Smith idiag[i] = 1.0/v[diag[i]]; 155071f1c65dSBarry Smith } 155171f1c65dSBarry Smith ierr = PetscLogFlops(m);CHKERRQ(ierr); 155271f1c65dSBarry Smith } else { 155371f1c65dSBarry Smith for (i=0; i<m; i++) { 155471f1c65dSBarry Smith mdiag[i] = v[diag[i]]; 155571f1c65dSBarry Smith idiag[i] = omega/(fshift + v[diag[i]]); 155671f1c65dSBarry Smith } 1557dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*m);CHKERRQ(ierr); 155871f1c65dSBarry Smith } 155971f1c65dSBarry Smith a->idiagvalid = PETSC_TRUE; 156071f1c65dSBarry Smith PetscFunctionReturn(0); 156171f1c65dSBarry Smith } 156271f1c65dSBarry Smith 1563c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/ftn-kernels/frelax.h> 156441f059aeSBarry Smith PetscErrorCode MatSOR_SeqAIJ(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal fshift,PetscInt its,PetscInt lits,Vec xx) 156517ab2063SBarry Smith { 1566416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1567e6d1f457SBarry Smith PetscScalar *x,d,sum,*t,scale; 15683d3eaba7SBarry Smith const MatScalar *v,*idiag=0,*mdiag; 156954f21887SBarry Smith const PetscScalar *b, *bs,*xb, *ts; 1570dfbe8321SBarry Smith PetscErrorCode ierr; 15713d3eaba7SBarry Smith PetscInt n,m = A->rmap->n,i; 157297f1f81fSBarry Smith const PetscInt *idx,*diag; 157317ab2063SBarry Smith 15743a40ed3dSBarry Smith PetscFunctionBegin; 1575b965ef7fSBarry Smith its = its*lits; 157691723122SBarry Smith 157771f1c65dSBarry Smith if (fshift != a->fshift || omega != a->omega) a->idiagvalid = PETSC_FALSE; /* must recompute idiag[] */ 157871f1c65dSBarry Smith if (!a->idiagvalid) {ierr = MatInvertDiagonal_SeqAIJ(A,omega,fshift);CHKERRQ(ierr);} 157971f1c65dSBarry Smith a->fshift = fshift; 158071f1c65dSBarry Smith a->omega = omega; 1581ed480e8bSBarry Smith 158271f1c65dSBarry Smith diag = a->diag; 158371f1c65dSBarry Smith t = a->ssor_work; 1584ed480e8bSBarry Smith idiag = a->idiag; 158571f1c65dSBarry Smith mdiag = a->mdiag; 1586ed480e8bSBarry Smith 15871ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 15883649974fSBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 1589ed480e8bSBarry Smith /* We count flops by assuming the upper triangular and lower triangular parts have the same number of nonzeros */ 159017ab2063SBarry Smith if (flag == SOR_APPLY_UPPER) { 159117ab2063SBarry Smith /* apply (U + D/omega) to the vector */ 1592ed480e8bSBarry Smith bs = b; 159317ab2063SBarry Smith for (i=0; i<m; i++) { 159471f1c65dSBarry Smith d = fshift + mdiag[i]; 1595416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1596ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1597ed480e8bSBarry Smith v = a->a + diag[i] + 1; 159817ab2063SBarry Smith sum = b[i]*d/omega; 1599003131ecSBarry Smith PetscSparseDensePlusDot(sum,bs,v,idx,n); 160017ab2063SBarry Smith x[i] = sum; 160117ab2063SBarry Smith } 16021ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16033649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1604efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16053a40ed3dSBarry Smith PetscFunctionReturn(0); 160617ab2063SBarry Smith } 1607c783ea89SBarry Smith 16082205254eSKarl Rupp if (flag == SOR_APPLY_LOWER) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"SOR_APPLY_LOWER is not implemented"); 16092205254eSKarl Rupp else if (flag & SOR_EISENSTAT) { 161017ab2063SBarry Smith /* Let A = L + U + D; where L is lower trianglar, 1611887ee2caSBarry Smith U is upper triangular, E = D/omega; This routine applies 161217ab2063SBarry Smith 161317ab2063SBarry Smith (L + E)^{-1} A (U + E)^{-1} 161417ab2063SBarry Smith 1615887ee2caSBarry Smith to a vector efficiently using Eisenstat's trick. 161617ab2063SBarry Smith */ 161717ab2063SBarry Smith scale = (2.0/omega) - 1.0; 161817ab2063SBarry Smith 161917ab2063SBarry Smith /* x = (E + U)^{-1} b */ 162017ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1621416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1622ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1623ed480e8bSBarry Smith v = a->a + diag[i] + 1; 162417ab2063SBarry Smith sum = b[i]; 1625e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1626ed480e8bSBarry Smith x[i] = sum*idiag[i]; 162717ab2063SBarry Smith } 162817ab2063SBarry Smith 162917ab2063SBarry Smith /* t = b - (2*E - D)x */ 1630416022c9SBarry Smith v = a->a; 16312205254eSKarl Rupp for (i=0; i<m; i++) t[i] = b[i] - scale*(v[*diag++])*x[i]; 163217ab2063SBarry Smith 163317ab2063SBarry Smith /* t = (E + L)^{-1}t */ 1634ed480e8bSBarry Smith ts = t; 1635416022c9SBarry Smith diag = a->diag; 163617ab2063SBarry Smith for (i=0; i<m; i++) { 1637416022c9SBarry Smith n = diag[i] - a->i[i]; 1638ed480e8bSBarry Smith idx = a->j + a->i[i]; 1639ed480e8bSBarry Smith v = a->a + a->i[i]; 164017ab2063SBarry Smith sum = t[i]; 1641003131ecSBarry Smith PetscSparseDenseMinusDot(sum,ts,v,idx,n); 1642ed480e8bSBarry Smith t[i] = sum*idiag[i]; 1643733d66baSBarry Smith /* x = x + t */ 1644733d66baSBarry Smith x[i] += t[i]; 164517ab2063SBarry Smith } 164617ab2063SBarry Smith 1647dc0b31edSSatish Balay ierr = PetscLogFlops(6.0*m-1 + 2.0*a->nz);CHKERRQ(ierr); 16481ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 16493649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 16503a40ed3dSBarry Smith PetscFunctionReturn(0); 165117ab2063SBarry Smith } 165217ab2063SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 165317ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 165417ab2063SBarry Smith for (i=0; i<m; i++) { 1655416022c9SBarry Smith n = diag[i] - a->i[i]; 1656ed480e8bSBarry Smith idx = a->j + a->i[i]; 1657ed480e8bSBarry Smith v = a->a + a->i[i]; 165817ab2063SBarry Smith sum = b[i]; 1659e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16605c99c7daSBarry Smith t[i] = sum; 1661ed480e8bSBarry Smith x[i] = sum*idiag[i]; 166217ab2063SBarry Smith } 16635c99c7daSBarry Smith xb = t; 1664efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 16653a40ed3dSBarry Smith } else xb = b; 166617ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 166717ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1668416022c9SBarry Smith n = a->i[i+1] - diag[i] - 1; 1669ed480e8bSBarry Smith idx = a->j + diag[i] + 1; 1670ed480e8bSBarry Smith v = a->a + diag[i] + 1; 167117ab2063SBarry Smith sum = xb[i]; 1672e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 16735c99c7daSBarry Smith if (xb == b) { 1674ed480e8bSBarry Smith x[i] = sum*idiag[i]; 16755c99c7daSBarry Smith } else { 1676b19a5dc2SMark Adams x[i] = (1-omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 167717ab2063SBarry Smith } 16785c99c7daSBarry Smith } 1679b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 168017ab2063SBarry Smith } 168117ab2063SBarry Smith its--; 168217ab2063SBarry Smith } 168317ab2063SBarry Smith while (its--) { 168417ab2063SBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 168517ab2063SBarry Smith for (i=0; i<m; i++) { 1686b19a5dc2SMark Adams /* lower */ 1687b19a5dc2SMark Adams n = diag[i] - a->i[i]; 1688ed480e8bSBarry Smith idx = a->j + a->i[i]; 1689ed480e8bSBarry Smith v = a->a + a->i[i]; 169017ab2063SBarry Smith sum = b[i]; 1691e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1692b19a5dc2SMark Adams t[i] = sum; /* save application of the lower-triangular part */ 1693b19a5dc2SMark Adams /* upper */ 1694b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1695b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1696b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1697b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1698b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 169917ab2063SBarry Smith } 1700b19a5dc2SMark Adams xb = t; 17019f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1702b19a5dc2SMark Adams } else xb = b; 170317ab2063SBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 170417ab2063SBarry Smith for (i=m-1; i>=0; i--) { 1705b19a5dc2SMark Adams sum = xb[i]; 1706b19a5dc2SMark Adams if (xb == b) { 1707b19a5dc2SMark Adams /* whole matrix (no checkpointing available) */ 1708416022c9SBarry Smith n = a->i[i+1] - a->i[i]; 1709ed480e8bSBarry Smith idx = a->j + a->i[i]; 1710ed480e8bSBarry Smith v = a->a + a->i[i]; 1711e6d1f457SBarry Smith PetscSparseDenseMinusDot(sum,x,v,idx,n); 1712ed480e8bSBarry Smith x[i] = (1. - omega)*x[i] + (sum + mdiag[i]*x[i])*idiag[i]; 1713b19a5dc2SMark Adams } else { /* lower-triangular part has been saved, so only apply upper-triangular */ 1714b19a5dc2SMark Adams n = a->i[i+1] - diag[i] - 1; 1715b19a5dc2SMark Adams idx = a->j + diag[i] + 1; 1716b19a5dc2SMark Adams v = a->a + diag[i] + 1; 1717b19a5dc2SMark Adams PetscSparseDenseMinusDot(sum,x,v,idx,n); 1718b19a5dc2SMark Adams x[i] = (1. - omega)*x[i] + sum*idiag[i]; /* omega in idiag */ 171917ab2063SBarry Smith } 1720b19a5dc2SMark Adams } 1721b19a5dc2SMark Adams if (xb == b) { 17229f863219SBarry Smith ierr = PetscLogFlops(2.0*a->nz);CHKERRQ(ierr); 1723b19a5dc2SMark Adams } else { 1724b19a5dc2SMark Adams ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); /* assumes 1/2 in upper */ 1725b19a5dc2SMark Adams } 172617ab2063SBarry Smith } 172717ab2063SBarry Smith } 17281ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 17293649974fSBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 1730365a8a9eSBarry Smith PetscFunctionReturn(0); 173117ab2063SBarry Smith } 173217ab2063SBarry Smith 17332af78befSBarry Smith 1734dfbe8321SBarry Smith PetscErrorCode MatGetInfo_SeqAIJ(Mat A,MatInfoType flag,MatInfo *info) 173517ab2063SBarry Smith { 1736416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 17374e220ebcSLois Curfman McInnes 17383a40ed3dSBarry Smith PetscFunctionBegin; 17394e220ebcSLois Curfman McInnes info->block_size = 1.0; 17404e220ebcSLois Curfman McInnes info->nz_allocated = (double)a->maxnz; 17414e220ebcSLois Curfman McInnes info->nz_used = (double)a->nz; 17424e220ebcSLois Curfman McInnes info->nz_unneeded = (double)(a->maxnz - a->nz); 17434e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 17448e58a170SBarry Smith info->mallocs = (double)A->info.mallocs; 17457adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 1746d5f3da31SBarry Smith if (A->factortype) { 17474e220ebcSLois Curfman McInnes info->fill_ratio_given = A->info.fill_ratio_given; 17484e220ebcSLois Curfman McInnes info->fill_ratio_needed = A->info.fill_ratio_needed; 17494e220ebcSLois Curfman McInnes info->factor_mallocs = A->info.factor_mallocs; 17504e220ebcSLois Curfman McInnes } else { 17514e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 17524e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 17534e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 17544e220ebcSLois Curfman McInnes } 17553a40ed3dSBarry Smith PetscFunctionReturn(0); 175617ab2063SBarry Smith } 175717ab2063SBarry Smith 17582b40b63fSBarry Smith PetscErrorCode MatZeroRows_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 175917ab2063SBarry Smith { 1760416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1761c7da8527SEric Chamberland PetscInt i,m = A->rmap->n - 1; 17626849ba73SBarry Smith PetscErrorCode ierr; 176397b48c8fSBarry Smith const PetscScalar *xx; 176497b48c8fSBarry Smith PetscScalar *bb; 1765c7da8527SEric Chamberland PetscInt d = 0; 176617ab2063SBarry Smith 17673a40ed3dSBarry Smith PetscFunctionBegin; 176897b48c8fSBarry Smith if (x && b) { 176997b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 177097b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 177197b48c8fSBarry Smith for (i=0; i<N; i++) { 177297b48c8fSBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 177397b48c8fSBarry Smith bb[rows[i]] = diag*xx[rows[i]]; 177497b48c8fSBarry Smith } 177597b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 177697b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 177797b48c8fSBarry Smith } 177897b48c8fSBarry Smith 1779a9817697SBarry Smith if (a->keepnonzeropattern) { 1780f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1781e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1782bfeeae90SHong Zhang ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 1783f1e2ffcdSBarry Smith } 1784f4df32b1SMatthew Knepley if (diag != 0.0) { 1785c7da8527SEric Chamberland for (i=0; i<N; i++) { 1786c7da8527SEric Chamberland d = rows[i]; 1787c7da8527SEric Chamberland if (a->diag[d] >= a->i[d+1]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in the zeroed row %D",d); 1788c7da8527SEric Chamberland } 1789f1e2ffcdSBarry Smith for (i=0; i<N; i++) { 1790f4df32b1SMatthew Knepley a->a[a->diag[rows[i]]] = diag; 1791f1e2ffcdSBarry Smith } 1792f1e2ffcdSBarry Smith } 1793f1e2ffcdSBarry Smith } else { 1794f4df32b1SMatthew Knepley if (diag != 0.0) { 179517ab2063SBarry Smith for (i=0; i<N; i++) { 1796e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 17977ae801bdSBarry Smith if (a->ilen[rows[i]] > 0) { 1798416022c9SBarry Smith a->ilen[rows[i]] = 1; 1799f4df32b1SMatthew Knepley a->a[a->i[rows[i]]] = diag; 1800bfeeae90SHong Zhang a->j[a->i[rows[i]]] = rows[i]; 18017ae801bdSBarry Smith } else { /* in case row was completely empty */ 1802f4df32b1SMatthew Knepley ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 180317ab2063SBarry Smith } 180417ab2063SBarry Smith } 18053a40ed3dSBarry Smith } else { 180617ab2063SBarry Smith for (i=0; i<N; i++) { 1807e32f2f54SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 1808416022c9SBarry Smith a->ilen[rows[i]] = 0; 180917ab2063SBarry Smith } 181017ab2063SBarry Smith } 1811e56f5c9eSBarry Smith A->nonzerostate++; 1812f1e2ffcdSBarry Smith } 181343a90d84SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18143a40ed3dSBarry Smith PetscFunctionReturn(0); 181517ab2063SBarry Smith } 181617ab2063SBarry Smith 18176e169961SBarry Smith PetscErrorCode MatZeroRowsColumns_SeqAIJ(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 18186e169961SBarry Smith { 18196e169961SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 18206e169961SBarry Smith PetscInt i,j,m = A->rmap->n - 1,d = 0; 18216e169961SBarry Smith PetscErrorCode ierr; 18222b40b63fSBarry Smith PetscBool missing,*zeroed,vecs = PETSC_FALSE; 18236e169961SBarry Smith const PetscScalar *xx; 18246e169961SBarry Smith PetscScalar *bb; 18256e169961SBarry Smith 18266e169961SBarry Smith PetscFunctionBegin; 18276e169961SBarry Smith if (x && b) { 18286e169961SBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 18296e169961SBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 18302b40b63fSBarry Smith vecs = PETSC_TRUE; 18316e169961SBarry Smith } 18321795a4d1SJed Brown ierr = PetscCalloc1(A->rmap->n,&zeroed);CHKERRQ(ierr); 18336e169961SBarry Smith for (i=0; i<N; i++) { 18346e169961SBarry Smith if (rows[i] < 0 || rows[i] > m) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"row %D out of range", rows[i]); 18356e169961SBarry Smith ierr = PetscMemzero(&a->a[a->i[rows[i]]],a->ilen[rows[i]]*sizeof(PetscScalar));CHKERRQ(ierr); 18362205254eSKarl Rupp 18376e169961SBarry Smith zeroed[rows[i]] = PETSC_TRUE; 18386e169961SBarry Smith } 18396e169961SBarry Smith for (i=0; i<A->rmap->n; i++) { 18406e169961SBarry Smith if (!zeroed[i]) { 18416e169961SBarry Smith for (j=a->i[i]; j<a->i[i+1]; j++) { 18426e169961SBarry Smith if (zeroed[a->j[j]]) { 18432b40b63fSBarry Smith if (vecs) bb[i] -= a->a[j]*xx[a->j[j]]; 18446e169961SBarry Smith a->a[j] = 0.0; 18456e169961SBarry Smith } 18466e169961SBarry Smith } 18472b40b63fSBarry Smith } else if (vecs) bb[i] = diag*xx[i]; 18486e169961SBarry Smith } 18496e169961SBarry Smith if (x && b) { 18506e169961SBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 18516e169961SBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 18526e169961SBarry Smith } 18536e169961SBarry Smith ierr = PetscFree(zeroed);CHKERRQ(ierr); 18546e169961SBarry Smith if (diag != 0.0) { 18556e169961SBarry Smith ierr = MatMissingDiagonal_SeqAIJ(A,&missing,&d);CHKERRQ(ierr); 18561d5a398dSstefano_zampini if (missing) { 18571d5a398dSstefano_zampini if (a->nonew) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix is missing diagonal entry in row %D",d); 18581d5a398dSstefano_zampini else { 18591d5a398dSstefano_zampini for (i=0; i<N; i++) { 18601d5a398dSstefano_zampini ierr = MatSetValues_SeqAIJ(A,1,&rows[i],1,&rows[i],&diag,INSERT_VALUES);CHKERRQ(ierr); 18611d5a398dSstefano_zampini } 18621d5a398dSstefano_zampini } 18631d5a398dSstefano_zampini } else { 18646e169961SBarry Smith for (i=0; i<N; i++) { 18656e169961SBarry Smith a->a[a->diag[rows[i]]] = diag; 18666e169961SBarry Smith } 18676e169961SBarry Smith } 18681d5a398dSstefano_zampini } 18696e169961SBarry Smith ierr = MatAssemblyEnd_SeqAIJ(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 18706e169961SBarry Smith PetscFunctionReturn(0); 18716e169961SBarry Smith } 18726e169961SBarry Smith 1873a77337e4SBarry Smith PetscErrorCode MatGetRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 187417ab2063SBarry Smith { 1875416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 187697f1f81fSBarry Smith PetscInt *itmp; 187717ab2063SBarry Smith 18783a40ed3dSBarry Smith PetscFunctionBegin; 1879e32f2f54SBarry Smith if (row < 0 || row >= A->rmap->n) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D out of range",row); 188017ab2063SBarry Smith 1881416022c9SBarry Smith *nz = a->i[row+1] - a->i[row]; 1882bfeeae90SHong Zhang if (v) *v = a->a + a->i[row]; 188317ab2063SBarry Smith if (idx) { 1884bfeeae90SHong Zhang itmp = a->j + a->i[row]; 188526fbe8dcSKarl Rupp if (*nz) *idx = itmp; 188617ab2063SBarry Smith else *idx = 0; 188717ab2063SBarry Smith } 18883a40ed3dSBarry Smith PetscFunctionReturn(0); 188917ab2063SBarry Smith } 189017ab2063SBarry Smith 1891bfeeae90SHong Zhang /* remove this function? */ 1892a77337e4SBarry Smith PetscErrorCode MatRestoreRow_SeqAIJ(Mat A,PetscInt row,PetscInt *nz,PetscInt **idx,PetscScalar **v) 189317ab2063SBarry Smith { 18943a40ed3dSBarry Smith PetscFunctionBegin; 18953a40ed3dSBarry Smith PetscFunctionReturn(0); 189617ab2063SBarry Smith } 189717ab2063SBarry Smith 1898dfbe8321SBarry Smith PetscErrorCode MatNorm_SeqAIJ(Mat A,NormType type,PetscReal *nrm) 189917ab2063SBarry Smith { 1900416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 190154f21887SBarry Smith MatScalar *v = a->a; 190236db0b34SBarry Smith PetscReal sum = 0.0; 19036849ba73SBarry Smith PetscErrorCode ierr; 190497f1f81fSBarry Smith PetscInt i,j; 190517ab2063SBarry Smith 19063a40ed3dSBarry Smith PetscFunctionBegin; 190717ab2063SBarry Smith if (type == NORM_FROBENIUS) { 1908570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1909570b7f6dSBarry Smith PetscBLASInt one = 1,nz = a->nz; 1910570b7f6dSBarry Smith *nrm = BLASnrm2_(&nz,v,&one); 1911570b7f6dSBarry Smith #else 1912416022c9SBarry Smith for (i=0; i<a->nz; i++) { 191336db0b34SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 191417ab2063SBarry Smith } 19158f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1916570b7f6dSBarry Smith #endif 191751f70360SJed Brown ierr = PetscLogFlops(2*a->nz);CHKERRQ(ierr); 19183a40ed3dSBarry Smith } else if (type == NORM_1) { 191936db0b34SBarry Smith PetscReal *tmp; 192097f1f81fSBarry Smith PetscInt *jj = a->j; 19211795a4d1SJed Brown ierr = PetscCalloc1(A->cmap->n+1,&tmp);CHKERRQ(ierr); 1922064f8208SBarry Smith *nrm = 0.0; 1923416022c9SBarry Smith for (j=0; j<a->nz; j++) { 1924bfeeae90SHong Zhang tmp[*jj++] += PetscAbsScalar(*v); v++; 192517ab2063SBarry Smith } 1926d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1927064f8208SBarry Smith if (tmp[j] > *nrm) *nrm = tmp[j]; 192817ab2063SBarry Smith } 1929606d414cSSatish Balay ierr = PetscFree(tmp);CHKERRQ(ierr); 193051f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 19313a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1932064f8208SBarry Smith *nrm = 0.0; 1933d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1934bfeeae90SHong Zhang v = a->a + a->i[j]; 193517ab2063SBarry Smith sum = 0.0; 1936416022c9SBarry Smith for (i=0; i<a->i[j+1]-a->i[j]; i++) { 1937cddf8d76SBarry Smith sum += PetscAbsScalar(*v); v++; 193817ab2063SBarry Smith } 1939064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 194017ab2063SBarry Smith } 194151f70360SJed Brown ierr = PetscLogFlops(PetscMax(a->nz-1,0));CHKERRQ(ierr); 1942f23aa3ddSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for two norm"); 19433a40ed3dSBarry Smith PetscFunctionReturn(0); 194417ab2063SBarry Smith } 194517ab2063SBarry Smith 19464e938277SHong Zhang /* Merged from MatGetSymbolicTranspose_SeqAIJ() - replace MatGetSymbolicTranspose_SeqAIJ()? */ 19474e938277SHong Zhang PetscErrorCode MatTransposeSymbolic_SeqAIJ(Mat A,Mat *B) 19484e938277SHong Zhang { 19494e938277SHong Zhang PetscErrorCode ierr; 19504e938277SHong Zhang PetscInt i,j,anzj; 19514e938277SHong Zhang Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data,*b; 19524e938277SHong Zhang PetscInt an=A->cmap->N,am=A->rmap->N; 19534e938277SHong Zhang PetscInt *ati,*atj,*atfill,*ai=a->i,*aj=a->j; 19544e938277SHong Zhang 19554e938277SHong Zhang PetscFunctionBegin; 19564e938277SHong Zhang /* Allocate space for symbolic transpose info and work array */ 1957854ce69bSBarry Smith ierr = PetscCalloc1(an+1,&ati);CHKERRQ(ierr); 1958785e854fSJed Brown ierr = PetscMalloc1(ai[am],&atj);CHKERRQ(ierr); 1959785e854fSJed Brown ierr = PetscMalloc1(an,&atfill);CHKERRQ(ierr); 19604e938277SHong Zhang 19614e938277SHong Zhang /* Walk through aj and count ## of non-zeros in each row of A^T. */ 19624e938277SHong Zhang /* Note: offset by 1 for fast conversion into csr format. */ 196326fbe8dcSKarl Rupp for (i=0;i<ai[am];i++) ati[aj[i]+1] += 1; 19644e938277SHong Zhang /* Form ati for csr format of A^T. */ 196526fbe8dcSKarl Rupp for (i=0;i<an;i++) ati[i+1] += ati[i]; 19664e938277SHong Zhang 19674e938277SHong Zhang /* Copy ati into atfill so we have locations of the next free space in atj */ 19684e938277SHong Zhang ierr = PetscMemcpy(atfill,ati,an*sizeof(PetscInt));CHKERRQ(ierr); 19694e938277SHong Zhang 19704e938277SHong Zhang /* Walk through A row-wise and mark nonzero entries of A^T. */ 19714e938277SHong Zhang for (i=0;i<am;i++) { 19724e938277SHong Zhang anzj = ai[i+1] - ai[i]; 19734e938277SHong Zhang for (j=0;j<anzj;j++) { 19744e938277SHong Zhang atj[atfill[*aj]] = i; 19754e938277SHong Zhang atfill[*aj++] += 1; 19764e938277SHong Zhang } 19774e938277SHong Zhang } 19784e938277SHong Zhang 19794e938277SHong Zhang /* Clean up temporary space and complete requests. */ 19804e938277SHong Zhang ierr = PetscFree(atfill);CHKERRQ(ierr); 1981ce94432eSBarry Smith ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),an,am,ati,atj,NULL,B);CHKERRQ(ierr); 198233d57670SJed Brown ierr = MatSetBlockSizes(*B,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 1983a2f3521dSMark F. Adams 19844e938277SHong Zhang b = (Mat_SeqAIJ*)((*B)->data); 19854e938277SHong Zhang b->free_a = PETSC_FALSE; 19864e938277SHong Zhang b->free_ij = PETSC_TRUE; 19874e938277SHong Zhang b->nonew = 0; 19884e938277SHong Zhang PetscFunctionReturn(0); 19894e938277SHong Zhang } 19904e938277SHong Zhang 1991fc4dec0aSBarry Smith PetscErrorCode MatTranspose_SeqAIJ(Mat A,MatReuse reuse,Mat *B) 199217ab2063SBarry Smith { 1993416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 1994416022c9SBarry Smith Mat C; 19956849ba73SBarry Smith PetscErrorCode ierr; 1996d0f46423SBarry Smith PetscInt i,*aj = a->j,*ai = a->i,m = A->rmap->n,len,*col; 199754f21887SBarry Smith MatScalar *array = a->a; 199817ab2063SBarry Smith 19993a40ed3dSBarry Smith PetscFunctionBegin; 2000cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX && m != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Square matrix only for in-place"); 2001fc4dec0aSBarry Smith 2002cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_INPLACE_MATRIX) { 2003854ce69bSBarry Smith ierr = PetscCalloc1(1+A->cmap->n,&col);CHKERRQ(ierr); 2004bfeeae90SHong Zhang 2005bfeeae90SHong Zhang for (i=0; i<ai[m]; i++) col[aj[i]] += 1; 2006ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2007d0f46423SBarry Smith ierr = MatSetSizes(C,A->cmap->n,m,A->cmap->n,m);CHKERRQ(ierr); 200833d57670SJed Brown ierr = MatSetBlockSizes(C,PetscAbs(A->cmap->bs),PetscAbs(A->rmap->bs));CHKERRQ(ierr); 20097adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2010ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,col);CHKERRQ(ierr); 2011606d414cSSatish Balay ierr = PetscFree(col);CHKERRQ(ierr); 2012a541d17aSBarry Smith } else { 2013a541d17aSBarry Smith C = *B; 2014a541d17aSBarry Smith } 2015a541d17aSBarry Smith 201617ab2063SBarry Smith for (i=0; i<m; i++) { 201717ab2063SBarry Smith len = ai[i+1]-ai[i]; 201887d4246cSBarry Smith ierr = MatSetValues_SeqAIJ(C,len,aj,1,&i,array,INSERT_VALUES);CHKERRQ(ierr); 2019b9b97703SBarry Smith array += len; 2020b9b97703SBarry Smith aj += len; 202117ab2063SBarry Smith } 20226d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20236d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 202417ab2063SBarry Smith 2025cf37664fSBarry Smith if (reuse == MAT_INITIAL_MATRIX || reuse == MAT_REUSE_MATRIX) { 2026416022c9SBarry Smith *B = C; 202717ab2063SBarry Smith } else { 202828be2f97SBarry Smith ierr = MatHeaderMerge(A,&C);CHKERRQ(ierr); 202917ab2063SBarry Smith } 20303a40ed3dSBarry Smith PetscFunctionReturn(0); 203117ab2063SBarry Smith } 203217ab2063SBarry Smith 20337087cfbeSBarry Smith PetscErrorCode MatIsTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 2034cd0d46ebSvictorle { 20353d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 203654f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 203754f21887SBarry Smith MatScalar *va,*vb; 20386849ba73SBarry Smith PetscErrorCode ierr; 203997f1f81fSBarry Smith PetscInt ma,na,mb,nb, i; 2040cd0d46ebSvictorle 2041cd0d46ebSvictorle PetscFunctionBegin; 2042cd0d46ebSvictorle ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 2043cd0d46ebSvictorle ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20445485867bSBarry Smith if (ma!=nb || na!=mb) { 20455485867bSBarry Smith *f = PETSC_FALSE; 20465485867bSBarry Smith PetscFunctionReturn(0); 20475485867bSBarry Smith } 2048cd0d46ebSvictorle aii = aij->i; bii = bij->i; 2049cd0d46ebSvictorle adx = aij->j; bdx = bij->j; 2050cd0d46ebSvictorle va = aij->a; vb = bij->a; 2051785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2052785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 2053cd0d46ebSvictorle for (i=0; i<ma; i++) aptr[i] = aii[i]; 2054cd0d46ebSvictorle for (i=0; i<mb; i++) bptr[i] = bii[i]; 2055cd0d46ebSvictorle 2056cd0d46ebSvictorle *f = PETSC_TRUE; 2057cd0d46ebSvictorle for (i=0; i<ma; i++) { 2058cd0d46ebSvictorle while (aptr[i]<aii[i+1]) { 205997f1f81fSBarry Smith PetscInt idc,idr; 20605485867bSBarry Smith PetscScalar vc,vr; 2061cd0d46ebSvictorle /* column/row index/value */ 20625485867bSBarry Smith idc = adx[aptr[i]]; 20635485867bSBarry Smith idr = bdx[bptr[idc]]; 20645485867bSBarry Smith vc = va[aptr[i]]; 20655485867bSBarry Smith vr = vb[bptr[idc]]; 20665485867bSBarry Smith if (i!=idr || PetscAbsScalar(vc-vr) > tol) { 20675485867bSBarry Smith *f = PETSC_FALSE; 20685485867bSBarry Smith goto done; 2069cd0d46ebSvictorle } else { 20705485867bSBarry Smith aptr[i]++; 20715485867bSBarry Smith if (B || i!=idc) bptr[idc]++; 2072cd0d46ebSvictorle } 2073cd0d46ebSvictorle } 2074cd0d46ebSvictorle } 2075cd0d46ebSvictorle done: 2076cd0d46ebSvictorle ierr = PetscFree(aptr);CHKERRQ(ierr); 20773aeef889SHong Zhang ierr = PetscFree(bptr);CHKERRQ(ierr); 2078cd0d46ebSvictorle PetscFunctionReturn(0); 2079cd0d46ebSvictorle } 2080cd0d46ebSvictorle 20817087cfbeSBarry Smith PetscErrorCode MatIsHermitianTranspose_SeqAIJ(Mat A,Mat B,PetscReal tol,PetscBool *f) 20821cbb95d3SBarry Smith { 20833d3eaba7SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*) A->data,*bij = (Mat_SeqAIJ*) B->data; 208454f21887SBarry Smith PetscInt *adx,*bdx,*aii,*bii,*aptr,*bptr; 208554f21887SBarry Smith MatScalar *va,*vb; 20861cbb95d3SBarry Smith PetscErrorCode ierr; 20871cbb95d3SBarry Smith PetscInt ma,na,mb,nb, i; 20881cbb95d3SBarry Smith 20891cbb95d3SBarry Smith PetscFunctionBegin; 20901cbb95d3SBarry Smith ierr = MatGetSize(A,&ma,&na);CHKERRQ(ierr); 20911cbb95d3SBarry Smith ierr = MatGetSize(B,&mb,&nb);CHKERRQ(ierr); 20921cbb95d3SBarry Smith if (ma!=nb || na!=mb) { 20931cbb95d3SBarry Smith *f = PETSC_FALSE; 20941cbb95d3SBarry Smith PetscFunctionReturn(0); 20951cbb95d3SBarry Smith } 20961cbb95d3SBarry Smith aii = aij->i; bii = bij->i; 20971cbb95d3SBarry Smith adx = aij->j; bdx = bij->j; 20981cbb95d3SBarry Smith va = aij->a; vb = bij->a; 2099785e854fSJed Brown ierr = PetscMalloc1(ma,&aptr);CHKERRQ(ierr); 2100785e854fSJed Brown ierr = PetscMalloc1(mb,&bptr);CHKERRQ(ierr); 21011cbb95d3SBarry Smith for (i=0; i<ma; i++) aptr[i] = aii[i]; 21021cbb95d3SBarry Smith for (i=0; i<mb; i++) bptr[i] = bii[i]; 21031cbb95d3SBarry Smith 21041cbb95d3SBarry Smith *f = PETSC_TRUE; 21051cbb95d3SBarry Smith for (i=0; i<ma; i++) { 21061cbb95d3SBarry Smith while (aptr[i]<aii[i+1]) { 21071cbb95d3SBarry Smith PetscInt idc,idr; 21081cbb95d3SBarry Smith PetscScalar vc,vr; 21091cbb95d3SBarry Smith /* column/row index/value */ 21101cbb95d3SBarry Smith idc = adx[aptr[i]]; 21111cbb95d3SBarry Smith idr = bdx[bptr[idc]]; 21121cbb95d3SBarry Smith vc = va[aptr[i]]; 21131cbb95d3SBarry Smith vr = vb[bptr[idc]]; 21141cbb95d3SBarry Smith if (i!=idr || PetscAbsScalar(vc-PetscConj(vr)) > tol) { 21151cbb95d3SBarry Smith *f = PETSC_FALSE; 21161cbb95d3SBarry Smith goto done; 21171cbb95d3SBarry Smith } else { 21181cbb95d3SBarry Smith aptr[i]++; 21191cbb95d3SBarry Smith if (B || i!=idc) bptr[idc]++; 21201cbb95d3SBarry Smith } 21211cbb95d3SBarry Smith } 21221cbb95d3SBarry Smith } 21231cbb95d3SBarry Smith done: 21241cbb95d3SBarry Smith ierr = PetscFree(aptr);CHKERRQ(ierr); 21251cbb95d3SBarry Smith ierr = PetscFree(bptr);CHKERRQ(ierr); 21261cbb95d3SBarry Smith PetscFunctionReturn(0); 21271cbb95d3SBarry Smith } 21281cbb95d3SBarry Smith 2129ace3abfcSBarry Smith PetscErrorCode MatIsSymmetric_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21309e29f15eSvictorle { 2131dfbe8321SBarry Smith PetscErrorCode ierr; 21326e111a19SKarl Rupp 21339e29f15eSvictorle PetscFunctionBegin; 21345485867bSBarry Smith ierr = MatIsTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21359e29f15eSvictorle PetscFunctionReturn(0); 21369e29f15eSvictorle } 21379e29f15eSvictorle 2138ace3abfcSBarry Smith PetscErrorCode MatIsHermitian_SeqAIJ(Mat A,PetscReal tol,PetscBool *f) 21391cbb95d3SBarry Smith { 21401cbb95d3SBarry Smith PetscErrorCode ierr; 21416e111a19SKarl Rupp 21421cbb95d3SBarry Smith PetscFunctionBegin; 21431cbb95d3SBarry Smith ierr = MatIsHermitianTranspose_SeqAIJ(A,A,tol,f);CHKERRQ(ierr); 21441cbb95d3SBarry Smith PetscFunctionReturn(0); 21451cbb95d3SBarry Smith } 21461cbb95d3SBarry Smith 2147dfbe8321SBarry Smith PetscErrorCode MatDiagonalScale_SeqAIJ(Mat A,Vec ll,Vec rr) 214817ab2063SBarry Smith { 2149416022c9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 215054f21887SBarry Smith PetscScalar *l,*r,x; 215154f21887SBarry Smith MatScalar *v; 2152dfbe8321SBarry Smith PetscErrorCode ierr; 2153d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,M,nz = a->nz,*jj; 215417ab2063SBarry Smith 21553a40ed3dSBarry Smith PetscFunctionBegin; 215617ab2063SBarry Smith if (ll) { 21573ea7c6a1SSatish Balay /* The local size is used so that VecMPI can be passed to this routine 21583ea7c6a1SSatish Balay by MatDiagonalScale_MPIAIJ */ 2159e1311b90SBarry Smith ierr = VecGetLocalSize(ll,&m);CHKERRQ(ierr); 2160e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vector wrong length"); 21611ebc52fbSHong Zhang ierr = VecGetArray(ll,&l);CHKERRQ(ierr); 2162416022c9SBarry Smith v = a->a; 216317ab2063SBarry Smith for (i=0; i<m; i++) { 216417ab2063SBarry Smith x = l[i]; 2165416022c9SBarry Smith M = a->i[i+1] - a->i[i]; 21662205254eSKarl Rupp for (j=0; j<M; j++) (*v++) *= x; 216717ab2063SBarry Smith } 21681ebc52fbSHong Zhang ierr = VecRestoreArray(ll,&l);CHKERRQ(ierr); 2169efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 217017ab2063SBarry Smith } 217117ab2063SBarry Smith if (rr) { 2172e1311b90SBarry Smith ierr = VecGetLocalSize(rr,&n);CHKERRQ(ierr); 2173e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vector wrong length"); 21741ebc52fbSHong Zhang ierr = VecGetArray(rr,&r);CHKERRQ(ierr); 2175416022c9SBarry Smith v = a->a; jj = a->j; 21762205254eSKarl Rupp for (i=0; i<nz; i++) (*v++) *= r[*jj++]; 21771ebc52fbSHong Zhang ierr = VecRestoreArray(rr,&r);CHKERRQ(ierr); 2178efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 217917ab2063SBarry Smith } 2180acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(A);CHKERRQ(ierr); 21813a40ed3dSBarry Smith PetscFunctionReturn(0); 218217ab2063SBarry Smith } 218317ab2063SBarry Smith 21847dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrix_SeqAIJ(Mat A,IS isrow,IS iscol,PetscInt csize,MatReuse scall,Mat *B) 218517ab2063SBarry Smith { 2186db02288aSLois Curfman McInnes Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*c; 21876849ba73SBarry Smith PetscErrorCode ierr; 2188d0f46423SBarry Smith PetscInt *smap,i,k,kstart,kend,oldcols = A->cmap->n,*lens; 218997f1f81fSBarry Smith PetscInt row,mat_i,*mat_j,tcol,first,step,*mat_ilen,sum,lensi; 21905d0c19d7SBarry Smith const PetscInt *irow,*icol; 21915d0c19d7SBarry Smith PetscInt nrows,ncols; 219297f1f81fSBarry Smith PetscInt *starts,*j_new,*i_new,*aj = a->j,*ai = a->i,ii,*ailen = a->ilen; 219354f21887SBarry Smith MatScalar *a_new,*mat_a; 2194416022c9SBarry Smith Mat C; 2195cdc6f3adSToby Isaac PetscBool stride; 219617ab2063SBarry Smith 21973a40ed3dSBarry Smith PetscFunctionBegin; 219899141d43SSatish Balay 219917ab2063SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 2200b9b97703SBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 2201b9b97703SBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 220217ab2063SBarry Smith 2203251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)iscol,ISSTRIDE,&stride);CHKERRQ(ierr); 2204ff718158SBarry Smith if (stride) { 2205ff718158SBarry Smith ierr = ISStrideGetInfo(iscol,&first,&step);CHKERRQ(ierr); 2206ff718158SBarry Smith } else { 2207ff718158SBarry Smith first = 0; 2208ff718158SBarry Smith step = 0; 2209ff718158SBarry Smith } 2210fee21e36SBarry Smith if (stride && step == 1) { 221102834360SBarry Smith /* special case of contiguous rows */ 2212dcca6d9dSJed Brown ierr = PetscMalloc2(nrows,&lens,nrows,&starts);CHKERRQ(ierr); 221302834360SBarry Smith /* loop over new rows determining lens and starting points */ 221402834360SBarry Smith for (i=0; i<nrows; i++) { 2215bfeeae90SHong Zhang kstart = ai[irow[i]]; 2216a2744918SBarry Smith kend = kstart + ailen[irow[i]]; 2217a91a9bebSLisandro Dalcin starts[i] = kstart; 221802834360SBarry Smith for (k=kstart; k<kend; k++) { 2219bfeeae90SHong Zhang if (aj[k] >= first) { 222002834360SBarry Smith starts[i] = k; 222102834360SBarry Smith break; 222202834360SBarry Smith } 222302834360SBarry Smith } 2224a2744918SBarry Smith sum = 0; 222502834360SBarry Smith while (k < kend) { 2226bfeeae90SHong Zhang if (aj[k++] >= first+ncols) break; 2227a2744918SBarry Smith sum++; 222802834360SBarry Smith } 2229a2744918SBarry Smith lens[i] = sum; 223002834360SBarry Smith } 223102834360SBarry Smith /* create submatrix */ 2232cddf8d76SBarry Smith if (scall == MAT_REUSE_MATRIX) { 223397f1f81fSBarry Smith PetscInt n_cols,n_rows; 223408480c60SBarry Smith ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 2235e32f2f54SBarry Smith if (n_rows != nrows || n_cols != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Reused submatrix wrong size"); 2236d8ced48eSBarry Smith ierr = MatZeroEntries(*B);CHKERRQ(ierr); 223708480c60SBarry Smith C = *B; 22383a40ed3dSBarry Smith } else { 22393bef6203SJed Brown PetscInt rbs,cbs; 2240ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2241f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 22423bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 22433bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 22443bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 22457adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2246ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 224708480c60SBarry Smith } 2248db02288aSLois Curfman McInnes c = (Mat_SeqAIJ*)C->data; 2249db02288aSLois Curfman McInnes 225002834360SBarry Smith /* loop over rows inserting into submatrix */ 2251db02288aSLois Curfman McInnes a_new = c->a; 2252db02288aSLois Curfman McInnes j_new = c->j; 2253db02288aSLois Curfman McInnes i_new = c->i; 2254bfeeae90SHong Zhang 225502834360SBarry Smith for (i=0; i<nrows; i++) { 2256a2744918SBarry Smith ii = starts[i]; 2257a2744918SBarry Smith lensi = lens[i]; 2258a2744918SBarry Smith for (k=0; k<lensi; k++) { 2259a2744918SBarry Smith *j_new++ = aj[ii+k] - first; 226002834360SBarry Smith } 226187828ca2SBarry Smith ierr = PetscMemcpy(a_new,a->a + starts[i],lensi*sizeof(PetscScalar));CHKERRQ(ierr); 2262a2744918SBarry Smith a_new += lensi; 2263a2744918SBarry Smith i_new[i+1] = i_new[i] + lensi; 2264a2744918SBarry Smith c->ilen[i] = lensi; 226502834360SBarry Smith } 22660e83c824SBarry Smith ierr = PetscFree2(lens,starts);CHKERRQ(ierr); 22673a40ed3dSBarry Smith } else { 226802834360SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 22691795a4d1SJed Brown ierr = PetscCalloc1(oldcols,&smap);CHKERRQ(ierr); 2270854ce69bSBarry Smith ierr = PetscMalloc1(1+nrows,&lens);CHKERRQ(ierr); 22714dcab191SBarry Smith for (i=0; i<ncols; i++) { 22724dcab191SBarry Smith #if defined(PETSC_USE_DEBUG) 22734dcab191SBarry 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); 22744dcab191SBarry Smith #endif 22754dcab191SBarry Smith smap[icol[i]] = i+1; 22764dcab191SBarry Smith } 22774dcab191SBarry Smith 227802834360SBarry Smith /* determine lens of each row */ 227902834360SBarry Smith for (i=0; i<nrows; i++) { 2280bfeeae90SHong Zhang kstart = ai[irow[i]]; 228102834360SBarry Smith kend = kstart + a->ilen[irow[i]]; 228202834360SBarry Smith lens[i] = 0; 228302834360SBarry Smith for (k=kstart; k<kend; k++) { 2284bfeeae90SHong Zhang if (smap[aj[k]]) { 228502834360SBarry Smith lens[i]++; 228602834360SBarry Smith } 228702834360SBarry Smith } 228802834360SBarry Smith } 228917ab2063SBarry Smith /* Create and fill new matrix */ 2290a2744918SBarry Smith if (scall == MAT_REUSE_MATRIX) { 2291ace3abfcSBarry Smith PetscBool equal; 22920f5bd95cSBarry Smith 229399141d43SSatish Balay c = (Mat_SeqAIJ*)((*B)->data); 2294e32f2f54SBarry Smith if ((*B)->rmap->n != nrows || (*B)->cmap->n != ncols) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong size"); 2295d0f46423SBarry Smith ierr = PetscMemcmp(c->ilen,lens,(*B)->rmap->n*sizeof(PetscInt),&equal);CHKERRQ(ierr); 2296f23aa3ddSBarry Smith if (!equal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Cannot reuse matrix. wrong no of nonzeros"); 2297d0f46423SBarry Smith ierr = PetscMemzero(c->ilen,(*B)->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 229808480c60SBarry Smith C = *B; 22993a40ed3dSBarry Smith } else { 23003bef6203SJed Brown PetscInt rbs,cbs; 2301ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&C);CHKERRQ(ierr); 2302f69a0ea3SMatthew Knepley ierr = MatSetSizes(C,nrows,ncols,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 23033bef6203SJed Brown ierr = ISGetBlockSize(isrow,&rbs);CHKERRQ(ierr); 23043bef6203SJed Brown ierr = ISGetBlockSize(iscol,&cbs);CHKERRQ(ierr); 23053bef6203SJed Brown ierr = MatSetBlockSizes(C,rbs,cbs);CHKERRQ(ierr); 23067adad957SLisandro Dalcin ierr = MatSetType(C,((PetscObject)A)->type_name);CHKERRQ(ierr); 2307ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(C,0,lens);CHKERRQ(ierr); 230808480c60SBarry Smith } 230999141d43SSatish Balay c = (Mat_SeqAIJ*)(C->data); 231017ab2063SBarry Smith for (i=0; i<nrows; i++) { 231199141d43SSatish Balay row = irow[i]; 2312bfeeae90SHong Zhang kstart = ai[row]; 231399141d43SSatish Balay kend = kstart + a->ilen[row]; 2314bfeeae90SHong Zhang mat_i = c->i[i]; 231599141d43SSatish Balay mat_j = c->j + mat_i; 231699141d43SSatish Balay mat_a = c->a + mat_i; 231799141d43SSatish Balay mat_ilen = c->ilen + i; 231817ab2063SBarry Smith for (k=kstart; k<kend; k++) { 2319bfeeae90SHong Zhang if ((tcol=smap[a->j[k]])) { 2320ed480e8bSBarry Smith *mat_j++ = tcol - 1; 232199141d43SSatish Balay *mat_a++ = a->a[k]; 232299141d43SSatish Balay (*mat_ilen)++; 232399141d43SSatish Balay 232417ab2063SBarry Smith } 232517ab2063SBarry Smith } 232617ab2063SBarry Smith } 232702834360SBarry Smith /* Free work space */ 232802834360SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 2329606d414cSSatish Balay ierr = PetscFree(smap);CHKERRQ(ierr); 2330606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 2331cdc6f3adSToby Isaac /* sort */ 2332cdc6f3adSToby Isaac for (i = 0; i < nrows; i++) { 2333cdc6f3adSToby Isaac PetscInt ilen; 2334cdc6f3adSToby Isaac 2335cdc6f3adSToby Isaac mat_i = c->i[i]; 2336cdc6f3adSToby Isaac mat_j = c->j + mat_i; 2337cdc6f3adSToby Isaac mat_a = c->a + mat_i; 2338cdc6f3adSToby Isaac ilen = c->ilen[i]; 2339390e1bf2SBarry Smith ierr = PetscSortIntWithScalarArray(ilen,mat_j,mat_a);CHKERRQ(ierr); 2340cdc6f3adSToby Isaac } 234102834360SBarry Smith } 23426d4a8577SBarry Smith ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 23436d4a8577SBarry Smith ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 234417ab2063SBarry Smith 234517ab2063SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 2346416022c9SBarry Smith *B = C; 23473a40ed3dSBarry Smith PetscFunctionReturn(0); 234817ab2063SBarry Smith } 234917ab2063SBarry Smith 2350fc08c53fSHong Zhang PetscErrorCode MatGetMultiProcBlock_SeqAIJ(Mat mat,MPI_Comm subComm,MatReuse scall,Mat *subMat) 235182d44351SHong Zhang { 235282d44351SHong Zhang PetscErrorCode ierr; 235382d44351SHong Zhang Mat B; 235482d44351SHong Zhang 235582d44351SHong Zhang PetscFunctionBegin; 2356c2d650bdSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 235782d44351SHong Zhang ierr = MatCreate(subComm,&B);CHKERRQ(ierr); 235882d44351SHong Zhang ierr = MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->n,mat->cmap->n);CHKERRQ(ierr); 235933d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,mat,mat);CHKERRQ(ierr); 236082d44351SHong Zhang ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 236182d44351SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(B,mat,MAT_COPY_VALUES,PETSC_TRUE);CHKERRQ(ierr); 236282d44351SHong Zhang *subMat = B; 2363c2d650bdSHong Zhang } else { 2364c2d650bdSHong Zhang ierr = MatCopy_SeqAIJ(mat,*subMat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 2365c2d650bdSHong Zhang } 236682d44351SHong Zhang PetscFunctionReturn(0); 236782d44351SHong Zhang } 236882d44351SHong Zhang 23699a625307SHong Zhang PetscErrorCode MatILUFactor_SeqAIJ(Mat inA,IS row,IS col,const MatFactorInfo *info) 2370a871dcd8SBarry Smith { 237163b91edcSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2372dfbe8321SBarry Smith PetscErrorCode ierr; 237363b91edcSBarry Smith Mat outA; 2374ace3abfcSBarry Smith PetscBool row_identity,col_identity; 237563b91edcSBarry Smith 23763a40ed3dSBarry Smith PetscFunctionBegin; 2377e32f2f54SBarry Smith if (info->levels != 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only levels=0 supported for in-place ilu"); 23781df811f5SHong Zhang 2379b8a78c4aSBarry Smith ierr = ISIdentity(row,&row_identity);CHKERRQ(ierr); 2380b8a78c4aSBarry Smith ierr = ISIdentity(col,&col_identity);CHKERRQ(ierr); 2381a871dcd8SBarry Smith 238263b91edcSBarry Smith outA = inA; 2383d5f3da31SBarry Smith outA->factortype = MAT_FACTOR_LU; 2384f6224b95SHong Zhang ierr = PetscFree(inA->solvertype);CHKERRQ(ierr); 2385f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&inA->solvertype);CHKERRQ(ierr); 23862205254eSKarl Rupp 2387c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)row);CHKERRQ(ierr); 23886bf464f9SBarry Smith ierr = ISDestroy(&a->row);CHKERRQ(ierr); 23892205254eSKarl Rupp 2390c3122656SLisandro Dalcin a->row = row; 23912205254eSKarl Rupp 2392c38d4ed2SBarry Smith ierr = PetscObjectReference((PetscObject)col);CHKERRQ(ierr); 23936bf464f9SBarry Smith ierr = ISDestroy(&a->col);CHKERRQ(ierr); 23942205254eSKarl Rupp 2395c3122656SLisandro Dalcin a->col = col; 239663b91edcSBarry Smith 239736db0b34SBarry Smith /* Create the inverse permutation so that it can be used in MatLUFactorNumeric() */ 23986bf464f9SBarry Smith ierr = ISDestroy(&a->icol);CHKERRQ(ierr); 23994c49b128SBarry Smith ierr = ISInvertPermutation(col,PETSC_DECIDE,&a->icol);CHKERRQ(ierr); 24003bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)inA,(PetscObject)a->icol);CHKERRQ(ierr); 2401f0ec6fceSSatish Balay 240294a9d846SBarry Smith if (!a->solve_work) { /* this matrix may have been factored before */ 2403854ce69bSBarry Smith ierr = PetscMalloc1(inA->rmap->n+1,&a->solve_work);CHKERRQ(ierr); 24043bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)inA, (inA->rmap->n+1)*sizeof(PetscScalar));CHKERRQ(ierr); 240594a9d846SBarry Smith } 240663b91edcSBarry Smith 2407f1e2ffcdSBarry Smith ierr = MatMarkDiagonal_SeqAIJ(inA);CHKERRQ(ierr); 2408137fb511SHong Zhang if (row_identity && col_identity) { 2409ad04f41aSHong Zhang ierr = MatLUFactorNumeric_SeqAIJ_inplace(outA,inA,info);CHKERRQ(ierr); 2410137fb511SHong Zhang } else { 2411719d5645SBarry Smith ierr = MatLUFactorNumeric_SeqAIJ_InplaceWithPerm(outA,inA,info);CHKERRQ(ierr); 2412137fb511SHong Zhang } 24133a40ed3dSBarry Smith PetscFunctionReturn(0); 2414a871dcd8SBarry Smith } 2415a871dcd8SBarry Smith 2416f4df32b1SMatthew Knepley PetscErrorCode MatScale_SeqAIJ(Mat inA,PetscScalar alpha) 2417f0b747eeSBarry Smith { 2418f0b747eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)inA->data; 2419f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 2420efee365bSSatish Balay PetscErrorCode ierr; 2421c5df96a5SBarry Smith PetscBLASInt one = 1,bnz; 24223a40ed3dSBarry Smith 24233a40ed3dSBarry Smith PetscFunctionBegin; 2424c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->nz,&bnz);CHKERRQ(ierr); 24258b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&bnz,&oalpha,a->a,&one)); 2426efee365bSSatish Balay ierr = PetscLogFlops(a->nz);CHKERRQ(ierr); 2427acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(inA);CHKERRQ(ierr); 24283a40ed3dSBarry Smith PetscFunctionReturn(0); 2429f0b747eeSBarry Smith } 2430f0b747eeSBarry Smith 24315c39f6d9SHong Zhang PetscErrorCode MatDestroySubMatrices_Private(Mat_SubSppt *submatj) 243216b64355SHong Zhang { 243316b64355SHong Zhang PetscErrorCode ierr; 243416b64355SHong Zhang PetscInt i; 243516b64355SHong Zhang 243616b64355SHong Zhang PetscFunctionBegin; 243716b64355SHong Zhang if (!submatj->id) { /* delete data that are linked only to submats[id=0] */ 243816b64355SHong Zhang ierr = PetscFree4(submatj->sbuf1,submatj->ptr,submatj->tmp,submatj->ctr);CHKERRQ(ierr); 243916b64355SHong Zhang 244016b64355SHong Zhang for (i=0; i<submatj->nrqr; ++i) { 244116b64355SHong Zhang ierr = PetscFree(submatj->sbuf2[i]);CHKERRQ(ierr); 244216b64355SHong Zhang } 244316b64355SHong Zhang ierr = PetscFree3(submatj->sbuf2,submatj->req_size,submatj->req_source1);CHKERRQ(ierr); 244416b64355SHong Zhang 244516b64355SHong Zhang if (submatj->rbuf1) { 244616b64355SHong Zhang ierr = PetscFree(submatj->rbuf1[0]);CHKERRQ(ierr); 244716b64355SHong Zhang ierr = PetscFree(submatj->rbuf1);CHKERRQ(ierr); 244816b64355SHong Zhang } 244916b64355SHong Zhang 245016b64355SHong Zhang for (i=0; i<submatj->nrqs; ++i) { 245116b64355SHong Zhang ierr = PetscFree(submatj->rbuf3[i]);CHKERRQ(ierr); 245216b64355SHong Zhang } 245316b64355SHong Zhang ierr = PetscFree3(submatj->req_source2,submatj->rbuf2,submatj->rbuf3);CHKERRQ(ierr); 245416b64355SHong Zhang ierr = PetscFree(submatj->pa);CHKERRQ(ierr); 245516b64355SHong Zhang } 245616b64355SHong Zhang 245716b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 245816b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->rmap);CHKERRQ(ierr); 245916b64355SHong Zhang if (submatj->cmap_loc) {ierr = PetscFree(submatj->cmap_loc);CHKERRQ(ierr);} 246016b64355SHong Zhang ierr = PetscFree(submatj->rmap_loc);CHKERRQ(ierr); 246116b64355SHong Zhang #else 246216b64355SHong Zhang ierr = PetscFree(submatj->rmap);CHKERRQ(ierr); 246316b64355SHong Zhang #endif 246416b64355SHong Zhang 246516b64355SHong Zhang if (!submatj->allcolumns) { 246616b64355SHong Zhang #if defined(PETSC_USE_CTABLE) 246716b64355SHong Zhang ierr = PetscTableDestroy((PetscTable*)&submatj->cmap);CHKERRQ(ierr); 246816b64355SHong Zhang #else 246916b64355SHong Zhang ierr = PetscFree(submatj->cmap);CHKERRQ(ierr); 247016b64355SHong Zhang #endif 247116b64355SHong Zhang } 247216b64355SHong Zhang ierr = PetscFree(submatj->row2proc);CHKERRQ(ierr); 247316b64355SHong Zhang 247416b64355SHong Zhang ierr = PetscFree(submatj);CHKERRQ(ierr); 247516b64355SHong Zhang PetscFunctionReturn(0); 247616b64355SHong Zhang } 247716b64355SHong Zhang 247816b64355SHong Zhang PetscErrorCode MatDestroy_SeqAIJ_Submatrices(Mat C) 247916b64355SHong Zhang { 248016b64355SHong Zhang PetscErrorCode ierr; 248116b64355SHong Zhang Mat_SeqAIJ *c = (Mat_SeqAIJ*)C->data; 24825c39f6d9SHong Zhang Mat_SubSppt *submatj = c->submatis1; 248316b64355SHong Zhang 248416b64355SHong Zhang PetscFunctionBegin; 248516b64355SHong Zhang ierr = submatj->destroy(C);CHKERRQ(ierr); 2486e69d178cSHong Zhang ierr = MatDestroySubMatrices_Private(submatj);CHKERRQ(ierr); 248716b64355SHong Zhang PetscFunctionReturn(0); 248816b64355SHong Zhang } 248916b64355SHong Zhang 24907dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrices_SeqAIJ(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2491cddf8d76SBarry Smith { 2492dfbe8321SBarry Smith PetscErrorCode ierr; 249397f1f81fSBarry Smith PetscInt i; 2494cddf8d76SBarry Smith 24953a40ed3dSBarry Smith PetscFunctionBegin; 2496cddf8d76SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 2497df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 2498cddf8d76SBarry Smith } 2499cddf8d76SBarry Smith 2500cddf8d76SBarry Smith for (i=0; i<n; i++) { 25017dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqAIJ(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 2502cddf8d76SBarry Smith } 25033a40ed3dSBarry Smith PetscFunctionReturn(0); 2504cddf8d76SBarry Smith } 2505cddf8d76SBarry Smith 250697f1f81fSBarry Smith PetscErrorCode MatIncreaseOverlap_SeqAIJ(Mat A,PetscInt is_max,IS is[],PetscInt ov) 25074dcbc457SBarry Smith { 2508e4d965acSSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25096849ba73SBarry Smith PetscErrorCode ierr; 25105d0c19d7SBarry Smith PetscInt row,i,j,k,l,m,n,*nidx,isz,val; 25115d0c19d7SBarry Smith const PetscInt *idx; 251297f1f81fSBarry Smith PetscInt start,end,*ai,*aj; 2513f1af5d2fSBarry Smith PetscBT table; 2514bbd702dbSSatish Balay 25153a40ed3dSBarry Smith PetscFunctionBegin; 2516d0f46423SBarry Smith m = A->rmap->n; 2517e4d965acSSatish Balay ai = a->i; 2518bfeeae90SHong Zhang aj = a->j; 25198a047759SSatish Balay 2520e32f2f54SBarry Smith if (ov < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"illegal negative overlap value used"); 252106763907SSatish Balay 2522854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&nidx);CHKERRQ(ierr); 252353b8de81SBarry Smith ierr = PetscBTCreate(m,&table);CHKERRQ(ierr); 252406763907SSatish Balay 2525e4d965acSSatish Balay for (i=0; i<is_max; i++) { 2526b97fc60eSLois Curfman McInnes /* Initialize the two local arrays */ 2527e4d965acSSatish Balay isz = 0; 25286831982aSBarry Smith ierr = PetscBTMemzero(m,table);CHKERRQ(ierr); 2529e4d965acSSatish Balay 2530e4d965acSSatish Balay /* Extract the indices, assume there can be duplicate entries */ 25314dcbc457SBarry Smith ierr = ISGetIndices(is[i],&idx);CHKERRQ(ierr); 2532b9b97703SBarry Smith ierr = ISGetLocalSize(is[i],&n);CHKERRQ(ierr); 2533e4d965acSSatish Balay 2534dd097bc3SLois Curfman McInnes /* Enter these into the temp arrays. I.e., mark table[row], enter row into new index */ 2535e4d965acSSatish Balay for (j=0; j<n; ++j) { 25362205254eSKarl Rupp if (!PetscBTLookupSet(table,idx[j])) nidx[isz++] = idx[j]; 25374dcbc457SBarry Smith } 253806763907SSatish Balay ierr = ISRestoreIndices(is[i],&idx);CHKERRQ(ierr); 25396bf464f9SBarry Smith ierr = ISDestroy(&is[i]);CHKERRQ(ierr); 2540e4d965acSSatish Balay 254104a348a9SBarry Smith k = 0; 254204a348a9SBarry Smith for (j=0; j<ov; j++) { /* for each overlap */ 254304a348a9SBarry Smith n = isz; 254406763907SSatish Balay for (; k<n; k++) { /* do only those rows in nidx[k], which are not done yet */ 2545e4d965acSSatish Balay row = nidx[k]; 2546e4d965acSSatish Balay start = ai[row]; 2547e4d965acSSatish Balay end = ai[row+1]; 254804a348a9SBarry Smith for (l = start; l<end; l++) { 2549efb16452SHong Zhang val = aj[l]; 25502205254eSKarl Rupp if (!PetscBTLookupSet(table,val)) nidx[isz++] = val; 2551e4d965acSSatish Balay } 2552e4d965acSSatish Balay } 2553e4d965acSSatish Balay } 255470b3c8c7SBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,isz,nidx,PETSC_COPY_VALUES,(is+i));CHKERRQ(ierr); 2555e4d965acSSatish Balay } 255694bacf5dSBarry Smith ierr = PetscBTDestroy(&table);CHKERRQ(ierr); 2557606d414cSSatish Balay ierr = PetscFree(nidx);CHKERRQ(ierr); 25583a40ed3dSBarry Smith PetscFunctionReturn(0); 25594dcbc457SBarry Smith } 256017ab2063SBarry Smith 25610513a670SBarry Smith /* -------------------------------------------------------------- */ 2562dfbe8321SBarry Smith PetscErrorCode MatPermute_SeqAIJ(Mat A,IS rowp,IS colp,Mat *B) 25630513a670SBarry Smith { 25640513a670SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 25656849ba73SBarry Smith PetscErrorCode ierr; 25663b98c0a2SBarry Smith PetscInt i,nz = 0,m = A->rmap->n,n = A->cmap->n; 25675d0c19d7SBarry Smith const PetscInt *row,*col; 25685d0c19d7SBarry Smith PetscInt *cnew,j,*lens; 256956cd22aeSBarry Smith IS icolp,irowp; 25700298fd71SBarry Smith PetscInt *cwork = NULL; 25710298fd71SBarry Smith PetscScalar *vwork = NULL; 25720513a670SBarry Smith 25733a40ed3dSBarry Smith PetscFunctionBegin; 25744c49b128SBarry Smith ierr = ISInvertPermutation(rowp,PETSC_DECIDE,&irowp);CHKERRQ(ierr); 257556cd22aeSBarry Smith ierr = ISGetIndices(irowp,&row);CHKERRQ(ierr); 25764c49b128SBarry Smith ierr = ISInvertPermutation(colp,PETSC_DECIDE,&icolp);CHKERRQ(ierr); 257756cd22aeSBarry Smith ierr = ISGetIndices(icolp,&col);CHKERRQ(ierr); 25780513a670SBarry Smith 25790513a670SBarry Smith /* determine lengths of permuted rows */ 2580854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&lens);CHKERRQ(ierr); 25812205254eSKarl Rupp for (i=0; i<m; i++) lens[row[i]] = a->i[i+1] - a->i[i]; 2582ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 2583f69a0ea3SMatthew Knepley ierr = MatSetSizes(*B,m,n,m,n);CHKERRQ(ierr); 258433d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 25857adad957SLisandro Dalcin ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 2586ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*B,0,lens);CHKERRQ(ierr); 2587606d414cSSatish Balay ierr = PetscFree(lens);CHKERRQ(ierr); 25880513a670SBarry Smith 2589785e854fSJed Brown ierr = PetscMalloc1(n,&cnew);CHKERRQ(ierr); 25900513a670SBarry Smith for (i=0; i<m; i++) { 259132ec9ce4SBarry Smith ierr = MatGetRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25922205254eSKarl Rupp for (j=0; j<nz; j++) cnew[j] = col[cwork[j]]; 2593cdc0ba36SBarry Smith ierr = MatSetValues_SeqAIJ(*B,1,&row[i],nz,cnew,vwork,INSERT_VALUES);CHKERRQ(ierr); 259432ec9ce4SBarry Smith ierr = MatRestoreRow_SeqAIJ(A,i,&nz,&cwork,&vwork);CHKERRQ(ierr); 25950513a670SBarry Smith } 2596606d414cSSatish Balay ierr = PetscFree(cnew);CHKERRQ(ierr); 25972205254eSKarl Rupp 25983c7d62e4SBarry Smith (*B)->assembled = PETSC_FALSE; 25992205254eSKarl Rupp 26000513a670SBarry Smith ierr = MatAssemblyBegin(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 26010513a670SBarry Smith ierr = MatAssemblyEnd(*B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 260256cd22aeSBarry Smith ierr = ISRestoreIndices(irowp,&row);CHKERRQ(ierr); 260356cd22aeSBarry Smith ierr = ISRestoreIndices(icolp,&col);CHKERRQ(ierr); 26046bf464f9SBarry Smith ierr = ISDestroy(&irowp);CHKERRQ(ierr); 26056bf464f9SBarry Smith ierr = ISDestroy(&icolp);CHKERRQ(ierr); 26063a40ed3dSBarry Smith PetscFunctionReturn(0); 26070513a670SBarry Smith } 26080513a670SBarry Smith 2609dfbe8321SBarry Smith PetscErrorCode MatCopy_SeqAIJ(Mat A,Mat B,MatStructure str) 2610cb5b572fSBarry Smith { 2611dfbe8321SBarry Smith PetscErrorCode ierr; 2612cb5b572fSBarry Smith 2613cb5b572fSBarry Smith PetscFunctionBegin; 261433f4a19fSKris Buschelman /* If the two matrices have the same copy implementation, use fast copy. */ 261533f4a19fSKris Buschelman if (str == SAME_NONZERO_PATTERN && (A->ops->copy == B->ops->copy)) { 2616be6bf707SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2617be6bf707SBarry Smith Mat_SeqAIJ *b = (Mat_SeqAIJ*)B->data; 2618be6bf707SBarry Smith 2619700c5bfcSBarry 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"); 2620d0f46423SBarry Smith ierr = PetscMemcpy(b->a,a->a,(a->i[A->rmap->n])*sizeof(PetscScalar));CHKERRQ(ierr); 2621cb5b572fSBarry Smith } else { 2622cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 2623cb5b572fSBarry Smith } 2624cb5b572fSBarry Smith PetscFunctionReturn(0); 2625cb5b572fSBarry Smith } 2626cb5b572fSBarry Smith 26274994cf47SJed Brown PetscErrorCode MatSetUp_SeqAIJ(Mat A) 2628273d9f13SBarry Smith { 2629dfbe8321SBarry Smith PetscErrorCode ierr; 2630273d9f13SBarry Smith 2631273d9f13SBarry Smith PetscFunctionBegin; 2632ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(A,PETSC_DEFAULT,0);CHKERRQ(ierr); 2633273d9f13SBarry Smith PetscFunctionReturn(0); 2634273d9f13SBarry Smith } 2635273d9f13SBarry Smith 26368c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray_SeqAIJ(Mat A,PetscScalar *array[]) 26376c0721eeSBarry Smith { 26386c0721eeSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 26396e111a19SKarl Rupp 26406c0721eeSBarry Smith PetscFunctionBegin; 26416c0721eeSBarry Smith *array = a->a; 26426c0721eeSBarry Smith PetscFunctionReturn(0); 26436c0721eeSBarry Smith } 26446c0721eeSBarry Smith 26458c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray_SeqAIJ(Mat A,PetscScalar *array[]) 26466c0721eeSBarry Smith { 26476c0721eeSBarry Smith PetscFunctionBegin; 26486c0721eeSBarry Smith PetscFunctionReturn(0); 26496c0721eeSBarry Smith } 2650273d9f13SBarry Smith 26518229c054SShri Abhyankar /* 26528229c054SShri Abhyankar Computes the number of nonzeros per row needed for preallocation when X and Y 26538229c054SShri Abhyankar have different nonzero structure. 26548229c054SShri Abhyankar */ 2655b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqX_private(PetscInt m,const PetscInt *xi,const PetscInt *xj,const PetscInt *yi,const PetscInt *yj,PetscInt *nnz) 2656ec7775f6SShri Abhyankar { 2657b264fe52SHong Zhang PetscInt i,j,k,nzx,nzy; 2658ec7775f6SShri Abhyankar 2659ec7775f6SShri Abhyankar PetscFunctionBegin; 2660ec7775f6SShri Abhyankar /* Set the number of nonzeros in the new matrix */ 2661ec7775f6SShri Abhyankar for (i=0; i<m; i++) { 2662b264fe52SHong Zhang const PetscInt *xjj = xj+xi[i],*yjj = yj+yi[i]; 2663b264fe52SHong Zhang nzx = xi[i+1] - xi[i]; 2664b264fe52SHong Zhang nzy = yi[i+1] - yi[i]; 26658af7cee1SJed Brown nnz[i] = 0; 26668af7cee1SJed Brown for (j=0,k=0; j<nzx; j++) { /* Point in X */ 2667b264fe52SHong Zhang for (; k<nzy && yjj[k]<xjj[j]; k++) nnz[i]++; /* Catch up to X */ 2668b264fe52SHong Zhang if (k<nzy && yjj[k]==xjj[j]) k++; /* Skip duplicate */ 26698af7cee1SJed Brown nnz[i]++; 26708af7cee1SJed Brown } 26718af7cee1SJed Brown for (; k<nzy; k++) nnz[i]++; 2672ec7775f6SShri Abhyankar } 2673ec7775f6SShri Abhyankar PetscFunctionReturn(0); 2674ec7775f6SShri Abhyankar } 2675ec7775f6SShri Abhyankar 2676b264fe52SHong Zhang PetscErrorCode MatAXPYGetPreallocation_SeqAIJ(Mat Y,Mat X,PetscInt *nnz) 2677b264fe52SHong Zhang { 2678b264fe52SHong Zhang PetscInt m = Y->rmap->N; 2679b264fe52SHong Zhang Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data; 2680b264fe52SHong Zhang Mat_SeqAIJ *y = (Mat_SeqAIJ*)Y->data; 2681b264fe52SHong Zhang PetscErrorCode ierr; 2682b264fe52SHong Zhang 2683b264fe52SHong Zhang PetscFunctionBegin; 2684b264fe52SHong Zhang /* Set the number of nonzeros in the new matrix */ 2685b264fe52SHong Zhang ierr = MatAXPYGetPreallocation_SeqX_private(m,x->i,x->j,y->i,y->j,nnz);CHKERRQ(ierr); 2686b264fe52SHong Zhang PetscFunctionReturn(0); 2687b264fe52SHong Zhang } 2688b264fe52SHong Zhang 2689f4df32b1SMatthew Knepley PetscErrorCode MatAXPY_SeqAIJ(Mat Y,PetscScalar a,Mat X,MatStructure str) 2690ac90fabeSBarry Smith { 2691dfbe8321SBarry Smith PetscErrorCode ierr; 2692ac90fabeSBarry Smith Mat_SeqAIJ *x = (Mat_SeqAIJ*)X->data,*y = (Mat_SeqAIJ*)Y->data; 2693c5df96a5SBarry Smith PetscBLASInt one=1,bnz; 2694ac90fabeSBarry Smith 2695ac90fabeSBarry Smith PetscFunctionBegin; 2696c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->nz,&bnz);CHKERRQ(ierr); 2697ac90fabeSBarry Smith if (str == SAME_NONZERO_PATTERN) { 2698f4df32b1SMatthew Knepley PetscScalar alpha = a; 26998b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&bnz,&alpha,x->a,&one,y->a,&one)); 2700acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal(Y);CHKERRQ(ierr); 2701a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2702ab784542SHong Zhang } else if (str == SUBSET_NONZERO_PATTERN) { /* nonzeros of X is a subset of Y's */ 2703ab784542SHong Zhang ierr = MatAXPY_Basic(Y,a,X,str);CHKERRQ(ierr); 2704ac90fabeSBarry Smith } else { 27058229c054SShri Abhyankar Mat B; 27068229c054SShri Abhyankar PetscInt *nnz; 2707785e854fSJed Brown ierr = PetscMalloc1(Y->rmap->N,&nnz);CHKERRQ(ierr); 2708ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)Y),&B);CHKERRQ(ierr); 2709bc5a2726SShri Abhyankar ierr = PetscObjectSetName((PetscObject)B,((PetscObject)Y)->name);CHKERRQ(ierr); 27104aa94f47SShri Abhyankar ierr = MatSetSizes(B,Y->rmap->n,Y->cmap->n,Y->rmap->N,Y->cmap->N);CHKERRQ(ierr); 271133d57670SJed Brown ierr = MatSetBlockSizesFromMats(B,Y,Y);CHKERRQ(ierr); 2712176df525SBarry Smith ierr = MatSetType(B,(MatType) ((PetscObject)Y)->type_name);CHKERRQ(ierr); 27138229c054SShri Abhyankar ierr = MatAXPYGetPreallocation_SeqAIJ(Y,X,nnz);CHKERRQ(ierr); 2714ecd8bba6SJed Brown ierr = MatSeqAIJSetPreallocation(B,0,nnz);CHKERRQ(ierr); 2715ec7775f6SShri Abhyankar ierr = MatAXPY_BasicWithPreallocation(B,Y,a,X,str);CHKERRQ(ierr); 271628be2f97SBarry Smith ierr = MatHeaderReplace(Y,&B);CHKERRQ(ierr); 27178229c054SShri Abhyankar ierr = PetscFree(nnz);CHKERRQ(ierr); 2718ac90fabeSBarry Smith } 2719ac90fabeSBarry Smith PetscFunctionReturn(0); 2720ac90fabeSBarry Smith } 2721ac90fabeSBarry Smith 27227087cfbeSBarry Smith PetscErrorCode MatConjugate_SeqAIJ(Mat mat) 2723354c94deSBarry Smith { 2724354c94deSBarry Smith #if defined(PETSC_USE_COMPLEX) 2725354c94deSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 2726354c94deSBarry Smith PetscInt i,nz; 2727354c94deSBarry Smith PetscScalar *a; 2728354c94deSBarry Smith 2729354c94deSBarry Smith PetscFunctionBegin; 2730354c94deSBarry Smith nz = aij->nz; 2731354c94deSBarry Smith a = aij->a; 27322205254eSKarl Rupp for (i=0; i<nz; i++) a[i] = PetscConj(a[i]); 2733354c94deSBarry Smith #else 2734354c94deSBarry Smith PetscFunctionBegin; 2735354c94deSBarry Smith #endif 2736354c94deSBarry Smith PetscFunctionReturn(0); 2737354c94deSBarry Smith } 2738354c94deSBarry Smith 2739985db425SBarry Smith PetscErrorCode MatGetRowMaxAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2740e34fafa9SBarry Smith { 2741e34fafa9SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2742e34fafa9SBarry Smith PetscErrorCode ierr; 2743d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2744e34fafa9SBarry Smith PetscReal atmp; 2745985db425SBarry Smith PetscScalar *x; 2746e34fafa9SBarry Smith MatScalar *aa; 2747e34fafa9SBarry Smith 2748e34fafa9SBarry Smith PetscFunctionBegin; 2749e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2750e34fafa9SBarry Smith aa = a->a; 2751e34fafa9SBarry Smith ai = a->i; 2752e34fafa9SBarry Smith aj = a->j; 2753e34fafa9SBarry Smith 2754985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2755e34fafa9SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2756e34fafa9SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2757e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2758e34fafa9SBarry Smith for (i=0; i<m; i++) { 2759e34fafa9SBarry Smith ncols = ai[1] - ai[0]; ai++; 27609189402eSHong Zhang x[i] = 0.0; 2761e34fafa9SBarry Smith for (j=0; j<ncols; j++) { 2762985db425SBarry Smith atmp = PetscAbsScalar(*aa); 2763985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2764985db425SBarry Smith aa++; aj++; 2765985db425SBarry Smith } 2766985db425SBarry Smith } 2767985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2768985db425SBarry Smith PetscFunctionReturn(0); 2769985db425SBarry Smith } 2770985db425SBarry Smith 2771985db425SBarry Smith PetscErrorCode MatGetRowMax_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2772985db425SBarry Smith { 2773985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2774985db425SBarry Smith PetscErrorCode ierr; 2775d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2776985db425SBarry Smith PetscScalar *x; 2777985db425SBarry Smith MatScalar *aa; 2778985db425SBarry Smith 2779985db425SBarry Smith PetscFunctionBegin; 2780e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2781985db425SBarry Smith aa = a->a; 2782985db425SBarry Smith ai = a->i; 2783985db425SBarry Smith aj = a->j; 2784985db425SBarry Smith 2785985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2786985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2787985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2788e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2789985db425SBarry Smith for (i=0; i<m; i++) { 2790985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2791d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2792985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2793985db425SBarry Smith } else { /* row is sparse so already KNOW maximum is 0.0 or higher */ 2794985db425SBarry Smith x[i] = 0.0; 2795985db425SBarry Smith if (idx) { 2796985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2797985db425SBarry Smith for (j=0;j<ncols;j++) { /* find first implicit 0.0 in the row */ 2798985db425SBarry Smith if (aj[j] > j) { 2799985db425SBarry Smith idx[i] = j; 2800985db425SBarry Smith break; 2801985db425SBarry Smith } 2802985db425SBarry Smith } 2803985db425SBarry Smith } 2804985db425SBarry Smith } 2805985db425SBarry Smith for (j=0; j<ncols; j++) { 2806985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2807985db425SBarry Smith aa++; aj++; 2808985db425SBarry Smith } 2809985db425SBarry Smith } 2810985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2811985db425SBarry Smith PetscFunctionReturn(0); 2812985db425SBarry Smith } 2813985db425SBarry Smith 2814c87e5d42SMatthew Knepley PetscErrorCode MatGetRowMinAbs_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2815c87e5d42SMatthew Knepley { 2816c87e5d42SMatthew Knepley Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2817c87e5d42SMatthew Knepley PetscErrorCode ierr; 2818c87e5d42SMatthew Knepley PetscInt i,j,m = A->rmap->n,*ai,*aj,ncols,n; 2819c87e5d42SMatthew Knepley PetscReal atmp; 2820c87e5d42SMatthew Knepley PetscScalar *x; 2821c87e5d42SMatthew Knepley MatScalar *aa; 2822c87e5d42SMatthew Knepley 2823c87e5d42SMatthew Knepley PetscFunctionBegin; 2824e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2825c87e5d42SMatthew Knepley aa = a->a; 2826c87e5d42SMatthew Knepley ai = a->i; 2827c87e5d42SMatthew Knepley aj = a->j; 2828c87e5d42SMatthew Knepley 2829c87e5d42SMatthew Knepley ierr = VecSet(v,0.0);CHKERRQ(ierr); 2830c87e5d42SMatthew Knepley ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2831c87e5d42SMatthew Knepley ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 283260e0710aSBarry Smith 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); 2833c87e5d42SMatthew Knepley for (i=0; i<m; i++) { 2834c87e5d42SMatthew Knepley ncols = ai[1] - ai[0]; ai++; 2835289a08f5SMatthew Knepley if (ncols) { 2836289a08f5SMatthew Knepley /* Get first nonzero */ 2837289a08f5SMatthew Knepley for (j = 0; j < ncols; j++) { 2838289a08f5SMatthew Knepley atmp = PetscAbsScalar(aa[j]); 28392205254eSKarl Rupp if (atmp > 1.0e-12) { 28402205254eSKarl Rupp x[i] = atmp; 28412205254eSKarl Rupp if (idx) idx[i] = aj[j]; 28422205254eSKarl Rupp break; 28432205254eSKarl Rupp } 2844289a08f5SMatthew Knepley } 284512431cb0SMatthew G Knepley if (j == ncols) {x[i] = PetscAbsScalar(*aa); if (idx) idx[i] = *aj;} 2846289a08f5SMatthew Knepley } else { 2847289a08f5SMatthew Knepley x[i] = 0.0; if (idx) idx[i] = 0; 2848289a08f5SMatthew Knepley } 2849c87e5d42SMatthew Knepley for (j = 0; j < ncols; j++) { 2850c87e5d42SMatthew Knepley atmp = PetscAbsScalar(*aa); 2851289a08f5SMatthew Knepley if (atmp > 1.0e-12 && PetscAbsScalar(x[i]) > atmp) {x[i] = atmp; if (idx) idx[i] = *aj;} 2852c87e5d42SMatthew Knepley aa++; aj++; 2853c87e5d42SMatthew Knepley } 2854c87e5d42SMatthew Knepley } 2855c87e5d42SMatthew Knepley ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2856c87e5d42SMatthew Knepley PetscFunctionReturn(0); 2857c87e5d42SMatthew Knepley } 2858c87e5d42SMatthew Knepley 2859985db425SBarry Smith PetscErrorCode MatGetRowMin_SeqAIJ(Mat A,Vec v,PetscInt idx[]) 2860985db425SBarry Smith { 2861985db425SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 2862985db425SBarry Smith PetscErrorCode ierr; 2863d9ca1df4SBarry Smith PetscInt i,j,m = A->rmap->n,ncols,n; 2864d9ca1df4SBarry Smith const PetscInt *ai,*aj; 2865985db425SBarry Smith PetscScalar *x; 2866d9ca1df4SBarry Smith const MatScalar *aa; 2867985db425SBarry Smith 2868985db425SBarry Smith PetscFunctionBegin; 2869e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2870985db425SBarry Smith aa = a->a; 2871985db425SBarry Smith ai = a->i; 2872985db425SBarry Smith aj = a->j; 2873985db425SBarry Smith 2874985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2875985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2876985db425SBarry Smith ierr = VecGetLocalSize(v,&n);CHKERRQ(ierr); 2877e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2878985db425SBarry Smith for (i=0; i<m; i++) { 2879985db425SBarry Smith ncols = ai[1] - ai[0]; ai++; 2880d0f46423SBarry Smith if (ncols == A->cmap->n) { /* row is dense */ 2881985db425SBarry Smith x[i] = *aa; if (idx) idx[i] = 0; 2882985db425SBarry Smith } else { /* row is sparse so already KNOW minimum is 0.0 or lower */ 2883985db425SBarry Smith x[i] = 0.0; 2884985db425SBarry Smith if (idx) { /* find first implicit 0.0 in the row */ 2885985db425SBarry Smith idx[i] = 0; /* in case ncols is zero */ 2886985db425SBarry Smith for (j=0; j<ncols; j++) { 2887985db425SBarry Smith if (aj[j] > j) { 2888985db425SBarry Smith idx[i] = j; 2889985db425SBarry Smith break; 2890985db425SBarry Smith } 2891985db425SBarry Smith } 2892985db425SBarry Smith } 2893985db425SBarry Smith } 2894985db425SBarry Smith for (j=0; j<ncols; j++) { 2895985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(*aa)) {x[i] = *aa; if (idx) idx[i] = *aj;} 2896985db425SBarry Smith aa++; aj++; 2897e34fafa9SBarry Smith } 2898e34fafa9SBarry Smith } 2899e34fafa9SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2900e34fafa9SBarry Smith PetscFunctionReturn(0); 2901e34fafa9SBarry Smith } 2902bbead8a2SBarry Smith 2903bbead8a2SBarry Smith #include <petscblaslapack.h> 2904af0996ceSBarry Smith #include <petsc/private/kernels/blockinvert.h> 2905bbead8a2SBarry Smith 2906713ccfa9SJed Brown PetscErrorCode MatInvertBlockDiagonal_SeqAIJ(Mat A,const PetscScalar **values) 2907bbead8a2SBarry Smith { 2908bbead8a2SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*) A->data; 2909bbead8a2SBarry Smith PetscErrorCode ierr; 291033d57670SJed Brown PetscInt i,bs = PetscAbs(A->rmap->bs),mbs = A->rmap->n/bs,ipvt[5],bs2 = bs*bs,*v_pivots,ij[7],*IJ,j; 2911bbead8a2SBarry Smith MatScalar *diag,work[25],*v_work; 2912bbead8a2SBarry Smith PetscReal shift = 0.0; 29131a9391e3SHong Zhang PetscBool allowzeropivot,zeropivotdetected=PETSC_FALSE; 2914bbead8a2SBarry Smith 2915bbead8a2SBarry Smith PetscFunctionBegin; 2916a455e926SHong Zhang allowzeropivot = PetscNot(A->erroriffailure); 29174a0d0026SBarry Smith if (a->ibdiagvalid) { 29184a0d0026SBarry Smith if (values) *values = a->ibdiag; 29194a0d0026SBarry Smith PetscFunctionReturn(0); 29204a0d0026SBarry Smith } 2921bbead8a2SBarry Smith ierr = MatMarkDiagonal_SeqAIJ(A);CHKERRQ(ierr); 2922bbead8a2SBarry Smith if (!a->ibdiag) { 2923785e854fSJed Brown ierr = PetscMalloc1(bs2*mbs,&a->ibdiag);CHKERRQ(ierr); 29243bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,bs2*mbs*sizeof(PetscScalar));CHKERRQ(ierr); 2925bbead8a2SBarry Smith } 2926bbead8a2SBarry Smith diag = a->ibdiag; 2927bbead8a2SBarry Smith if (values) *values = a->ibdiag; 2928bbead8a2SBarry Smith /* factor and invert each block */ 2929bbead8a2SBarry Smith switch (bs) { 2930bbead8a2SBarry Smith case 1: 2931bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2932bbead8a2SBarry Smith ierr = MatGetValues(A,1,&i,1,&i,diag+i);CHKERRQ(ierr); 2933ec1892c8SHong Zhang if (PetscAbsScalar(diag[i] + shift) < PETSC_MACHINE_EPSILON) { 2934ec1892c8SHong Zhang if (allowzeropivot) { 29357b6c816cSBarry Smith A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 29367b6c816cSBarry Smith A->factorerror_zeropivot_value = PetscAbsScalar(diag[i]); 29377b6c816cSBarry Smith A->factorerror_zeropivot_row = i; 29387b6c816cSBarry Smith ierr = PetscInfo3(A,"Zero pivot, row %D pivot %g tolerance %g\n",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON);CHKERRQ(ierr); 29397b6c816cSBarry Smith } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Zero pivot, row %D pivot %g tolerance %g",i,(double)PetscAbsScalar(diag[i]),(double)PETSC_MACHINE_EPSILON); 2940ec1892c8SHong Zhang } 2941bbead8a2SBarry Smith diag[i] = (PetscScalar)1.0 / (diag[i] + shift); 2942bbead8a2SBarry Smith } 2943bbead8a2SBarry Smith break; 2944bbead8a2SBarry Smith case 2: 2945bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2946bbead8a2SBarry Smith ij[0] = 2*i; ij[1] = 2*i + 1; 2947bbead8a2SBarry Smith ierr = MatGetValues(A,2,ij,2,ij,diag);CHKERRQ(ierr); 2948a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_2(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29497b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 295096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_2(diag);CHKERRQ(ierr); 2951bbead8a2SBarry Smith diag += 4; 2952bbead8a2SBarry Smith } 2953bbead8a2SBarry Smith break; 2954bbead8a2SBarry Smith case 3: 2955bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2956bbead8a2SBarry Smith ij[0] = 3*i; ij[1] = 3*i + 1; ij[2] = 3*i + 2; 2957bbead8a2SBarry Smith ierr = MatGetValues(A,3,ij,3,ij,diag);CHKERRQ(ierr); 2958a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_3(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29597b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 296096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_3(diag);CHKERRQ(ierr); 2961bbead8a2SBarry Smith diag += 9; 2962bbead8a2SBarry Smith } 2963bbead8a2SBarry Smith break; 2964bbead8a2SBarry Smith case 4: 2965bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2966bbead8a2SBarry Smith ij[0] = 4*i; ij[1] = 4*i + 1; ij[2] = 4*i + 2; ij[3] = 4*i + 3; 2967bbead8a2SBarry Smith ierr = MatGetValues(A,4,ij,4,ij,diag);CHKERRQ(ierr); 2968a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_4(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29697b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 297096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_4(diag);CHKERRQ(ierr); 2971bbead8a2SBarry Smith diag += 16; 2972bbead8a2SBarry Smith } 2973bbead8a2SBarry Smith break; 2974bbead8a2SBarry Smith case 5: 2975bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2976bbead8a2SBarry 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; 2977bbead8a2SBarry Smith ierr = MatGetValues(A,5,ij,5,ij,diag);CHKERRQ(ierr); 2978a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_5(diag,ipvt,work,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29797b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 298096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_5(diag);CHKERRQ(ierr); 2981bbead8a2SBarry Smith diag += 25; 2982bbead8a2SBarry Smith } 2983bbead8a2SBarry Smith break; 2984bbead8a2SBarry Smith case 6: 2985bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2986bbead8a2SBarry 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; 2987bbead8a2SBarry Smith ierr = MatGetValues(A,6,ij,6,ij,diag);CHKERRQ(ierr); 2988a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_6(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29897b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 299096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_6(diag);CHKERRQ(ierr); 2991bbead8a2SBarry Smith diag += 36; 2992bbead8a2SBarry Smith } 2993bbead8a2SBarry Smith break; 2994bbead8a2SBarry Smith case 7: 2995bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 2996bbead8a2SBarry 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; 2997bbead8a2SBarry Smith ierr = MatGetValues(A,7,ij,7,ij,diag);CHKERRQ(ierr); 2998a455e926SHong Zhang ierr = PetscKernel_A_gets_inverse_A_7(diag,shift,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 29997b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 300096b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_7(diag);CHKERRQ(ierr); 3001bbead8a2SBarry Smith diag += 49; 3002bbead8a2SBarry Smith } 3003bbead8a2SBarry Smith break; 3004bbead8a2SBarry Smith default: 3005dcca6d9dSJed Brown ierr = PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ);CHKERRQ(ierr); 3006bbead8a2SBarry Smith for (i=0; i<mbs; i++) { 3007bbead8a2SBarry Smith for (j=0; j<bs; j++) { 3008bbead8a2SBarry Smith IJ[j] = bs*i + j; 3009bbead8a2SBarry Smith } 3010bbead8a2SBarry Smith ierr = MatGetValues(A,bs,IJ,bs,IJ,diag);CHKERRQ(ierr); 30115f8bbccaSHong Zhang ierr = PetscKernel_A_gets_inverse_A(bs,diag,v_pivots,v_work,allowzeropivot,&zeropivotdetected);CHKERRQ(ierr); 30127b6c816cSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 301396b95a6bSBarry Smith ierr = PetscKernel_A_gets_transpose_A_N(diag,bs);CHKERRQ(ierr); 3014bbead8a2SBarry Smith diag += bs2; 3015bbead8a2SBarry Smith } 3016bbead8a2SBarry Smith ierr = PetscFree3(v_work,v_pivots,IJ);CHKERRQ(ierr); 3017bbead8a2SBarry Smith } 3018bbead8a2SBarry Smith a->ibdiagvalid = PETSC_TRUE; 3019bbead8a2SBarry Smith PetscFunctionReturn(0); 3020bbead8a2SBarry Smith } 3021bbead8a2SBarry Smith 302273a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqAIJ(Mat x,PetscRandom rctx) 302373a71a0fSBarry Smith { 302473a71a0fSBarry Smith PetscErrorCode ierr; 302573a71a0fSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)x->data; 302673a71a0fSBarry Smith PetscScalar a; 302773a71a0fSBarry Smith PetscInt m,n,i,j,col; 302873a71a0fSBarry Smith 302973a71a0fSBarry Smith PetscFunctionBegin; 303073a71a0fSBarry Smith if (!x->assembled) { 303173a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 303273a71a0fSBarry Smith for (i=0; i<m; i++) { 303373a71a0fSBarry Smith for (j=0; j<aij->imax[i]; j++) { 303473a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,&a);CHKERRQ(ierr); 303573a71a0fSBarry Smith col = (PetscInt)(n*PetscRealPart(a)); 303673a71a0fSBarry Smith ierr = MatSetValues(x,1,&i,1,&col,&a,ADD_VALUES);CHKERRQ(ierr); 303773a71a0fSBarry Smith } 303873a71a0fSBarry Smith } 303973a71a0fSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet coded"); 304073a71a0fSBarry Smith ierr = MatAssemblyBegin(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 304173a71a0fSBarry Smith ierr = MatAssemblyEnd(x,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 304273a71a0fSBarry Smith PetscFunctionReturn(0); 304373a71a0fSBarry Smith } 304473a71a0fSBarry Smith 30457d68702bSBarry Smith PetscErrorCode MatShift_SeqAIJ(Mat Y,PetscScalar a) 30467d68702bSBarry Smith { 30477d68702bSBarry Smith PetscErrorCode ierr; 30487d68702bSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)Y->data; 30497d68702bSBarry Smith 30507d68702bSBarry Smith PetscFunctionBegin; 30516f33a894SBarry Smith if (!Y->preallocated || !aij->nz) { 30527d68702bSBarry Smith ierr = MatSeqAIJSetPreallocation(Y,1,NULL);CHKERRQ(ierr); 30537d68702bSBarry Smith } 30547d68702bSBarry Smith ierr = MatShift_Basic(Y,a);CHKERRQ(ierr); 30557d68702bSBarry Smith PetscFunctionReturn(0); 30567d68702bSBarry Smith } 30577d68702bSBarry Smith 3058682d7d0cSBarry Smith /* -------------------------------------------------------------------*/ 30590a6ffc59SBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqAIJ, 3060cb5b572fSBarry Smith MatGetRow_SeqAIJ, 3061cb5b572fSBarry Smith MatRestoreRow_SeqAIJ, 3062cb5b572fSBarry Smith MatMult_SeqAIJ, 306397304618SKris Buschelman /* 4*/ MatMultAdd_SeqAIJ, 30647c922b88SBarry Smith MatMultTranspose_SeqAIJ, 30657c922b88SBarry Smith MatMultTransposeAdd_SeqAIJ, 3066db4efbfdSBarry Smith 0, 3067db4efbfdSBarry Smith 0, 3068db4efbfdSBarry Smith 0, 3069db4efbfdSBarry Smith /* 10*/ 0, 3070cb5b572fSBarry Smith MatLUFactor_SeqAIJ, 3071cb5b572fSBarry Smith 0, 307241f059aeSBarry Smith MatSOR_SeqAIJ, 307317ab2063SBarry Smith MatTranspose_SeqAIJ, 307497304618SKris Buschelman /*1 5*/ MatGetInfo_SeqAIJ, 3075cb5b572fSBarry Smith MatEqual_SeqAIJ, 3076cb5b572fSBarry Smith MatGetDiagonal_SeqAIJ, 3077cb5b572fSBarry Smith MatDiagonalScale_SeqAIJ, 3078cb5b572fSBarry Smith MatNorm_SeqAIJ, 307997304618SKris Buschelman /* 20*/ 0, 3080cb5b572fSBarry Smith MatAssemblyEnd_SeqAIJ, 3081cb5b572fSBarry Smith MatSetOption_SeqAIJ, 3082cb5b572fSBarry Smith MatZeroEntries_SeqAIJ, 3083d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqAIJ, 3084db4efbfdSBarry Smith 0, 3085db4efbfdSBarry Smith 0, 3086db4efbfdSBarry Smith 0, 3087db4efbfdSBarry Smith 0, 30884994cf47SJed Brown /* 29*/ MatSetUp_SeqAIJ, 3089db4efbfdSBarry Smith 0, 3090db4efbfdSBarry Smith 0, 30918c778c55SBarry Smith 0, 30928c778c55SBarry Smith 0, 3093d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqAIJ, 3094cb5b572fSBarry Smith 0, 3095cb5b572fSBarry Smith 0, 3096cb5b572fSBarry Smith MatILUFactor_SeqAIJ, 3097cb5b572fSBarry Smith 0, 3098d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqAIJ, 30997dae84e0SHong Zhang MatCreateSubMatrices_SeqAIJ, 3100cb5b572fSBarry Smith MatIncreaseOverlap_SeqAIJ, 3101cb5b572fSBarry Smith MatGetValues_SeqAIJ, 3102cb5b572fSBarry Smith MatCopy_SeqAIJ, 3103d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqAIJ, 3104cb5b572fSBarry Smith MatScale_SeqAIJ, 31057d68702bSBarry Smith MatShift_SeqAIJ, 310679299369SBarry Smith MatDiagonalSet_SeqAIJ, 31076e169961SBarry Smith MatZeroRowsColumns_SeqAIJ, 310873a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqAIJ, 31093b2fbd54SBarry Smith MatGetRowIJ_SeqAIJ, 31103b2fbd54SBarry Smith MatRestoreRowIJ_SeqAIJ, 31113b2fbd54SBarry Smith MatGetColumnIJ_SeqAIJ, 3112a93ec695SBarry Smith MatRestoreColumnIJ_SeqAIJ, 311393dfae19SHong Zhang /* 54*/ MatFDColoringCreate_SeqXAIJ, 3114b9617806SBarry Smith 0, 31150513a670SBarry Smith 0, 3116cda55fadSBarry Smith MatPermute_SeqAIJ, 3117cda55fadSBarry Smith 0, 3118d519adbfSMatthew Knepley /* 59*/ 0, 3119b9b97703SBarry Smith MatDestroy_SeqAIJ, 3120b9b97703SBarry Smith MatView_SeqAIJ, 3121357abbc8SBarry Smith 0, 3122321b30b9SSatish Balay MatMatMatMult_SeqAIJ_SeqAIJ_SeqAIJ, 3123321b30b9SSatish Balay /* 64*/ MatMatMatMultSymbolic_SeqAIJ_SeqAIJ_SeqAIJ, 3124321b30b9SSatish Balay MatMatMatMultNumeric_SeqAIJ_SeqAIJ_SeqAIJ, 3125ee4f033dSBarry Smith 0, 3126ee4f033dSBarry Smith 0, 3127ee4f033dSBarry Smith 0, 3128d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqAIJ, 3129c87e5d42SMatthew Knepley MatGetRowMinAbs_SeqAIJ, 3130ee4f033dSBarry Smith 0, 3131dcf5cc72SBarry Smith 0, 31322c93a97aSBarry Smith 0, 31332c93a97aSBarry Smith /* 74*/ 0, 31343acb8795SBarry Smith MatFDColoringApply_AIJ, 313597304618SKris Buschelman 0, 313697304618SKris Buschelman 0, 313797304618SKris Buschelman 0, 31386ce1633cSBarry Smith /* 79*/ MatFindZeroDiagonals_SeqAIJ, 313997304618SKris Buschelman 0, 314097304618SKris Buschelman 0, 314197304618SKris Buschelman 0, 3142bc011b1eSHong Zhang MatLoad_SeqAIJ, 3143d519adbfSMatthew Knepley /* 84*/ MatIsSymmetric_SeqAIJ, 31441cbb95d3SBarry Smith MatIsHermitian_SeqAIJ, 31456284ec50SHong Zhang 0, 31466284ec50SHong Zhang 0, 3147bc011b1eSHong Zhang 0, 3148d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqAIJ_SeqAIJ, 314926be0446SHong Zhang MatMatMultSymbolic_SeqAIJ_SeqAIJ, 315026be0446SHong Zhang MatMatMultNumeric_SeqAIJ_SeqAIJ, 315165e8a0caSHong Zhang MatPtAP_SeqAIJ_SeqAIJ, 31524a1b09b7SHong Zhang MatPtAPSymbolic_SeqAIJ_SeqAIJ_DenseAxpy, 315365e8a0caSHong Zhang /* 94*/ MatPtAPNumeric_SeqAIJ_SeqAIJ, 31546fc122caSHong Zhang MatMatTransposeMult_SeqAIJ_SeqAIJ, 31556fc122caSHong Zhang MatMatTransposeMultSymbolic_SeqAIJ_SeqAIJ, 31566fc122caSHong Zhang MatMatTransposeMultNumeric_SeqAIJ_SeqAIJ, 31572121bac1SHong Zhang 0, 31582121bac1SHong Zhang /* 99*/ 0, 3159609c6c4dSKris Buschelman 0, 3160609c6c4dSKris Buschelman 0, 316187d4246cSBarry Smith MatConjugate_SeqAIJ, 316287d4246cSBarry Smith 0, 3163d519adbfSMatthew Knepley /*104*/ MatSetValuesRow_SeqAIJ, 316499cafbc1SBarry Smith MatRealPart_SeqAIJ, 3165f5edf698SHong Zhang MatImaginaryPart_SeqAIJ, 3166f5edf698SHong Zhang 0, 31672bebee5dSHong Zhang 0, 3168cbd44569SHong Zhang /*109*/ MatMatSolve_SeqAIJ, 3169985db425SBarry Smith 0, 31702af78befSBarry Smith MatGetRowMin_SeqAIJ, 31712af78befSBarry Smith 0, 3172599ef60dSHong Zhang MatMissingDiagonal_SeqAIJ, 3173d519adbfSMatthew Knepley /*114*/ 0, 3174599ef60dSHong Zhang 0, 31753c2a7987SHong Zhang 0, 3176fe97e370SBarry Smith 0, 3177fbdbba38SShri Abhyankar 0, 3178fbdbba38SShri Abhyankar /*119*/ 0, 3179fbdbba38SShri Abhyankar 0, 3180fbdbba38SShri Abhyankar 0, 318182d44351SHong Zhang 0, 3182b3a44c85SBarry Smith MatGetMultiProcBlock_SeqAIJ, 31830716a85fSBarry Smith /*124*/ MatFindNonzeroRows_SeqAIJ, 3184bbead8a2SBarry Smith MatGetColumnNorms_SeqAIJ, 318537868618SMatthew G Knepley MatInvertBlockDiagonal_SeqAIJ, 318637868618SMatthew G Knepley 0, 318737868618SMatthew G Knepley 0, 31885df89d91SHong Zhang /*129*/ 0, 318975648e8dSHong Zhang MatTransposeMatMult_SeqAIJ_SeqAIJ, 319075648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqAIJ_SeqAIJ, 319175648e8dSHong Zhang MatTransposeMatMultNumeric_SeqAIJ_SeqAIJ, 3192b9af6bddSHong Zhang MatTransposeColoringCreate_SeqAIJ, 3193b9af6bddSHong Zhang /*134*/ MatTransColoringApplySpToDen_SeqAIJ, 31942b8ad9a3SHong Zhang MatTransColoringApplyDenToSp_SeqAIJ, 31952b8ad9a3SHong Zhang MatRARt_SeqAIJ_SeqAIJ, 31962b8ad9a3SHong Zhang MatRARtSymbolic_SeqAIJ_SeqAIJ, 31973964eb88SJed Brown MatRARtNumeric_SeqAIJ_SeqAIJ, 31983964eb88SJed Brown /*139*/0, 3199f9426fe0SMark Adams 0, 32001919a2e2SJed Brown 0, 32013a062f41SBarry Smith MatFDColoringSetUp_SeqXAIJ, 32029c8f2541SHong Zhang MatFindOffBlockDiagonalEntries_SeqAIJ, 32039c8f2541SHong Zhang /*144*/MatCreateMPIMatConcatenateSeqMat_SeqAIJ 32049e29f15eSvictorle }; 320517ab2063SBarry Smith 32067087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices_SeqAIJ(Mat mat,PetscInt *indices) 3207bef8e0ddSBarry Smith { 3208bef8e0ddSBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 320997f1f81fSBarry Smith PetscInt i,nz,n; 3210bef8e0ddSBarry Smith 3211bef8e0ddSBarry Smith PetscFunctionBegin; 3212bef8e0ddSBarry Smith nz = aij->maxnz; 3213d0f46423SBarry Smith n = mat->rmap->n; 3214bef8e0ddSBarry Smith for (i=0; i<nz; i++) { 3215bef8e0ddSBarry Smith aij->j[i] = indices[i]; 3216bef8e0ddSBarry Smith } 3217bef8e0ddSBarry Smith aij->nz = nz; 3218bef8e0ddSBarry Smith for (i=0; i<n; i++) { 3219bef8e0ddSBarry Smith aij->ilen[i] = aij->imax[i]; 3220bef8e0ddSBarry Smith } 3221bef8e0ddSBarry Smith PetscFunctionReturn(0); 3222bef8e0ddSBarry Smith } 3223bef8e0ddSBarry Smith 3224bef8e0ddSBarry Smith /*@ 3225bef8e0ddSBarry Smith MatSeqAIJSetColumnIndices - Set the column indices for all the rows 3226bef8e0ddSBarry Smith in the matrix. 3227bef8e0ddSBarry Smith 3228bef8e0ddSBarry Smith Input Parameters: 3229bef8e0ddSBarry Smith + mat - the SeqAIJ matrix 3230bef8e0ddSBarry Smith - indices - the column indices 3231bef8e0ddSBarry Smith 323215091d37SBarry Smith Level: advanced 323315091d37SBarry Smith 3234bef8e0ddSBarry Smith Notes: 3235bef8e0ddSBarry Smith This can be called if you have precomputed the nonzero structure of the 3236bef8e0ddSBarry Smith matrix and want to provide it to the matrix object to improve the performance 3237bef8e0ddSBarry Smith of the MatSetValues() operation. 3238bef8e0ddSBarry Smith 3239bef8e0ddSBarry Smith You MUST have set the correct numbers of nonzeros per row in the call to 3240d1be2dadSMatthew Knepley MatCreateSeqAIJ(), and the columns indices MUST be sorted. 3241bef8e0ddSBarry Smith 3242bef8e0ddSBarry Smith MUST be called before any calls to MatSetValues(); 3243bef8e0ddSBarry Smith 3244b9617806SBarry Smith The indices should start with zero, not one. 3245b9617806SBarry Smith 3246bef8e0ddSBarry Smith @*/ 32477087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetColumnIndices(Mat mat,PetscInt *indices) 3248bef8e0ddSBarry Smith { 32494ac538c5SBarry Smith PetscErrorCode ierr; 3250bef8e0ddSBarry Smith 3251bef8e0ddSBarry Smith PetscFunctionBegin; 32520700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 32534482741eSBarry Smith PetscValidPointer(indices,2); 32544ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatSeqAIJSetColumnIndices_C",(Mat,PetscInt*),(mat,indices));CHKERRQ(ierr); 3255bef8e0ddSBarry Smith PetscFunctionReturn(0); 3256bef8e0ddSBarry Smith } 3257bef8e0ddSBarry Smith 3258be6bf707SBarry Smith /* ----------------------------------------------------------------------------------------*/ 3259be6bf707SBarry Smith 32607087cfbeSBarry Smith PetscErrorCode MatStoreValues_SeqAIJ(Mat mat) 3261be6bf707SBarry Smith { 3262be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 32636849ba73SBarry Smith PetscErrorCode ierr; 3264d0f46423SBarry Smith size_t nz = aij->i[mat->rmap->n]; 3265be6bf707SBarry Smith 3266be6bf707SBarry Smith PetscFunctionBegin; 3267169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3268be6bf707SBarry Smith 3269be6bf707SBarry Smith /* allocate space for values if not already there */ 3270be6bf707SBarry Smith if (!aij->saved_values) { 3271854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&aij->saved_values);CHKERRQ(ierr); 32723bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)mat,(nz+1)*sizeof(PetscScalar));CHKERRQ(ierr); 3273be6bf707SBarry Smith } 3274be6bf707SBarry Smith 3275be6bf707SBarry Smith /* copy values over */ 327687828ca2SBarry Smith ierr = PetscMemcpy(aij->saved_values,aij->a,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3277be6bf707SBarry Smith PetscFunctionReturn(0); 3278be6bf707SBarry Smith } 3279be6bf707SBarry Smith 3280be6bf707SBarry Smith /*@ 3281be6bf707SBarry Smith MatStoreValues - Stashes a copy of the matrix values; this allows, for 3282be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3283be6bf707SBarry Smith nonlinear portion. 3284be6bf707SBarry Smith 3285be6bf707SBarry Smith Collect on Mat 3286be6bf707SBarry Smith 3287be6bf707SBarry Smith Input Parameters: 32880e609b76SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3289be6bf707SBarry Smith 329015091d37SBarry Smith Level: advanced 329115091d37SBarry Smith 3292be6bf707SBarry Smith Common Usage, with SNESSolve(): 3293be6bf707SBarry Smith $ Create Jacobian matrix 3294be6bf707SBarry Smith $ Set linear terms into matrix 3295be6bf707SBarry Smith $ Apply boundary conditions to matrix, at this time matrix must have 3296be6bf707SBarry Smith $ final nonzero structure (i.e. setting the nonlinear terms and applying 3297be6bf707SBarry Smith $ boundary conditions again will not change the nonzero structure 3298512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3299be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3300be6bf707SBarry Smith $ Call SNESSetJacobian() with matrix 3301be6bf707SBarry Smith $ In your Jacobian routine 3302be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3303be6bf707SBarry Smith $ Set nonlinear terms in matrix 3304be6bf707SBarry Smith 3305be6bf707SBarry Smith Common Usage without SNESSolve(), i.e. when you handle nonlinear solve yourself: 3306be6bf707SBarry Smith $ // build linear portion of Jacobian 3307512a5fc5SBarry Smith $ ierr = MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); 3308be6bf707SBarry Smith $ ierr = MatStoreValues(mat); 3309be6bf707SBarry Smith $ loop over nonlinear iterations 3310be6bf707SBarry Smith $ ierr = MatRetrieveValues(mat); 3311be6bf707SBarry Smith $ // call MatSetValues(mat,...) to set nonliner portion of Jacobian 3312be6bf707SBarry Smith $ // call MatAssemblyBegin/End() on matrix 3313be6bf707SBarry Smith $ Solve linear system with Jacobian 3314be6bf707SBarry Smith $ endloop 3315be6bf707SBarry Smith 3316be6bf707SBarry Smith Notes: 3317be6bf707SBarry Smith Matrix must already be assemblied before calling this routine 3318512a5fc5SBarry Smith Must set the matrix option MatSetOption(mat,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE); before 3319be6bf707SBarry Smith calling this routine. 3320be6bf707SBarry Smith 33210c468ba9SBarry Smith When this is called multiple times it overwrites the previous set of stored values 33220c468ba9SBarry Smith and does not allocated additional space. 33230c468ba9SBarry Smith 3324be6bf707SBarry Smith .seealso: MatRetrieveValues() 3325be6bf707SBarry Smith 3326be6bf707SBarry Smith @*/ 33277087cfbeSBarry Smith PetscErrorCode MatStoreValues(Mat mat) 3328be6bf707SBarry Smith { 33294ac538c5SBarry Smith PetscErrorCode ierr; 3330be6bf707SBarry Smith 3331be6bf707SBarry Smith PetscFunctionBegin; 33320700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3333e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3334e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33354ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatStoreValues_C",(Mat),(mat));CHKERRQ(ierr); 3336be6bf707SBarry Smith PetscFunctionReturn(0); 3337be6bf707SBarry Smith } 3338be6bf707SBarry Smith 33397087cfbeSBarry Smith PetscErrorCode MatRetrieveValues_SeqAIJ(Mat mat) 3340be6bf707SBarry Smith { 3341be6bf707SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)mat->data; 33426849ba73SBarry Smith PetscErrorCode ierr; 3343d0f46423SBarry Smith PetscInt nz = aij->i[mat->rmap->n]; 3344be6bf707SBarry Smith 3345be6bf707SBarry Smith PetscFunctionBegin; 3346169f6850SBarry Smith if (!aij->nonew) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatSetOption(A,MAT_NEW_NONZERO_LOCATIONS,PETSC_FALSE);first"); 3347f23aa3ddSBarry Smith if (!aij->saved_values) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call MatStoreValues(A);first"); 3348be6bf707SBarry Smith /* copy values over */ 334987828ca2SBarry Smith ierr = PetscMemcpy(aij->a,aij->saved_values,nz*sizeof(PetscScalar));CHKERRQ(ierr); 3350be6bf707SBarry Smith PetscFunctionReturn(0); 3351be6bf707SBarry Smith } 3352be6bf707SBarry Smith 3353be6bf707SBarry Smith /*@ 3354be6bf707SBarry Smith MatRetrieveValues - Retrieves the copy of the matrix values; this allows, for 3355be6bf707SBarry Smith example, reuse of the linear part of a Jacobian, while recomputing the 3356be6bf707SBarry Smith nonlinear portion. 3357be6bf707SBarry Smith 3358be6bf707SBarry Smith Collect on Mat 3359be6bf707SBarry Smith 3360be6bf707SBarry Smith Input Parameters: 3361386f7cf9SBarry Smith . mat - the matrix (currently only AIJ matrices support this option) 3362be6bf707SBarry Smith 336315091d37SBarry Smith Level: advanced 336415091d37SBarry Smith 3365be6bf707SBarry Smith .seealso: MatStoreValues() 3366be6bf707SBarry Smith 3367be6bf707SBarry Smith @*/ 33687087cfbeSBarry Smith PetscErrorCode MatRetrieveValues(Mat mat) 3369be6bf707SBarry Smith { 33704ac538c5SBarry Smith PetscErrorCode ierr; 3371be6bf707SBarry Smith 3372be6bf707SBarry Smith PetscFunctionBegin; 33730700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3374e32f2f54SBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix"); 3375e32f2f54SBarry Smith if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 33764ac538c5SBarry Smith ierr = PetscUseMethod(mat,"MatRetrieveValues_C",(Mat),(mat));CHKERRQ(ierr); 3377be6bf707SBarry Smith PetscFunctionReturn(0); 3378be6bf707SBarry Smith } 3379be6bf707SBarry Smith 3380f83d6046SBarry Smith 3381be6bf707SBarry Smith /* --------------------------------------------------------------------------------*/ 338217ab2063SBarry Smith /*@C 3383682d7d0cSBarry Smith MatCreateSeqAIJ - Creates a sparse matrix in AIJ (compressed row) format 33840d15e28bSLois Curfman McInnes (the default parallel PETSc format). For good matrix assembly performance 33856e62573dSLois Curfman McInnes the user should preallocate the matrix storage by setting the parameter nz 338651c19458SBarry Smith (or the array nnz). By setting these parameters accurately, performance 33872bd5e0b2SLois Curfman McInnes during matrix assembly can be increased by more than a factor of 50. 338817ab2063SBarry Smith 3389db81eaa0SLois Curfman McInnes Collective on MPI_Comm 3390db81eaa0SLois Curfman McInnes 339117ab2063SBarry Smith Input Parameters: 3392db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 339317ab2063SBarry Smith . m - number of rows 339417ab2063SBarry Smith . n - number of columns 339517ab2063SBarry Smith . nz - number of nonzeros per row (same for all rows) 339651c19458SBarry Smith - nnz - array containing the number of nonzeros in the various rows 33970298fd71SBarry Smith (possibly different for each row) or NULL 339817ab2063SBarry Smith 339917ab2063SBarry Smith Output Parameter: 3400416022c9SBarry Smith . A - the matrix 340117ab2063SBarry Smith 3402175b88e8SBarry Smith It is recommended that one use the MatCreate(), MatSetType() and/or MatSetFromOptions(), 3403ae1d86c5SBarry Smith MatXXXXSetPreallocation() paradgm instead of this routine directly. 3404175b88e8SBarry Smith [MatXXXXSetPreallocation() is, for example, MatSeqAIJSetPreallocation] 3405175b88e8SBarry Smith 3406b259b22eSLois Curfman McInnes Notes: 340749a6f317SBarry Smith If nnz is given then nz is ignored 340849a6f317SBarry Smith 340917ab2063SBarry Smith The AIJ format (also called the Yale sparse matrix format or 341017ab2063SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 34110002213bSLois Curfman McInnes storage. That is, the stored row and column indices can begin at 341244cd7ae7SLois Curfman McInnes either one (as in Fortran) or zero. See the users' manual for details. 341317ab2063SBarry Smith 341417ab2063SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34150298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 34163d323bbdSBarry Smith allocation. For large problems you MUST preallocate memory or you 34176da5968aSLois Curfman McInnes will get TERRIBLE performance, see the users' manual chapter on matrices. 341817ab2063SBarry Smith 3419682d7d0cSBarry Smith By default, this format uses inodes (identical nodes) when possible, to 34204fca80b9SLois Curfman McInnes improve numerical efficiency of matrix-vector products and solves. We 3421682d7d0cSBarry Smith search for consecutive rows with the same nonzero structure, thereby 34226c7ebb05SLois Curfman McInnes reusing matrix information to achieve increased efficiency. 34236c7ebb05SLois Curfman McInnes 34246c7ebb05SLois Curfman McInnes Options Database Keys: 3425698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 34269db58ca8SBarry Smith - -mat_inode_limit <limit> - Sets inode limit (max limit=5) 342717ab2063SBarry Smith 3428027ccd11SLois Curfman McInnes Level: intermediate 3429027ccd11SLois Curfman McInnes 343069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays() 343136db0b34SBarry Smith 343217ab2063SBarry Smith @*/ 34337087cfbeSBarry Smith PetscErrorCode MatCreateSeqAIJ(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt nz,const PetscInt nnz[],Mat *A) 343417ab2063SBarry Smith { 3435dfbe8321SBarry Smith PetscErrorCode ierr; 34366945ee14SBarry Smith 34373a40ed3dSBarry Smith PetscFunctionBegin; 3438f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 3439117016b1SBarry Smith ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 3440c4752a88SBarry Smith ierr = MatSetType(*A,MATSEQAIJ);CHKERRQ(ierr); 3441d28bb7d2SJed Brown ierr = MatSeqAIJSetPreallocation_SeqAIJ(*A,nz,nnz);CHKERRQ(ierr); 3442273d9f13SBarry Smith PetscFunctionReturn(0); 3443273d9f13SBarry Smith } 3444273d9f13SBarry Smith 3445273d9f13SBarry Smith /*@C 3446273d9f13SBarry Smith MatSeqAIJSetPreallocation - For good matrix assembly performance 3447273d9f13SBarry Smith the user should preallocate the matrix storage by setting the parameter nz 3448273d9f13SBarry Smith (or the array nnz). By setting these parameters accurately, performance 3449273d9f13SBarry Smith during matrix assembly can be increased by more than a factor of 50. 3450273d9f13SBarry Smith 3451273d9f13SBarry Smith Collective on MPI_Comm 3452273d9f13SBarry Smith 3453273d9f13SBarry Smith Input Parameters: 34541c4f3114SJed Brown + B - The matrix 3455273d9f13SBarry Smith . nz - number of nonzeros per row (same for all rows) 3456273d9f13SBarry Smith - nnz - array containing the number of nonzeros in the various rows 34570298fd71SBarry Smith (possibly different for each row) or NULL 3458273d9f13SBarry Smith 3459273d9f13SBarry Smith Notes: 346049a6f317SBarry Smith If nnz is given then nz is ignored 346149a6f317SBarry Smith 3462273d9f13SBarry Smith The AIJ format (also called the Yale sparse matrix format or 3463273d9f13SBarry Smith compressed row storage), is fully compatible with standard Fortran 77 3464273d9f13SBarry Smith storage. That is, the stored row and column indices can begin at 3465273d9f13SBarry Smith either one (as in Fortran) or zero. See the users' manual for details. 3466273d9f13SBarry Smith 3467273d9f13SBarry Smith Specify the preallocated storage with either nz or nnz (not both). 34680298fd71SBarry Smith Set nz=PETSC_DEFAULT and nnz=NULL for PETSc to control dynamic memory 3469273d9f13SBarry Smith allocation. For large problems you MUST preallocate memory or you 3470273d9f13SBarry Smith will get TERRIBLE performance, see the users' manual chapter on matrices. 3471273d9f13SBarry Smith 3472aa95bbe8SBarry Smith You can call MatGetInfo() to get information on how effective the preallocation was; 3473aa95bbe8SBarry Smith for example the fields mallocs,nz_allocated,nz_used,nz_unneeded; 3474aa95bbe8SBarry Smith You can also run with the option -info and look for messages with the string 3475aa95bbe8SBarry Smith malloc in them to see if additional memory allocation was needed. 3476aa95bbe8SBarry Smith 3477a96a251dSBarry Smith Developers: Use nz of MAT_SKIP_ALLOCATION to not allocate any space for the matrix 3478a96a251dSBarry Smith entries or columns indices 3479a96a251dSBarry Smith 3480273d9f13SBarry Smith By default, this format uses inodes (identical nodes) when possible, to 3481273d9f13SBarry Smith improve numerical efficiency of matrix-vector products and solves. We 3482273d9f13SBarry Smith search for consecutive rows with the same nonzero structure, thereby 3483273d9f13SBarry Smith reusing matrix information to achieve increased efficiency. 3484273d9f13SBarry Smith 3485273d9f13SBarry Smith Options Database Keys: 3486698d4c6aSKris Buschelman + -mat_no_inode - Do not use inodes 3487698d4c6aSKris Buschelman . -mat_inode_limit <limit> - Sets inode limit (max limit=5) 3488273d9f13SBarry Smith - -mat_aij_oneindex - Internally use indexing starting at 1 3489273d9f13SBarry Smith rather than 0. Note that when calling MatSetValues(), 3490273d9f13SBarry Smith the user still MUST index entries starting at 0! 3491273d9f13SBarry Smith 3492273d9f13SBarry Smith Level: intermediate 3493273d9f13SBarry Smith 349469b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatSetValues(), MatSeqAIJSetColumnIndices(), MatCreateSeqAIJWithArrays(), MatGetInfo() 3495273d9f13SBarry Smith 3496273d9f13SBarry Smith @*/ 34977087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation(Mat B,PetscInt nz,const PetscInt nnz[]) 3498273d9f13SBarry Smith { 34994ac538c5SBarry Smith PetscErrorCode ierr; 3500a23d5eceSKris Buschelman 3501a23d5eceSKris Buschelman PetscFunctionBegin; 35026ba663aaSJed Brown PetscValidHeaderSpecific(B,MAT_CLASSID,1); 35036ba663aaSJed Brown PetscValidType(B,1); 35044ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocation_C",(Mat,PetscInt,const PetscInt[]),(B,nz,nnz));CHKERRQ(ierr); 3505a23d5eceSKris Buschelman PetscFunctionReturn(0); 3506a23d5eceSKris Buschelman } 3507a23d5eceSKris Buschelman 35087087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocation_SeqAIJ(Mat B,PetscInt nz,const PetscInt *nnz) 3509a23d5eceSKris Buschelman { 3510273d9f13SBarry Smith Mat_SeqAIJ *b; 35112576faa2SJed Brown PetscBool skipallocation = PETSC_FALSE,realalloc = PETSC_FALSE; 35126849ba73SBarry Smith PetscErrorCode ierr; 351397f1f81fSBarry Smith PetscInt i; 3514273d9f13SBarry Smith 3515273d9f13SBarry Smith PetscFunctionBegin; 35162576faa2SJed Brown if (nz >= 0 || nnz) realalloc = PETSC_TRUE; 3517a96a251dSBarry Smith if (nz == MAT_SKIP_ALLOCATION) { 3518c461c341SBarry Smith skipallocation = PETSC_TRUE; 3519c461c341SBarry Smith nz = 0; 3520c461c341SBarry Smith } 3521c461c341SBarry Smith 352226283091SBarry Smith ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 352326283091SBarry Smith ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3524899cda47SBarry Smith 3525435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 5; 352660e0710aSBarry Smith if (nz < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"nz cannot be less than 0: value %D",nz); 3527b73539f3SBarry Smith if (nnz) { 3528d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) { 352960e0710aSBarry 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]); 353060e0710aSBarry 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); 3531b73539f3SBarry Smith } 3532b73539f3SBarry Smith } 3533b73539f3SBarry Smith 3534273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 35352205254eSKarl Rupp 3536273d9f13SBarry Smith b = (Mat_SeqAIJ*)B->data; 3537273d9f13SBarry Smith 3538ab93d7beSBarry Smith if (!skipallocation) { 35392ee49352SLisandro Dalcin if (!b->imax) { 3540dcca6d9dSJed Brown ierr = PetscMalloc2(B->rmap->n,&b->imax,B->rmap->n,&b->ilen);CHKERRQ(ierr); 35413bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,2*B->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 35422ee49352SLisandro Dalcin } 3543273d9f13SBarry Smith if (!nnz) { 3544435da068SBarry Smith if (nz == PETSC_DEFAULT || nz == PETSC_DECIDE) nz = 10; 3545c62bd62aSJed Brown else if (nz < 0) nz = 1; 3546d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) b->imax[i] = nz; 3547d0f46423SBarry Smith nz = nz*B->rmap->n; 3548273d9f13SBarry Smith } else { 3549273d9f13SBarry Smith nz = 0; 3550d0f46423SBarry Smith for (i=0; i<B->rmap->n; i++) {b->imax[i] = nnz[i]; nz += nnz[i];} 3551273d9f13SBarry Smith } 3552ab93d7beSBarry Smith /* b->ilen will count nonzeros in each row so far. */ 35532205254eSKarl Rupp for (i=0; i<B->rmap->n; i++) b->ilen[i] = 0; 3554ab93d7beSBarry Smith 3555273d9f13SBarry Smith /* allocate the matrix space */ 355653dd7562SDmitry Karpeev /* FIXME: should B's old memory be unlogged? */ 35572ee49352SLisandro Dalcin ierr = MatSeqXAIJFreeAIJ(B,&b->a,&b->j,&b->i);CHKERRQ(ierr); 3558dcca6d9dSJed Brown ierr = PetscMalloc3(nz,&b->a,nz,&b->j,B->rmap->n+1,&b->i);CHKERRQ(ierr); 35593bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,(B->rmap->n+1)*sizeof(PetscInt)+nz*(sizeof(PetscScalar)+sizeof(PetscInt)));CHKERRQ(ierr); 3560bfeeae90SHong Zhang b->i[0] = 0; 3561d0f46423SBarry Smith for (i=1; i<B->rmap->n+1; i++) { 35625da197adSKris Buschelman b->i[i] = b->i[i-1] + b->imax[i-1]; 35635da197adSKris Buschelman } 3564273d9f13SBarry Smith b->singlemalloc = PETSC_TRUE; 3565e6b907acSBarry Smith b->free_a = PETSC_TRUE; 3566e6b907acSBarry Smith b->free_ij = PETSC_TRUE; 3567c461c341SBarry Smith } else { 3568e6b907acSBarry Smith b->free_a = PETSC_FALSE; 3569e6b907acSBarry Smith b->free_ij = PETSC_FALSE; 3570c461c341SBarry Smith } 3571273d9f13SBarry Smith 3572273d9f13SBarry Smith b->nz = 0; 3573273d9f13SBarry Smith b->maxnz = nz; 3574273d9f13SBarry Smith B->info.nz_unneeded = (double)b->maxnz; 35752205254eSKarl Rupp if (realalloc) { 35762205254eSKarl Rupp ierr = MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 35772205254eSKarl Rupp } 3578cb7b82ddSBarry Smith B->was_assembled = PETSC_FALSE; 3579cb7b82ddSBarry Smith B->assembled = PETSC_FALSE; 3580273d9f13SBarry Smith PetscFunctionReturn(0); 3581273d9f13SBarry Smith } 3582273d9f13SBarry Smith 358358d36128SBarry Smith /*@ 3584a1661176SMatthew Knepley MatSeqAIJSetPreallocationCSR - Allocates memory for a sparse sequential matrix in AIJ format. 3585a1661176SMatthew Knepley 3586a1661176SMatthew Knepley Input Parameters: 3587a1661176SMatthew Knepley + B - the matrix 3588a1661176SMatthew Knepley . i - the indices into j for the start of each row (starts with zero) 3589a1661176SMatthew Knepley . j - the column indices for each row (starts with zero) these must be sorted for each row 3590a1661176SMatthew Knepley - v - optional values in the matrix 3591a1661176SMatthew Knepley 3592a1661176SMatthew Knepley Level: developer 3593a1661176SMatthew Knepley 359458d36128SBarry Smith The i,j,v values are COPIED with this routine; to avoid the copy use MatCreateSeqAIJWithArrays() 359558d36128SBarry Smith 3596a1661176SMatthew Knepley .keywords: matrix, aij, compressed row, sparse, sequential 3597a1661176SMatthew Knepley 3598a1661176SMatthew Knepley .seealso: MatCreate(), MatCreateSeqAIJ(), MatSetValues(), MatSeqAIJSetPreallocation(), MatCreateSeqAIJ(), SeqAIJ 3599a1661176SMatthew Knepley @*/ 3600a1661176SMatthew Knepley PetscErrorCode MatSeqAIJSetPreallocationCSR(Mat B,const PetscInt i[],const PetscInt j[],const PetscScalar v[]) 3601a1661176SMatthew Knepley { 3602a1661176SMatthew Knepley PetscErrorCode ierr; 3603a1661176SMatthew Knepley 3604a1661176SMatthew Knepley PetscFunctionBegin; 36050700a824SBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,1); 36066ba663aaSJed Brown PetscValidType(B,1); 36074ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqAIJSetPreallocationCSR_C",(Mat,const PetscInt[],const PetscInt[],const PetscScalar[]),(B,i,j,v));CHKERRQ(ierr); 3608a1661176SMatthew Knepley PetscFunctionReturn(0); 3609a1661176SMatthew Knepley } 3610a1661176SMatthew Knepley 36117087cfbeSBarry Smith PetscErrorCode MatSeqAIJSetPreallocationCSR_SeqAIJ(Mat B,const PetscInt Ii[],const PetscInt J[],const PetscScalar v[]) 3612a1661176SMatthew Knepley { 3613a1661176SMatthew Knepley PetscInt i; 3614a1661176SMatthew Knepley PetscInt m,n; 3615a1661176SMatthew Knepley PetscInt nz; 3616a1661176SMatthew Knepley PetscInt *nnz, nz_max = 0; 3617a1661176SMatthew Knepley PetscScalar *values; 3618a1661176SMatthew Knepley PetscErrorCode ierr; 3619a1661176SMatthew Knepley 3620a1661176SMatthew Knepley PetscFunctionBegin; 362165e19b50SBarry Smith if (Ii[0]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Ii[0] must be 0 it is %D", Ii[0]); 3622779a8d59SSatish Balay 3623779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 3624779a8d59SSatish Balay ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 3625779a8d59SSatish Balay 3626779a8d59SSatish Balay ierr = MatGetSize(B, &m, &n);CHKERRQ(ierr); 3627854ce69bSBarry Smith ierr = PetscMalloc1(m+1, &nnz);CHKERRQ(ierr); 3628a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3629b7940d39SSatish Balay nz = Ii[i+1]- Ii[i]; 3630a1661176SMatthew Knepley nz_max = PetscMax(nz_max, nz); 363165e19b50SBarry Smith if (nz < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Local row %D has a negative number of columns %D", i, nnz); 3632a1661176SMatthew Knepley nnz[i] = nz; 3633a1661176SMatthew Knepley } 3634a1661176SMatthew Knepley ierr = MatSeqAIJSetPreallocation(B, 0, nnz);CHKERRQ(ierr); 3635a1661176SMatthew Knepley ierr = PetscFree(nnz);CHKERRQ(ierr); 3636a1661176SMatthew Knepley 3637a1661176SMatthew Knepley if (v) { 3638a1661176SMatthew Knepley values = (PetscScalar*) v; 3639a1661176SMatthew Knepley } else { 36401795a4d1SJed Brown ierr = PetscCalloc1(nz_max, &values);CHKERRQ(ierr); 3641a1661176SMatthew Knepley } 3642a1661176SMatthew Knepley 3643a1661176SMatthew Knepley for (i = 0; i < m; i++) { 3644b7940d39SSatish Balay nz = Ii[i+1] - Ii[i]; 3645b7940d39SSatish Balay ierr = MatSetValues_SeqAIJ(B, 1, &i, nz, J+Ii[i], values + (v ? Ii[i] : 0), INSERT_VALUES);CHKERRQ(ierr); 3646a1661176SMatthew Knepley } 3647a1661176SMatthew Knepley 3648a1661176SMatthew Knepley ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3649a1661176SMatthew Knepley ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3650a1661176SMatthew Knepley 3651a1661176SMatthew Knepley if (!v) { 3652a1661176SMatthew Knepley ierr = PetscFree(values);CHKERRQ(ierr); 3653a1661176SMatthew Knepley } 36547827cd58SJed Brown ierr = MatSetOption(B,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 3655a1661176SMatthew Knepley PetscFunctionReturn(0); 3656a1661176SMatthew Knepley } 3657a1661176SMatthew Knepley 3658c6db04a5SJed Brown #include <../src/mat/impls/dense/seq/dense.h> 3659af0996ceSBarry Smith #include <petsc/private/kernels/petscaxpy.h> 3660170fe5c8SBarry Smith 3661170fe5c8SBarry Smith /* 3662170fe5c8SBarry Smith Computes (B'*A')' since computing B*A directly is untenable 3663170fe5c8SBarry Smith 3664170fe5c8SBarry Smith n p p 3665170fe5c8SBarry Smith ( ) ( ) ( ) 3666170fe5c8SBarry Smith m ( A ) * n ( B ) = m ( C ) 3667170fe5c8SBarry Smith ( ) ( ) ( ) 3668170fe5c8SBarry Smith 3669170fe5c8SBarry Smith */ 3670170fe5c8SBarry Smith PetscErrorCode MatMatMultNumeric_SeqDense_SeqAIJ(Mat A,Mat B,Mat C) 3671170fe5c8SBarry Smith { 3672170fe5c8SBarry Smith PetscErrorCode ierr; 3673170fe5c8SBarry Smith Mat_SeqDense *sub_a = (Mat_SeqDense*)A->data; 3674170fe5c8SBarry Smith Mat_SeqAIJ *sub_b = (Mat_SeqAIJ*)B->data; 3675170fe5c8SBarry Smith Mat_SeqDense *sub_c = (Mat_SeqDense*)C->data; 36761de00fd4SBarry Smith PetscInt i,n,m,q,p; 3677170fe5c8SBarry Smith const PetscInt *ii,*idx; 3678170fe5c8SBarry Smith const PetscScalar *b,*a,*a_q; 3679170fe5c8SBarry Smith PetscScalar *c,*c_q; 3680170fe5c8SBarry Smith 3681170fe5c8SBarry Smith PetscFunctionBegin; 3682d0f46423SBarry Smith m = A->rmap->n; 3683d0f46423SBarry Smith n = A->cmap->n; 3684d0f46423SBarry Smith p = B->cmap->n; 3685170fe5c8SBarry Smith a = sub_a->v; 3686170fe5c8SBarry Smith b = sub_b->a; 3687170fe5c8SBarry Smith c = sub_c->v; 3688170fe5c8SBarry Smith ierr = PetscMemzero(c,m*p*sizeof(PetscScalar));CHKERRQ(ierr); 3689170fe5c8SBarry Smith 3690170fe5c8SBarry Smith ii = sub_b->i; 3691170fe5c8SBarry Smith idx = sub_b->j; 3692170fe5c8SBarry Smith for (i=0; i<n; i++) { 3693170fe5c8SBarry Smith q = ii[i+1] - ii[i]; 3694170fe5c8SBarry Smith while (q-->0) { 3695170fe5c8SBarry Smith c_q = c + m*(*idx); 3696170fe5c8SBarry Smith a_q = a + m*i; 3697854c7f52SBarry Smith PetscKernelAXPY(c_q,*b,a_q,m); 3698170fe5c8SBarry Smith idx++; 3699170fe5c8SBarry Smith b++; 3700170fe5c8SBarry Smith } 3701170fe5c8SBarry Smith } 3702170fe5c8SBarry Smith PetscFunctionReturn(0); 3703170fe5c8SBarry Smith } 3704170fe5c8SBarry Smith 3705170fe5c8SBarry Smith PetscErrorCode MatMatMultSymbolic_SeqDense_SeqAIJ(Mat A,Mat B,PetscReal fill,Mat *C) 3706170fe5c8SBarry Smith { 3707170fe5c8SBarry Smith PetscErrorCode ierr; 3708d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 3709170fe5c8SBarry Smith Mat Cmat; 3710170fe5c8SBarry Smith 3711170fe5c8SBarry Smith PetscFunctionBegin; 371260e0710aSBarry 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); 3713ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&Cmat);CHKERRQ(ierr); 3714170fe5c8SBarry Smith ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 371533d57670SJed Brown ierr = MatSetBlockSizesFromMats(Cmat,A,B);CHKERRQ(ierr); 3716170fe5c8SBarry Smith ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 37170298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 3718d73949e8SHong Zhang 3719d73949e8SHong Zhang Cmat->ops->matmultnumeric = MatMatMultNumeric_SeqDense_SeqAIJ; 37202205254eSKarl Rupp 3721170fe5c8SBarry Smith *C = Cmat; 3722170fe5c8SBarry Smith PetscFunctionReturn(0); 3723170fe5c8SBarry Smith } 3724170fe5c8SBarry Smith 3725170fe5c8SBarry Smith /* ----------------------------------------------------------------*/ 3726150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqAIJ(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 3727170fe5c8SBarry Smith { 3728170fe5c8SBarry Smith PetscErrorCode ierr; 3729170fe5c8SBarry Smith 3730170fe5c8SBarry Smith PetscFunctionBegin; 3731170fe5c8SBarry Smith if (scall == MAT_INITIAL_MATRIX) { 37323ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3733170fe5c8SBarry Smith ierr = MatMatMultSymbolic_SeqDense_SeqAIJ(A,B,fill,C);CHKERRQ(ierr); 37343ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 3735170fe5c8SBarry Smith } 37363ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3737170fe5c8SBarry Smith ierr = MatMatMultNumeric_SeqDense_SeqAIJ(A,B,*C);CHKERRQ(ierr); 37383ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 3739170fe5c8SBarry Smith PetscFunctionReturn(0); 3740170fe5c8SBarry Smith } 3741170fe5c8SBarry Smith 3742170fe5c8SBarry Smith 37430bad9183SKris Buschelman /*MC 3744fafad747SKris Buschelman MATSEQAIJ - MATSEQAIJ = "seqaij" - A matrix type to be used for sequential sparse matrices, 37450bad9183SKris Buschelman based on compressed sparse row format. 37460bad9183SKris Buschelman 37470bad9183SKris Buschelman Options Database Keys: 37480bad9183SKris Buschelman . -mat_type seqaij - sets the matrix type to "seqaij" during a call to MatSetFromOptions() 37490bad9183SKris Buschelman 37500bad9183SKris Buschelman Level: beginner 37510bad9183SKris Buschelman 3752f587520bSBarry Smith .seealso: MatCreateSeqAIJ(), MatSetFromOptions(), MatSetType(), MatCreate(), MatType 37530bad9183SKris Buschelman M*/ 37540bad9183SKris Buschelman 3755ccd284c7SBarry Smith /*MC 3756ccd284c7SBarry Smith MATAIJ - MATAIJ = "aij" - A matrix type to be used for sparse matrices. 3757ccd284c7SBarry Smith 3758ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJ when constructed with a single process communicator, 3759ccd284c7SBarry Smith and MATMPIAIJ otherwise. As a result, for single process communicators, 3760ccd284c7SBarry Smith MatSeqAIJSetPreallocation is supported, and similarly MatMPIAIJSetPreallocation is supported 3761ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3762ccd284c7SBarry Smith the above preallocation routines for simplicity. 3763ccd284c7SBarry Smith 3764ccd284c7SBarry Smith Options Database Keys: 3765ccd284c7SBarry Smith . -mat_type aij - sets the matrix type to "aij" during a call to MatSetFromOptions() 3766ccd284c7SBarry Smith 3767ccd284c7SBarry Smith Developer Notes: Subclasses include MATAIJCUSP, MATAIJPERM, MATAIJCRL, and also automatically switches over to use inodes when 3768ccd284c7SBarry Smith enough exist. 3769ccd284c7SBarry Smith 3770ccd284c7SBarry Smith Level: beginner 3771ccd284c7SBarry Smith 3772ccd284c7SBarry Smith .seealso: MatCreateAIJ(), MatCreateSeqAIJ(), MATSEQAIJ,MATMPIAIJ 3773ccd284c7SBarry Smith M*/ 3774ccd284c7SBarry Smith 3775ccd284c7SBarry Smith /*MC 3776ccd284c7SBarry Smith MATAIJCRL - MATAIJCRL = "aijcrl" - A matrix type to be used for sparse matrices. 3777ccd284c7SBarry Smith 3778ccd284c7SBarry Smith This matrix type is identical to MATSEQAIJCRL when constructed with a single process communicator, 3779ccd284c7SBarry Smith and MATMPIAIJCRL otherwise. As a result, for single process communicators, 3780ccd284c7SBarry Smith MatSeqAIJSetPreallocation() is supported, and similarly MatMPIAIJSetPreallocation() is supported 3781ccd284c7SBarry Smith for communicators controlling multiple processes. It is recommended that you call both of 3782ccd284c7SBarry Smith the above preallocation routines for simplicity. 3783ccd284c7SBarry Smith 3784ccd284c7SBarry Smith Options Database Keys: 3785ccd284c7SBarry Smith . -mat_type aijcrl - sets the matrix type to "aijcrl" during a call to MatSetFromOptions() 3786ccd284c7SBarry Smith 3787ccd284c7SBarry Smith Level: beginner 3788ccd284c7SBarry Smith 3789ccd284c7SBarry Smith .seealso: MatCreateMPIAIJCRL,MATSEQAIJCRL,MATMPIAIJCRL, MATSEQAIJCRL, MATMPIAIJCRL 3790ccd284c7SBarry Smith M*/ 3791ccd284c7SBarry Smith 3792cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqAIJCRL(Mat,MatType,MatReuse,Mat*); 3793af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3794cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_Elemental(Mat,MatType,MatReuse,Mat*); 3795af8000cdSHong Zhang #endif 379663c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 379763c07aadSStefano Zampini PETSC_INTERN PetscErrorCode MatConvert_AIJ_HYPRE(Mat A,MatType,MatReuse,Mat*); 37983dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat,Mat,Mat,MatReuse,PetscReal,Mat*); 379963c07aadSStefano Zampini #endif 3800cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat,MatType,MatReuse,Mat*); 380142c9c57cSBarry Smith 3802b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 380329b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEnginePut_SeqAIJ(PetscObject,void*); 380429b38603SBarry Smith PETSC_EXTERN PetscErrorCode MatlabEngineGet_SeqAIJ(PetscObject,void*); 3805b3866ffcSBarry Smith #endif 380617667f90SBarry Smith 3807c0c8ee5eSDmitry Karpeev 38088c778c55SBarry Smith /*@C 38098397e458SBarry Smith MatSeqAIJGetArray - gives access to the array where the data for a MATSEQAIJ matrix is stored 38108c778c55SBarry Smith 38118c778c55SBarry Smith Not Collective 38128c778c55SBarry Smith 38138c778c55SBarry Smith Input Parameter: 3814579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38158c778c55SBarry Smith 38168c778c55SBarry Smith Output Parameter: 38178c778c55SBarry Smith . array - pointer to the data 38188c778c55SBarry Smith 38198c778c55SBarry Smith Level: intermediate 38208c778c55SBarry Smith 3821774cf152SJed Brown .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 38228c778c55SBarry Smith @*/ 38238c778c55SBarry Smith PetscErrorCode MatSeqAIJGetArray(Mat A,PetscScalar **array) 38248c778c55SBarry Smith { 38258c778c55SBarry Smith PetscErrorCode ierr; 38268c778c55SBarry Smith 38278c778c55SBarry Smith PetscFunctionBegin; 38288c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38298c778c55SBarry Smith PetscFunctionReturn(0); 38308c778c55SBarry Smith } 38318c778c55SBarry Smith 383221e72a00SBarry Smith /*@C 383321e72a00SBarry Smith MatSeqAIJGetMaxRowNonzeros - returns the maximum number of nonzeros in any row 383421e72a00SBarry Smith 383521e72a00SBarry Smith Not Collective 383621e72a00SBarry Smith 383721e72a00SBarry Smith Input Parameter: 3838579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 383921e72a00SBarry Smith 384021e72a00SBarry Smith Output Parameter: 384121e72a00SBarry Smith . nz - the maximum number of nonzeros in any row 384221e72a00SBarry Smith 384321e72a00SBarry Smith Level: intermediate 384421e72a00SBarry Smith 384521e72a00SBarry Smith .seealso: MatSeqAIJRestoreArray(), MatSeqAIJGetArrayF90() 384621e72a00SBarry Smith @*/ 384721e72a00SBarry Smith PetscErrorCode MatSeqAIJGetMaxRowNonzeros(Mat A,PetscInt *nz) 384821e72a00SBarry Smith { 384921e72a00SBarry Smith Mat_SeqAIJ *aij = (Mat_SeqAIJ*)A->data; 385021e72a00SBarry Smith 385121e72a00SBarry Smith PetscFunctionBegin; 385221e72a00SBarry Smith *nz = aij->rmax; 385321e72a00SBarry Smith PetscFunctionReturn(0); 385421e72a00SBarry Smith } 385521e72a00SBarry Smith 38568c778c55SBarry Smith /*@C 3857579dbff0SBarry Smith MatSeqAIJRestoreArray - returns access to the array where the data for a MATSEQAIJ matrix is stored obtained by MatSeqAIJGetArray() 38588c778c55SBarry Smith 38598c778c55SBarry Smith Not Collective 38608c778c55SBarry Smith 38618c778c55SBarry Smith Input Parameters: 3862579dbff0SBarry Smith . mat - a MATSEQAIJ matrix 38638c778c55SBarry Smith . array - pointer to the data 38648c778c55SBarry Smith 38658c778c55SBarry Smith Level: intermediate 38668c778c55SBarry Smith 3867774cf152SJed Brown .seealso: MatSeqAIJGetArray(), MatSeqAIJRestoreArrayF90() 38688c778c55SBarry Smith @*/ 38698c778c55SBarry Smith PetscErrorCode MatSeqAIJRestoreArray(Mat A,PetscScalar **array) 38708c778c55SBarry Smith { 38718c778c55SBarry Smith PetscErrorCode ierr; 38728c778c55SBarry Smith 38738c778c55SBarry Smith PetscFunctionBegin; 38748c778c55SBarry Smith ierr = PetscUseMethod(A,"MatSeqAIJRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 38758c778c55SBarry Smith PetscFunctionReturn(0); 38768c778c55SBarry Smith } 38778c778c55SBarry Smith 38788cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqAIJ(Mat B) 3879273d9f13SBarry Smith { 3880273d9f13SBarry Smith Mat_SeqAIJ *b; 3881dfbe8321SBarry Smith PetscErrorCode ierr; 388238baddfdSBarry Smith PetscMPIInt size; 3883273d9f13SBarry Smith 3884273d9f13SBarry Smith PetscFunctionBegin; 3885ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 3886e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Comm must be of size 1"); 3887273d9f13SBarry Smith 3888b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 38892205254eSKarl Rupp 3890b0a32e0cSBarry Smith B->data = (void*)b; 38912205254eSKarl Rupp 3892549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 38932205254eSKarl Rupp 3894416022c9SBarry Smith b->row = 0; 3895416022c9SBarry Smith b->col = 0; 389682bf6240SBarry Smith b->icol = 0; 3897b810aeb4SBarry Smith b->reallocs = 0; 389836db0b34SBarry Smith b->ignorezeroentries = PETSC_FALSE; 3899f1e2ffcdSBarry Smith b->roworiented = PETSC_TRUE; 3900416022c9SBarry Smith b->nonew = 0; 3901416022c9SBarry Smith b->diag = 0; 3902416022c9SBarry Smith b->solve_work = 0; 39032a1b7f2aSHong Zhang B->spptr = 0; 3904be6bf707SBarry Smith b->saved_values = 0; 3905d7f994e1SBarry Smith b->idiag = 0; 390671f1c65dSBarry Smith b->mdiag = 0; 390771f1c65dSBarry Smith b->ssor_work = 0; 390871f1c65dSBarry Smith b->omega = 1.0; 390971f1c65dSBarry Smith b->fshift = 0.0; 391071f1c65dSBarry Smith b->idiagvalid = PETSC_FALSE; 3911bbead8a2SBarry Smith b->ibdiagvalid = PETSC_FALSE; 3912a9817697SBarry Smith b->keepnonzeropattern = PETSC_FALSE; 391317ab2063SBarry Smith 391435d8aa7fSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 3915bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJGetArray_C",MatSeqAIJGetArray_SeqAIJ);CHKERRQ(ierr); 3916bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJRestoreArray_C",MatSeqAIJRestoreArray_SeqAIJ);CHKERRQ(ierr); 39178c778c55SBarry Smith 3918b3866ffcSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 3919bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEnginePut_C",MatlabEnginePut_SeqAIJ);CHKERRQ(ierr); 3920bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"PetscMatlabEngineGet_C",MatlabEngineGet_SeqAIJ);CHKERRQ(ierr); 3921b3866ffcSBarry Smith #endif 392217f1a0eaSHong Zhang 3923bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetColumnIndices_C",MatSeqAIJSetColumnIndices_SeqAIJ);CHKERRQ(ierr); 3924bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatStoreValues_C",MatStoreValues_SeqAIJ);CHKERRQ(ierr); 3925bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatRetrieveValues_C",MatRetrieveValues_SeqAIJ);CHKERRQ(ierr); 3926bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqsbaij_C",MatConvert_SeqAIJ_SeqSBAIJ);CHKERRQ(ierr); 3927bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqbaij_C",MatConvert_SeqAIJ_SeqBAIJ);CHKERRQ(ierr); 3928bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijperm_C",MatConvert_SeqAIJ_SeqAIJPERM);CHKERRQ(ierr); 3929bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqaijcrl_C",MatConvert_SeqAIJ_SeqAIJCRL);CHKERRQ(ierr); 3930af8000cdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3931af8000cdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_elemental_C",MatConvert_SeqAIJ_Elemental);CHKERRQ(ierr); 3932af8000cdSHong Zhang #endif 393363c07aadSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 393463c07aadSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_hypre_C",MatConvert_AIJ_HYPRE);CHKERRQ(ierr); 39353dad0653Sstefano_zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMatMult_transpose_seqaij_seqaij_C",MatMatMatMult_Transpose_AIJ_AIJ);CHKERRQ(ierr); 393663c07aadSStefano Zampini #endif 3937b49cda9fSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqaij_seqdense_C",MatConvert_SeqAIJ_SeqDense);CHKERRQ(ierr); 3938bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3939bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatIsHermitianTranspose_C",MatIsTranspose_SeqAIJ);CHKERRQ(ierr); 3940bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocation_C",MatSeqAIJSetPreallocation_SeqAIJ);CHKERRQ(ierr); 3941bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqAIJSetPreallocationCSR_C",MatSeqAIJSetPreallocationCSR_SeqAIJ);CHKERRQ(ierr); 3942bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatReorderForNonzeroDiagonal_C",MatReorderForNonzeroDiagonal_SeqAIJ);CHKERRQ(ierr); 3943bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqdense_seqaij_C",MatMatMult_SeqDense_SeqAIJ);CHKERRQ(ierr); 3944bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqdense_seqaij_C",MatMatMultSymbolic_SeqDense_SeqAIJ);CHKERRQ(ierr); 3945bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqdense_seqaij_C",MatMatMultNumeric_SeqDense_SeqAIJ);CHKERRQ(ierr); 39464108e4d5SBarry Smith ierr = MatCreate_SeqAIJ_Inode(B);CHKERRQ(ierr); 394717667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQAIJ);CHKERRQ(ierr); 39483a40ed3dSBarry Smith PetscFunctionReturn(0); 394917ab2063SBarry Smith } 395017ab2063SBarry Smith 3951b24902e0SBarry Smith /* 3952b24902e0SBarry Smith Given a matrix generated with MatGetFactor() duplicates all the information in A into B 3953b24902e0SBarry Smith */ 3954ace3abfcSBarry Smith PetscErrorCode MatDuplicateNoCreate_SeqAIJ(Mat C,Mat A,MatDuplicateOption cpvalues,PetscBool mallocmatspace) 395517ab2063SBarry Smith { 3956416022c9SBarry Smith Mat_SeqAIJ *c,*a = (Mat_SeqAIJ*)A->data; 39576849ba73SBarry Smith PetscErrorCode ierr; 3958d0f46423SBarry Smith PetscInt i,m = A->rmap->n; 395917ab2063SBarry Smith 39603a40ed3dSBarry Smith PetscFunctionBegin; 3961273d9f13SBarry Smith c = (Mat_SeqAIJ*)C->data; 3962273d9f13SBarry Smith 3963d5f3da31SBarry Smith C->factortype = A->factortype; 3964416022c9SBarry Smith c->row = 0; 3965416022c9SBarry Smith c->col = 0; 396682bf6240SBarry Smith c->icol = 0; 39676ad4291fSHong Zhang c->reallocs = 0; 396817ab2063SBarry Smith 39696ad4291fSHong Zhang C->assembled = PETSC_TRUE; 397017ab2063SBarry Smith 3971aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&C->rmap);CHKERRQ(ierr); 3972aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&C->cmap);CHKERRQ(ierr); 3973eec197d1SBarry Smith 3974dcca6d9dSJed Brown ierr = PetscMalloc2(m,&c->imax,m,&c->ilen);CHKERRQ(ierr); 39753bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, 2*m*sizeof(PetscInt));CHKERRQ(ierr); 397617ab2063SBarry Smith for (i=0; i<m; i++) { 3977416022c9SBarry Smith c->imax[i] = a->imax[i]; 3978416022c9SBarry Smith c->ilen[i] = a->ilen[i]; 397917ab2063SBarry Smith } 398017ab2063SBarry Smith 398117ab2063SBarry Smith /* allocate the matrix space */ 3982f77e22a1SHong Zhang if (mallocmatspace) { 3983dcca6d9dSJed Brown ierr = PetscMalloc3(a->i[m],&c->a,a->i[m],&c->j,m+1,&c->i);CHKERRQ(ierr); 39843bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C, a->i[m]*(sizeof(PetscScalar)+sizeof(PetscInt))+(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 39852205254eSKarl Rupp 3986f1e2ffcdSBarry Smith c->singlemalloc = PETSC_TRUE; 39872205254eSKarl Rupp 398897f1f81fSBarry Smith ierr = PetscMemcpy(c->i,a->i,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 398917ab2063SBarry Smith if (m > 0) { 399097f1f81fSBarry Smith ierr = PetscMemcpy(c->j,a->j,(a->i[m])*sizeof(PetscInt));CHKERRQ(ierr); 3991be6bf707SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 3992bfeeae90SHong Zhang ierr = PetscMemcpy(c->a,a->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 3993be6bf707SBarry Smith } else { 3994bfeeae90SHong Zhang ierr = PetscMemzero(c->a,(a->i[m])*sizeof(PetscScalar));CHKERRQ(ierr); 399517ab2063SBarry Smith } 399608480c60SBarry Smith } 3997f77e22a1SHong Zhang } 399817ab2063SBarry Smith 39996ad4291fSHong Zhang c->ignorezeroentries = a->ignorezeroentries; 4000416022c9SBarry Smith c->roworiented = a->roworiented; 4001416022c9SBarry Smith c->nonew = a->nonew; 4002416022c9SBarry Smith if (a->diag) { 4003854ce69bSBarry Smith ierr = PetscMalloc1(m+1,&c->diag);CHKERRQ(ierr); 40043bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)C,(m+1)*sizeof(PetscInt));CHKERRQ(ierr); 400517ab2063SBarry Smith for (i=0; i<m; i++) { 4006416022c9SBarry Smith c->diag[i] = a->diag[i]; 400717ab2063SBarry Smith } 40083a40ed3dSBarry Smith } else c->diag = 0; 40092205254eSKarl Rupp 40106ad4291fSHong Zhang c->solve_work = 0; 40116ad4291fSHong Zhang c->saved_values = 0; 40126ad4291fSHong Zhang c->idiag = 0; 401371f1c65dSBarry Smith c->ssor_work = 0; 4014a9817697SBarry Smith c->keepnonzeropattern = a->keepnonzeropattern; 4015e6b907acSBarry Smith c->free_a = PETSC_TRUE; 4016e6b907acSBarry Smith c->free_ij = PETSC_TRUE; 40176ad4291fSHong Zhang 4018893ad86cSHong Zhang c->rmax = a->rmax; 4019416022c9SBarry Smith c->nz = a->nz; 40208ed568f8SMatthew G Knepley c->maxnz = a->nz; /* Since we allocate exactly the right amount */ 4021273d9f13SBarry Smith C->preallocated = PETSC_TRUE; 4022754ec7b1SSatish Balay 40236ad4291fSHong Zhang c->compressedrow.use = a->compressedrow.use; 40246ad4291fSHong Zhang c->compressedrow.nrows = a->compressedrow.nrows; 4025cd6b891eSBarry Smith if (a->compressedrow.use) { 40266ad4291fSHong Zhang i = a->compressedrow.nrows; 4027dcca6d9dSJed Brown ierr = PetscMalloc2(i+1,&c->compressedrow.i,i,&c->compressedrow.rindex);CHKERRQ(ierr); 40286ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.i,a->compressedrow.i,(i+1)*sizeof(PetscInt));CHKERRQ(ierr); 40296ad4291fSHong Zhang ierr = PetscMemcpy(c->compressedrow.rindex,a->compressedrow.rindex,i*sizeof(PetscInt));CHKERRQ(ierr); 403027ea64f8SHong Zhang } else { 403127ea64f8SHong Zhang c->compressedrow.use = PETSC_FALSE; 40320298fd71SBarry Smith c->compressedrow.i = NULL; 40330298fd71SBarry Smith c->compressedrow.rindex = NULL; 40346ad4291fSHong Zhang } 4035ea632784SBarry Smith c->nonzerorowcnt = a->nonzerorowcnt; 4036e56f5c9eSBarry Smith C->nonzerostate = A->nonzerostate; 40374846f1f5SKris Buschelman 40382205254eSKarl Rupp ierr = MatDuplicate_SeqAIJ_Inode(A,cpvalues,&C);CHKERRQ(ierr); 4039140e18c1SBarry Smith ierr = PetscFunctionListDuplicate(((PetscObject)A)->qlist,&((PetscObject)C)->qlist);CHKERRQ(ierr); 40403a40ed3dSBarry Smith PetscFunctionReturn(0); 404117ab2063SBarry Smith } 404217ab2063SBarry Smith 4043b24902e0SBarry Smith PetscErrorCode MatDuplicate_SeqAIJ(Mat A,MatDuplicateOption cpvalues,Mat *B) 4044b24902e0SBarry Smith { 4045b24902e0SBarry Smith PetscErrorCode ierr; 4046b24902e0SBarry Smith 4047b24902e0SBarry Smith PetscFunctionBegin; 4048ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),B);CHKERRQ(ierr); 40494b6263acSBarry Smith ierr = MatSetSizes(*B,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 4050cfd3f464SBarry Smith if (!(A->rmap->n % A->rmap->bs) && !(A->cmap->n % A->cmap->bs)) { 405133d57670SJed Brown ierr = MatSetBlockSizesFromMats(*B,A,A);CHKERRQ(ierr); 4052cfd3f464SBarry Smith } 4053a54f2f98SBarry Smith ierr = MatSetType(*B,((PetscObject)A)->type_name);CHKERRQ(ierr); 4054f77e22a1SHong Zhang ierr = MatDuplicateNoCreate_SeqAIJ(*B,A,cpvalues,PETSC_TRUE);CHKERRQ(ierr); 4055b24902e0SBarry Smith PetscFunctionReturn(0); 4056b24902e0SBarry Smith } 4057b24902e0SBarry Smith 4058112444f4SShri Abhyankar PetscErrorCode MatLoad_SeqAIJ(Mat newMat, PetscViewer viewer) 4059fbdbba38SShri Abhyankar { 4060fbdbba38SShri Abhyankar Mat_SeqAIJ *a; 4061fbdbba38SShri Abhyankar PetscErrorCode ierr; 4062fbdbba38SShri Abhyankar PetscInt i,sum,nz,header[4],*rowlengths = 0,M,N,rows,cols; 4063fbdbba38SShri Abhyankar int fd; 4064fbdbba38SShri Abhyankar PetscMPIInt size; 4065fbdbba38SShri Abhyankar MPI_Comm comm; 40663059b6faSBarry Smith PetscInt bs = newMat->rmap->bs; 4067fbdbba38SShri Abhyankar 4068fbdbba38SShri Abhyankar PetscFunctionBegin; 4069c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 4070c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 4071fbdbba38SShri Abhyankar ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 4072fbdbba38SShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 4073fbdbba38SShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"view must have one processor"); 4074bbead8a2SBarry Smith 40750298fd71SBarry Smith ierr = PetscOptionsBegin(comm,NULL,"Options for loading SEQAIJ matrix","Mat");CHKERRQ(ierr); 40760298fd71SBarry Smith ierr = PetscOptionsInt("-matload_block_size","Set the blocksize used to store the matrix","MatLoad",bs,&bs,NULL);CHKERRQ(ierr); 4077bbead8a2SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 40783059b6faSBarry Smith if (bs < 0) bs = 1; 40793059b6faSBarry Smith ierr = MatSetBlockSize(newMat,bs);CHKERRQ(ierr); 4080bbead8a2SBarry Smith 4081fbdbba38SShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 4082fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 4083fbdbba38SShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"not matrix object in file"); 4084fbdbba38SShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 4085fbdbba38SShri Abhyankar 4086bbead8a2SBarry Smith if (nz < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Matrix stored in special format on disk,cannot load as SeqAIJ"); 4087fbdbba38SShri Abhyankar 4088fbdbba38SShri Abhyankar /* read in row lengths */ 4089785e854fSJed Brown ierr = PetscMalloc1(M,&rowlengths);CHKERRQ(ierr); 4090fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 4091fbdbba38SShri Abhyankar 4092fbdbba38SShri Abhyankar /* check if sum of rowlengths is same as nz */ 4093fbdbba38SShri Abhyankar for (i=0,sum=0; i< M; i++) sum +=rowlengths[i]; 409460e0710aSBarry Smith if (sum != nz) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_FILE_READ,"Inconsistant matrix data in file. no-nonzeros = %dD, sum-row-lengths = %D\n",nz,sum); 4095fbdbba38SShri Abhyankar 4096fbdbba38SShri Abhyankar /* set global size if not set already*/ 4097f501eaabSShri Abhyankar if (newMat->rmap->n < 0 && newMat->rmap->N < 0 && newMat->cmap->n < 0 && newMat->cmap->N < 0) { 4098fbdbba38SShri Abhyankar ierr = MatSetSizes(newMat,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 4099aabbc4fbSShri Abhyankar } else { 41009d36ed5fSBarry Smith /* if sizes and type are already set, check if the matrix global sizes are correct */ 4101fbdbba38SShri Abhyankar ierr = MatGetSize(newMat,&rows,&cols);CHKERRQ(ierr); 41024c5b953cSHong Zhang if (rows < 0 && cols < 0) { /* user might provide local size instead of global size */ 41034c5b953cSHong Zhang ierr = MatGetLocalSize(newMat,&rows,&cols);CHKERRQ(ierr); 41044c5b953cSHong Zhang } 410560e0710aSBarry Smith 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); 4106aabbc4fbSShri Abhyankar } 4107fbdbba38SShri Abhyankar ierr = MatSeqAIJSetPreallocation_SeqAIJ(newMat,0,rowlengths);CHKERRQ(ierr); 4108fbdbba38SShri Abhyankar a = (Mat_SeqAIJ*)newMat->data; 4109fbdbba38SShri Abhyankar 4110fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->j,nz,PETSC_INT);CHKERRQ(ierr); 4111fbdbba38SShri Abhyankar 4112fbdbba38SShri Abhyankar /* read in nonzero values */ 4113fbdbba38SShri Abhyankar ierr = PetscBinaryRead(fd,a->a,nz,PETSC_SCALAR);CHKERRQ(ierr); 4114fbdbba38SShri Abhyankar 4115fbdbba38SShri Abhyankar /* set matrix "i" values */ 4116fbdbba38SShri Abhyankar a->i[0] = 0; 4117fbdbba38SShri Abhyankar for (i=1; i<= M; i++) { 4118fbdbba38SShri Abhyankar a->i[i] = a->i[i-1] + rowlengths[i-1]; 4119fbdbba38SShri Abhyankar a->ilen[i-1] = rowlengths[i-1]; 4120fbdbba38SShri Abhyankar } 4121fbdbba38SShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 4122fbdbba38SShri Abhyankar 4123fbdbba38SShri Abhyankar ierr = MatAssemblyBegin(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4124fbdbba38SShri Abhyankar ierr = MatAssemblyEnd(newMat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4125fbdbba38SShri Abhyankar PetscFunctionReturn(0); 4126fbdbba38SShri Abhyankar } 4127fbdbba38SShri Abhyankar 4128ace3abfcSBarry Smith PetscErrorCode MatEqual_SeqAIJ(Mat A,Mat B,PetscBool * flg) 41297264ac53SSatish Balay { 41307264ac53SSatish Balay Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data,*b = (Mat_SeqAIJ*)B->data; 4131dfbe8321SBarry Smith PetscErrorCode ierr; 4132eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4133eeffb40dSHong Zhang PetscInt k; 4134eeffb40dSHong Zhang #endif 41357264ac53SSatish Balay 41363a40ed3dSBarry Smith PetscFunctionBegin; 4137bfeeae90SHong Zhang /* If the matrix dimensions are not equal,or no of nonzeros */ 4138d0f46423SBarry Smith if ((A->rmap->n != B->rmap->n) || (A->cmap->n != B->cmap->n) ||(a->nz != b->nz)) { 4139ca44d042SBarry Smith *flg = PETSC_FALSE; 4140ca44d042SBarry Smith PetscFunctionReturn(0); 4141bcd2baecSBarry Smith } 41427264ac53SSatish Balay 41437264ac53SSatish Balay /* if the a->i are the same */ 4144d0f46423SBarry Smith ierr = PetscMemcmp(a->i,b->i,(A->rmap->n+1)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4145abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 41467264ac53SSatish Balay 41477264ac53SSatish Balay /* if a->j are the same */ 414897f1f81fSBarry Smith ierr = PetscMemcmp(a->j,b->j,(a->nz)*sizeof(PetscInt),flg);CHKERRQ(ierr); 4149abc0a331SBarry Smith if (!*flg) PetscFunctionReturn(0); 4150bcd2baecSBarry Smith 4151bcd2baecSBarry Smith /* if a->a are the same */ 4152eeffb40dSHong Zhang #if defined(PETSC_USE_COMPLEX) 4153eeffb40dSHong Zhang for (k=0; k<a->nz; k++) { 4154eeffb40dSHong Zhang if (PetscRealPart(a->a[k]) != PetscRealPart(b->a[k]) || PetscImaginaryPart(a->a[k]) != PetscImaginaryPart(b->a[k])) { 4155eeffb40dSHong Zhang *flg = PETSC_FALSE; 41563a40ed3dSBarry Smith PetscFunctionReturn(0); 4157eeffb40dSHong Zhang } 4158eeffb40dSHong Zhang } 4159eeffb40dSHong Zhang #else 4160eeffb40dSHong Zhang ierr = PetscMemcmp(a->a,b->a,(a->nz)*sizeof(PetscScalar),flg);CHKERRQ(ierr); 4161eeffb40dSHong Zhang #endif 4162eeffb40dSHong Zhang PetscFunctionReturn(0); 41637264ac53SSatish Balay } 416436db0b34SBarry Smith 416505869f15SSatish Balay /*@ 416636db0b34SBarry Smith MatCreateSeqAIJWithArrays - Creates an sequential AIJ matrix using matrix elements (in CSR format) 416736db0b34SBarry Smith provided by the user. 416836db0b34SBarry Smith 4169c75a6043SHong Zhang Collective on MPI_Comm 417036db0b34SBarry Smith 417136db0b34SBarry Smith Input Parameters: 417236db0b34SBarry Smith + comm - must be an MPI communicator of size 1 417336db0b34SBarry Smith . m - number of rows 417436db0b34SBarry Smith . n - number of columns 417536db0b34SBarry Smith . i - row indices 417636db0b34SBarry Smith . j - column indices 417736db0b34SBarry Smith - a - matrix values 417836db0b34SBarry Smith 417936db0b34SBarry Smith Output Parameter: 418036db0b34SBarry Smith . mat - the matrix 418136db0b34SBarry Smith 418236db0b34SBarry Smith Level: intermediate 418336db0b34SBarry Smith 418436db0b34SBarry Smith Notes: 41850551d7c0SBarry Smith The i, j, and a arrays are not copied by this routine, the user must free these arrays 4186292fb18eSBarry Smith once the matrix is destroyed and not before 418736db0b34SBarry Smith 418836db0b34SBarry Smith You cannot set new nonzero locations into this matrix, that will generate an error. 418936db0b34SBarry Smith 4190bfeeae90SHong Zhang The i and j indices are 0 based 419136db0b34SBarry Smith 4192a4552177SSatish Balay The format which is used for the sparse matrix input, is equivalent to a 4193a4552177SSatish Balay row-major ordering.. i.e for the following matrix, the input data expected is 41948eef79e4SBarry Smith as shown 4195a4552177SSatish Balay 41968eef79e4SBarry Smith $ 1 0 0 41978eef79e4SBarry Smith $ 2 0 3 41988eef79e4SBarry Smith $ 4 5 6 41998eef79e4SBarry Smith $ 42008eef79e4SBarry Smith $ i = {0,1,3,6} [size = nrow+1 = 3+1] 42018eef79e4SBarry Smith $ j = {0,0,2,0,1,2} [size = 6]; values must be sorted for each row 42028eef79e4SBarry Smith $ v = {1,2,3,4,5,6} [size = 6] 4203a4552177SSatish Balay 42049985e31cSBarry Smith 420569b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateMPIAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 420636db0b34SBarry Smith 420736db0b34SBarry Smith @*/ 4208c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat) 420936db0b34SBarry Smith { 4210dfbe8321SBarry Smith PetscErrorCode ierr; 4211cbcfb4deSHong Zhang PetscInt ii; 421236db0b34SBarry Smith Mat_SeqAIJ *aij; 4213cbcfb4deSHong Zhang #if defined(PETSC_USE_DEBUG) 4214cbcfb4deSHong Zhang PetscInt jj; 4215cbcfb4deSHong Zhang #endif 421636db0b34SBarry Smith 421736db0b34SBarry Smith PetscFunctionBegin; 421841096f02SStefano Zampini if (m > 0 && i[0]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"i (row indices) must start with 0"); 4219f69a0ea3SMatthew Knepley ierr = MatCreate(comm,mat);CHKERRQ(ierr); 4220f69a0ea3SMatthew Knepley ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 4221a2f3521dSMark F. Adams /* ierr = MatSetBlockSizes(*mat,,);CHKERRQ(ierr); */ 4222ab93d7beSBarry Smith ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 4223ab93d7beSBarry Smith ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,MAT_SKIP_ALLOCATION,0);CHKERRQ(ierr); 4224ab93d7beSBarry Smith aij = (Mat_SeqAIJ*)(*mat)->data; 4225dcca6d9dSJed Brown ierr = PetscMalloc2(m,&aij->imax,m,&aij->ilen);CHKERRQ(ierr); 4226ab93d7beSBarry Smith 422736db0b34SBarry Smith aij->i = i; 422836db0b34SBarry Smith aij->j = j; 422936db0b34SBarry Smith aij->a = a; 423036db0b34SBarry Smith aij->singlemalloc = PETSC_FALSE; 423136db0b34SBarry Smith aij->nonew = -1; /*this indicates that inserting a new value in the matrix that generates a new nonzero is an error*/ 4232e6b907acSBarry Smith aij->free_a = PETSC_FALSE; 4233e6b907acSBarry Smith aij->free_ij = PETSC_FALSE; 423436db0b34SBarry Smith 423536db0b34SBarry Smith for (ii=0; ii<m; ii++) { 423636db0b34SBarry Smith aij->ilen[ii] = aij->imax[ii] = i[ii+1] - i[ii]; 42372515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 423860e0710aSBarry 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]); 42399985e31cSBarry Smith for (jj=i[ii]+1; jj<i[ii+1]; jj++) { 4240e32f2f54SBarry 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); 4241e32f2f54SBarry 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); 42429985e31cSBarry Smith } 424336db0b34SBarry Smith #endif 424436db0b34SBarry Smith } 42452515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 424636db0b34SBarry Smith for (ii=0; ii<aij->i[m]; ii++) { 424760e0710aSBarry Smith if (j[ii] < 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative column index at location = %D index = %D",ii,j[ii]); 424860e0710aSBarry 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]); 424936db0b34SBarry Smith } 425036db0b34SBarry Smith #endif 425136db0b34SBarry Smith 4252b65db4caSBarry Smith ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4253b65db4caSBarry Smith ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 425436db0b34SBarry Smith PetscFunctionReturn(0); 425536db0b34SBarry Smith } 425680ef6e79SMatthew G Knepley /*@C 4257d021a1c5SVictor Minden MatCreateSeqAIJFromTriple - Creates an sequential AIJ matrix using matrix elements (in COO format) 42588a0b0e6bSVictor Minden provided by the user. 42598a0b0e6bSVictor Minden 42608a0b0e6bSVictor Minden Collective on MPI_Comm 42618a0b0e6bSVictor Minden 42628a0b0e6bSVictor Minden Input Parameters: 42638a0b0e6bSVictor Minden + comm - must be an MPI communicator of size 1 42648a0b0e6bSVictor Minden . m - number of rows 42658a0b0e6bSVictor Minden . n - number of columns 42668a0b0e6bSVictor Minden . i - row indices 42678a0b0e6bSVictor Minden . j - column indices 42681230e6d1SVictor Minden . a - matrix values 42691230e6d1SVictor Minden . nz - number of nonzeros 42701230e6d1SVictor Minden - idx - 0 or 1 based 42718a0b0e6bSVictor Minden 42728a0b0e6bSVictor Minden Output Parameter: 42738a0b0e6bSVictor Minden . mat - the matrix 42748a0b0e6bSVictor Minden 42758a0b0e6bSVictor Minden Level: intermediate 42768a0b0e6bSVictor Minden 42778a0b0e6bSVictor Minden Notes: 42788a0b0e6bSVictor Minden The i and j indices are 0 based 42798a0b0e6bSVictor Minden 42808a0b0e6bSVictor Minden The format which is used for the sparse matrix input, is equivalent to a 42818a0b0e6bSVictor Minden row-major ordering.. i.e for the following matrix, the input data expected is 42828a0b0e6bSVictor Minden as shown: 42838a0b0e6bSVictor Minden 42848a0b0e6bSVictor Minden 1 0 0 42858a0b0e6bSVictor Minden 2 0 3 42868a0b0e6bSVictor Minden 4 5 6 42878a0b0e6bSVictor Minden 42888a0b0e6bSVictor Minden i = {0,1,1,2,2,2} 42898a0b0e6bSVictor Minden j = {0,0,2,0,1,2} 42908a0b0e6bSVictor Minden v = {1,2,3,4,5,6} 42918a0b0e6bSVictor Minden 42928a0b0e6bSVictor Minden 429369b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateAIJ(), MatCreateSeqAIJ(), MatCreateSeqAIJWithArrays(), MatMPIAIJSetPreallocationCSR() 42948a0b0e6bSVictor Minden 42958a0b0e6bSVictor Minden @*/ 4296c3c607ccSBarry Smith PetscErrorCode MatCreateSeqAIJFromTriple(MPI_Comm comm,PetscInt m,PetscInt n,PetscInt i[],PetscInt j[],PetscScalar a[],Mat *mat,PetscInt nz,PetscBool idx) 42978a0b0e6bSVictor Minden { 42988a0b0e6bSVictor Minden PetscErrorCode ierr; 4299d021a1c5SVictor Minden PetscInt ii, *nnz, one = 1,row,col; 43008a0b0e6bSVictor Minden 43018a0b0e6bSVictor Minden 43028a0b0e6bSVictor Minden PetscFunctionBegin; 43031795a4d1SJed Brown ierr = PetscCalloc1(m,&nnz);CHKERRQ(ierr); 43041230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 4305c8d679ebSHong Zhang nnz[i[ii] - !!idx] += 1; 43061230e6d1SVictor Minden } 43078a0b0e6bSVictor Minden ierr = MatCreate(comm,mat);CHKERRQ(ierr); 43088a0b0e6bSVictor Minden ierr = MatSetSizes(*mat,m,n,m,n);CHKERRQ(ierr); 43098a0b0e6bSVictor Minden ierr = MatSetType(*mat,MATSEQAIJ);CHKERRQ(ierr); 43101230e6d1SVictor Minden ierr = MatSeqAIJSetPreallocation_SeqAIJ(*mat,0,nnz);CHKERRQ(ierr); 43111230e6d1SVictor Minden for (ii = 0; ii < nz; ii++) { 43121230e6d1SVictor Minden if (idx) { 43131230e6d1SVictor Minden row = i[ii] - 1; 43141230e6d1SVictor Minden col = j[ii] - 1; 43151230e6d1SVictor Minden } else { 43161230e6d1SVictor Minden row = i[ii]; 43171230e6d1SVictor Minden col = j[ii]; 43188a0b0e6bSVictor Minden } 43191230e6d1SVictor Minden ierr = MatSetValues(*mat,one,&row,one,&col,&a[ii],ADD_VALUES);CHKERRQ(ierr); 43208a0b0e6bSVictor Minden } 43218a0b0e6bSVictor Minden ierr = MatAssemblyBegin(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 43228a0b0e6bSVictor Minden ierr = MatAssemblyEnd(*mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 4323d021a1c5SVictor Minden ierr = PetscFree(nnz);CHKERRQ(ierr); 43248a0b0e6bSVictor Minden PetscFunctionReturn(0); 43258a0b0e6bSVictor Minden } 432636db0b34SBarry Smith 4327acf2f550SJed Brown PetscErrorCode MatSeqAIJInvalidateDiagonal(Mat A) 4328acf2f550SJed Brown { 4329acf2f550SJed Brown Mat_SeqAIJ *a=(Mat_SeqAIJ*)A->data; 4330acf2f550SJed Brown PetscErrorCode ierr; 4331acf2f550SJed Brown 4332acf2f550SJed Brown PetscFunctionBegin; 4333acf2f550SJed Brown a->idiagvalid = PETSC_FALSE; 4334acf2f550SJed Brown a->ibdiagvalid = PETSC_FALSE; 43352205254eSKarl Rupp 4336acf2f550SJed Brown ierr = MatSeqAIJInvalidateDiagonal_Inode(A);CHKERRQ(ierr); 4337acf2f550SJed Brown PetscFunctionReturn(0); 4338acf2f550SJed Brown } 4339acf2f550SJed Brown 43409c8f2541SHong Zhang PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqAIJ(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 43419c8f2541SHong Zhang { 43429c8f2541SHong Zhang PetscErrorCode ierr; 43438761c3d6SHong Zhang PetscMPIInt size; 43449c8f2541SHong Zhang 43459c8f2541SHong Zhang PetscFunctionBegin; 43468761c3d6SHong Zhang ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 43478761c3d6SHong Zhang if (size == 1 && scall == MAT_REUSE_MATRIX) { 43488761c3d6SHong Zhang ierr = MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 43498761c3d6SHong Zhang } else { 43509c8f2541SHong Zhang ierr = MatCreateMPIMatConcatenateSeqMat_MPIAIJ(comm,inmat,n,scall,outmat);CHKERRQ(ierr); 43518761c3d6SHong Zhang } 43529c8f2541SHong Zhang PetscFunctionReturn(0); 43539c8f2541SHong Zhang } 43549c8f2541SHong Zhang 435581824310SBarry Smith /* 435653dd7562SDmitry Karpeev Permute A into C's *local* index space using rowemb,colemb. 435753dd7562SDmitry Karpeev The embedding are supposed to be injections and the above implies that the range of rowemb is a subset 435853dd7562SDmitry Karpeev of [0,m), colemb is in [0,n). 435953dd7562SDmitry Karpeev If pattern == DIFFERENT_NONZERO_PATTERN, C is preallocated according to A. 436053dd7562SDmitry Karpeev */ 436153dd7562SDmitry Karpeev PetscErrorCode MatSetSeqMat_SeqAIJ(Mat C,IS rowemb,IS colemb,MatStructure pattern,Mat B) 436253dd7562SDmitry Karpeev { 436353dd7562SDmitry Karpeev /* If making this function public, change the error returned in this function away from _PLIB. */ 436453dd7562SDmitry Karpeev PetscErrorCode ierr; 436553dd7562SDmitry Karpeev Mat_SeqAIJ *Baij; 436653dd7562SDmitry Karpeev PetscBool seqaij; 436753dd7562SDmitry Karpeev PetscInt m,n,*nz,i,j,count; 436853dd7562SDmitry Karpeev PetscScalar v; 436953dd7562SDmitry Karpeev const PetscInt *rowindices,*colindices; 437053dd7562SDmitry Karpeev 437153dd7562SDmitry Karpeev PetscFunctionBegin; 437253dd7562SDmitry Karpeev if (!B) PetscFunctionReturn(0); 437353dd7562SDmitry Karpeev /* Check to make sure the target matrix (and embeddings) are compatible with C and each other. */ 437453dd7562SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQAIJ,&seqaij);CHKERRQ(ierr); 437553dd7562SDmitry Karpeev if (!seqaij) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is of wrong type"); 437653dd7562SDmitry Karpeev if (rowemb) { 437753dd7562SDmitry Karpeev ierr = ISGetLocalSize(rowemb,&m);CHKERRQ(ierr); 437853dd7562SDmitry Karpeev if (m != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Row IS of size %D is incompatible with matrix row size %D",m,B->rmap->n); 437953dd7562SDmitry Karpeev } else { 43806c4ed002SBarry Smith if (C->rmap->n != B->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is row-incompatible with the target matrix"); 438153dd7562SDmitry Karpeev } 438253dd7562SDmitry Karpeev if (colemb) { 438353dd7562SDmitry Karpeev ierr = ISGetLocalSize(colemb,&n);CHKERRQ(ierr); 438453dd7562SDmitry Karpeev if (n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Diag col IS of size %D is incompatible with input matrix col size %D",n,B->cmap->n); 438553dd7562SDmitry Karpeev } else { 438653dd7562SDmitry Karpeev if (C->cmap->n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Input matrix is col-incompatible with the target matrix"); 438753dd7562SDmitry Karpeev } 438853dd7562SDmitry Karpeev 438953dd7562SDmitry Karpeev Baij = (Mat_SeqAIJ*)(B->data); 439053dd7562SDmitry Karpeev if (pattern == DIFFERENT_NONZERO_PATTERN) { 439153dd7562SDmitry Karpeev ierr = PetscMalloc1(B->rmap->n,&nz);CHKERRQ(ierr); 439253dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 439353dd7562SDmitry Karpeev nz[i] = Baij->i[i+1] - Baij->i[i]; 439453dd7562SDmitry Karpeev } 439553dd7562SDmitry Karpeev ierr = MatSeqAIJSetPreallocation(C,0,nz);CHKERRQ(ierr); 439653dd7562SDmitry Karpeev ierr = PetscFree(nz);CHKERRQ(ierr); 439753dd7562SDmitry Karpeev } 439853dd7562SDmitry Karpeev if (pattern == SUBSET_NONZERO_PATTERN) { 439953dd7562SDmitry Karpeev ierr = MatZeroEntries(C);CHKERRQ(ierr); 440053dd7562SDmitry Karpeev } 440153dd7562SDmitry Karpeev count = 0; 440253dd7562SDmitry Karpeev rowindices = NULL; 440353dd7562SDmitry Karpeev colindices = NULL; 440453dd7562SDmitry Karpeev if (rowemb) { 440553dd7562SDmitry Karpeev ierr = ISGetIndices(rowemb,&rowindices);CHKERRQ(ierr); 440653dd7562SDmitry Karpeev } 440753dd7562SDmitry Karpeev if (colemb) { 440853dd7562SDmitry Karpeev ierr = ISGetIndices(colemb,&colindices);CHKERRQ(ierr); 440953dd7562SDmitry Karpeev } 441053dd7562SDmitry Karpeev for (i=0; i<B->rmap->n; i++) { 441153dd7562SDmitry Karpeev PetscInt row; 441253dd7562SDmitry Karpeev row = i; 441353dd7562SDmitry Karpeev if (rowindices) row = rowindices[i]; 441453dd7562SDmitry Karpeev for (j=Baij->i[i]; j<Baij->i[i+1]; j++) { 441553dd7562SDmitry Karpeev PetscInt col; 441653dd7562SDmitry Karpeev col = Baij->j[count]; 441753dd7562SDmitry Karpeev if (colindices) col = colindices[col]; 441853dd7562SDmitry Karpeev v = Baij->a[count]; 441953dd7562SDmitry Karpeev ierr = MatSetValues(C,1,&row,1,&col,&v,INSERT_VALUES);CHKERRQ(ierr); 442053dd7562SDmitry Karpeev ++count; 442153dd7562SDmitry Karpeev } 442253dd7562SDmitry Karpeev } 442353dd7562SDmitry Karpeev /* FIXME: set C's nonzerostate correctly. */ 442453dd7562SDmitry Karpeev /* Assembly for C is necessary. */ 442553dd7562SDmitry Karpeev C->preallocated = PETSC_TRUE; 442653dd7562SDmitry Karpeev C->assembled = PETSC_TRUE; 442753dd7562SDmitry Karpeev C->was_assembled = PETSC_FALSE; 442853dd7562SDmitry Karpeev PetscFunctionReturn(0); 442953dd7562SDmitry Karpeev } 443053dd7562SDmitry Karpeev 443153dd7562SDmitry Karpeev 443253dd7562SDmitry Karpeev /* 443381824310SBarry Smith Special version for direct calls from Fortran 443481824310SBarry Smith */ 4435af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 443681824310SBarry Smith #if defined(PETSC_HAVE_FORTRAN_CAPS) 443781824310SBarry Smith #define matsetvaluesseqaij_ MATSETVALUESSEQAIJ 443881824310SBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 443981824310SBarry Smith #define matsetvaluesseqaij_ matsetvaluesseqaij 444081824310SBarry Smith #endif 444181824310SBarry Smith 444281824310SBarry Smith /* Change these macros so can be used in void function */ 444381824310SBarry Smith #undef CHKERRQ 4444ce94432eSBarry Smith #define CHKERRQ(ierr) CHKERRABORT(PetscObjectComm((PetscObject)A),ierr) 444581824310SBarry Smith #undef SETERRQ2 4446e32f2f54SBarry Smith #define SETERRQ2(comm,ierr,b,c,d) CHKERRABORT(comm,ierr) 44474994cf47SJed Brown #undef SETERRQ3 44484994cf47SJed Brown #define SETERRQ3(comm,ierr,b,c,d,e) CHKERRABORT(comm,ierr) 444981824310SBarry Smith 44508cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matsetvaluesseqaij_(Mat *AA,PetscInt *mm,const PetscInt im[],PetscInt *nn,const PetscInt in[],const PetscScalar v[],InsertMode *isis, PetscErrorCode *_ierr) 445181824310SBarry Smith { 445281824310SBarry Smith Mat A = *AA; 445381824310SBarry Smith PetscInt m = *mm, n = *nn; 445481824310SBarry Smith InsertMode is = *isis; 445581824310SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 445681824310SBarry Smith PetscInt *rp,k,low,high,t,ii,row,nrow,i,col,l,rmax,N; 445781824310SBarry Smith PetscInt *imax,*ai,*ailen; 445881824310SBarry Smith PetscErrorCode ierr; 445981824310SBarry Smith PetscInt *aj,nonew = a->nonew,lastcol = -1; 446054f21887SBarry Smith MatScalar *ap,value,*aa; 4461ace3abfcSBarry Smith PetscBool ignorezeroentries = a->ignorezeroentries; 4462ace3abfcSBarry Smith PetscBool roworiented = a->roworiented; 446381824310SBarry Smith 446481824310SBarry Smith PetscFunctionBegin; 44654994cf47SJed Brown MatCheckPreallocated(A,1); 446681824310SBarry Smith imax = a->imax; 446781824310SBarry Smith ai = a->i; 446881824310SBarry Smith ailen = a->ilen; 446981824310SBarry Smith aj = a->j; 447081824310SBarry Smith aa = a->a; 447181824310SBarry Smith 447281824310SBarry Smith for (k=0; k<m; k++) { /* loop over added rows */ 447381824310SBarry Smith row = im[k]; 447481824310SBarry Smith if (row < 0) continue; 447581824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4476ce94432eSBarry Smith if (row >= A->rmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Row too large"); 447781824310SBarry Smith #endif 447881824310SBarry Smith rp = aj + ai[row]; ap = aa + ai[row]; 447981824310SBarry Smith rmax = imax[row]; nrow = ailen[row]; 448081824310SBarry Smith low = 0; 448181824310SBarry Smith high = nrow; 448281824310SBarry Smith for (l=0; l<n; l++) { /* loop over added columns */ 448381824310SBarry Smith if (in[l] < 0) continue; 448481824310SBarry Smith #if defined(PETSC_USE_DEBUG) 4485ce94432eSBarry Smith if (in[l] >= A->cmap->n) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Column too large"); 448681824310SBarry Smith #endif 448781824310SBarry Smith col = in[l]; 44882205254eSKarl Rupp if (roworiented) value = v[l + k*n]; 44892205254eSKarl Rupp else value = v[k + l*m]; 44902205254eSKarl Rupp 449181824310SBarry Smith if (value == 0.0 && ignorezeroentries && (is == ADD_VALUES)) continue; 449281824310SBarry Smith 44932205254eSKarl Rupp if (col <= lastcol) low = 0; 44942205254eSKarl Rupp else high = nrow; 449581824310SBarry Smith lastcol = col; 449681824310SBarry Smith while (high-low > 5) { 449781824310SBarry Smith t = (low+high)/2; 449881824310SBarry Smith if (rp[t] > col) high = t; 449981824310SBarry Smith else low = t; 450081824310SBarry Smith } 450181824310SBarry Smith for (i=low; i<high; i++) { 450281824310SBarry Smith if (rp[i] > col) break; 450381824310SBarry Smith if (rp[i] == col) { 450481824310SBarry Smith if (is == ADD_VALUES) ap[i] += value; 450581824310SBarry Smith else ap[i] = value; 450681824310SBarry Smith goto noinsert; 450781824310SBarry Smith } 450881824310SBarry Smith } 450981824310SBarry Smith if (value == 0.0 && ignorezeroentries) goto noinsert; 451081824310SBarry Smith if (nonew == 1) goto noinsert; 4511ce94432eSBarry Smith if (nonew == -1) SETERRABORT(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_OUTOFRANGE,"Inserting a new nonzero in the matrix"); 4512fef13f97SBarry Smith MatSeqXAIJReallocateAIJ(A,A->rmap->n,1,nrow,row,col,rmax,aa,ai,aj,rp,ap,imax,nonew,MatScalar); 451381824310SBarry Smith N = nrow++ - 1; a->nz++; high++; 451481824310SBarry Smith /* shift up all the later entries in this row */ 451581824310SBarry Smith for (ii=N; ii>=i; ii--) { 451681824310SBarry Smith rp[ii+1] = rp[ii]; 451781824310SBarry Smith ap[ii+1] = ap[ii]; 451881824310SBarry Smith } 451981824310SBarry Smith rp[i] = col; 452081824310SBarry Smith ap[i] = value; 4521e56f5c9eSBarry Smith A->nonzerostate++; 452281824310SBarry Smith noinsert:; 452381824310SBarry Smith low = i + 1; 452481824310SBarry Smith } 452581824310SBarry Smith ailen[row] = nrow; 452681824310SBarry Smith } 452781824310SBarry Smith PetscFunctionReturnVoid(); 452881824310SBarry Smith } 45299f7953f8SBarry Smith 4530